- LINUX — это семейство операционных систем (ОС), работающих на основе одноименного ядра.
- Emacs — один из наиболее мощных и широко распространённых редакторов, используемых в мире Unix.
- Nginx — это программное обеспечение с открытым исходным кодом для создания легкого и мощного веб-сервера.
- TeX — это созданная американским математиком и программистом Дональдом Кнутом (Donald E. Knuth) система для верстки текстов с формулами.
Это многостраничный печатный вид этого раздела. Нажмите что бы печатать.
Справочники по автоматизации и программированию
- 1: Искусственный интеллект
- 1.1: Ollama
- 1.1.1: Настройка запросов к моделям через Ollama
- 1.1.2: Пример с curl и полным набором параметров
- 1.1.3: Пример из командной строки с ollama run
- 1.1.4: Alias для zsh с конфигурационным файлом YAML
- 1.1.5: Запуск модели из Ollama с конфигурационным файлом JSON
- 1.1.6: Запуск модели из Ollama с конфигурационным файлом JSON и контекстом
- 1.1.7: Запуск модели Ollama с конфигурационным файлом JSON из NODE.JS
- 1.1.8: Запуск модели Ollama на языке Go
- 1.1.9: Запуск модели Ollama на языке программирования Python
- 2: Язык программирования LUA
- 2.1: 2. Базовые концепции языка LUA
- 2.2: 3 – Язык Lua: Лексика и синтаксис
- 2.3: 4 – Интерфейс прикладного программирования (API)
- 2.4: Вспомогательная библиотека Lua
- 2.5: Руководство по языку Lua: Стандартные библиотеки
- 2.6: 7 – Lua как самостоятельное приложение
- 3: Authelia
- 3.1: Конфигурация Authelia
- 3.2: Методы Authelia
- 3.2.1: Секреты Authelia
- 3.2.2: Файлы конфигурации
- 3.2.3: Переменные Authelia
- 3.3: Однофакторная аутентификация
- 3.3.1: Однофакторная аутентификация
- 3.3.2: LDAP
- 3.3.3: Файлы конфигурации
- 3.4: Двухфакторная аутентификация
- 3.4.1: Мобильные устройства
- 3.4.2: Time-based One-Time Password
- 3.4.3: WebAuthn
- 3.5: Security
- 3.5.1: Контроль доступа
- 3.5.2: Регулирование
- 3.5.3: Password Policy
- 3.6: Проверка входа
- 3.6.1: Elevated Session
- 3.6.2: Reset password
- 3.7: Seccion
- 3.7.1: Конфигурация
- 3.7.2: Redis
- 3.8: Storage Хранилище данных
- 3.8.1: PostgreSQL
- 3.8.2: SQLite3
- 3.8.3: MySQL
- 3.9: Notifications (Уведомления)
- 3.9.1: SMTP
- 3.9.2: File system
- 3.10: Telemetry (телеметрия)
- 3.11: Определения
- 3.11.1: Network
- 3.11.2: User Attributes
- 3.12: Разное
- 3.12.1: Server в Authelia
- 3.12.2: Server Authz Endpoints
- 3.12.3: Server Endpoint Rate Limits
- 4: Bootstrap
- 4.1: Работа с цветами в Bootstrap
- 4.2: Mixins
- 4.3: Bootstrap Flexbox
- 4.4: Bootstrap Отступы
- 5: Описание настроек Docker
- 5.1: Шпаргалка по Docker и Docker Compose (CLI)
- 5.2: Справочник по созданию образов Docker
- 5.3: Очистка кеша при использовании Docker
- 6: Микроразметка для СЕО поиска
- 6.1: JSON-LD - микроразметка материалов для выдачи сниппетов в поиске Google
- 6.2: Документация RDF для универсальной микроразметки текстов для микропоиска
- 6.2.1: Обзор синтаксиса
- 6.2.2: Терминология RDF
- 6.2.3: Соответствие в RDF
- 6.2.4: Аттрибуты и синтаксис в RDF
- 6.2.5: Определение синтаксиса CURIE в RDF
- 7: Latex
- 7.1: Библиотека цветных блоков и рамок tcolorbox для Latex
- 7.1.1: Ключи к командам tcolorbox
- 7.1.2: Команды для Title
- 7.1.3: Команды для SubTitle
- 7.1.4: Команды для Part
- 7.1.5: Команды для Lower Part
- 7.1.6: Команды для Color и Font
- 7.1.7: Команды для выравнивания текста
- 7.1.8: Команды для управления размерами и отступами в боксах
- 7.1.9: Команды для управления параметрами углов в боксах
- 7.1.10: Команды для управления прозрачностью в боксах
- 7.1.11: Команды для управления высотой боксов
- 7.1.12: Команды для добавления различного контента в боксы
- 7.1.13: Команды для упрвления слоями в боксах
- 7.1.14: Команды для управления плавающими объектами боксов
- 7.1.15: Команды для встраивания объектов и боксов в боксы (embedding)
- 7.1.16: Управление ограничивающей рамкой (Bounding Box) в tcolorbox
- 7.1.17: Управление уровнями/слоями в пакете tcolorbox
- 7.1.18: Управление Capture mode в пакете tcolorbox
- 7.1.19: Управление характеристиками текста в пакете tcolorbox
- 7.1.20: Files - Работа с временными файлами в tcolorbox
- 7.1.21: cbox Specials - Специальные настройки для cbox и cboxmath
- 7.1.22: Counters, Labels, and References - Счётчики, метки и ссылки в tcolorbox
- 7.1.23: Even and Odd Pages - Разное оформление для чётных и нечётных страниц
- 7.1.24: Externalization - Интеграция с внешними файлами TikZ
- 7.1.25: Miscellaneous - Разные дополнительные возможности
- 7.2: Справочник основных пакетов LaTeX
- 7.3: Latex для авторов
- 7.3.1: Памятка по командам Latex 3
- 7.4: Пакеты для работы с таблицами в LaTeX
- 7.5: Описание пакетов fancyhdr и fancybox
- 7.6: TEX издательская система
- 7.6.1: TEX команды
- 7.6.2: TEX for the Impatient
- 7.6.3: TEX
- 7.6.4:
- 7.7: Графический пакет TIKZ для Latex
- 7.7.1: Дисплей для руководства пользователя
- 7.7.2: Foreach for Tex
- 7.7.3: Key Management
- 7.7.4: Примеры PIC в библиотеке TIKZ
- 7.7.5: Matrix в модуле TIKZ
- 7.7.6: PIC маленький рисунок
- 7.7.7: Node TIKZ
- 7.7.8: Path и его особенности
- 7.7.9: Вводные понятия в TIKZ
- 7.7.10: Диаграммы в Latex библиотека TIKZ
- 7.7.11: Примеры по Эвклиду
- 7.7.12: Сети PETRI
- 7.7.13: Графики в TIKZ для Latex
- 7.8: Пакет Xcolor и colortbl
- 7.9: Пакет longtable
- 7.10: Newfont
- 7.11: Pdfpages
- 7.12: Titleps
- 7.13: Titlesec
- 7.14: Пакет fontenc - Управление кодировками шрифтов в LaTeX
- 7.15: Пакет fontspec - Управление кодировками шрифтов в XeLaTeX
- 8: opensearch
- 8.1: Введение в Opensearch
- 8.1.1: Быстрый старт установки
- 8.1.2: Взаимодействие с OpenSearch
- 8.1.3: Загрузка данных в OpenSearch
- 8.1.4: Поиск данных в OpenSearch
- 8.1.5: Начало работы с безопасностью в OpenSearch
- 8.1.6: Основные концепции OpenSearch
- 8.2: Install and upgrade OpenSearch
- 8.2.1: Установка OpenSearch
- 8.2.1.1: Docker
- 8.2.1.2: Установка OpenSearch на Debian
- 8.2.2: Установка OpenSearch Dashboards
- 8.2.2.1: Запуск OpenSearch Dashboards с использованием Docker
- 8.2.2.2: Установка OpenSearch Dashboards (Debian)
- 8.2.2.3: Настройка TLS для OpenSearch Dashboards
- 8.2.3: configuring opensearch
- 8.2.3.1: Настройки доступности и восстановления
- 8.2.3.2: Конфигурация и системные настройки
- 8.2.3.3: Сетевые настройки
- 8.2.3.4: Настройки обнаружения и шлюза
- 8.2.3.5: Настройки безопасности
- 8.2.3.6: Настройки предохранителей
- 8.2.3.7: Настройка кластера
- 8.2.3.8: Настройка индекса
- 8.2.3.9: Настройки поиска
- 8.2.3.10: Настройки плагинов
- 8.2.3.11: Экспериментальные флаги функций
- 8.2.3.12: Logs
- 8.2.4: Сравнение ОС
- 8.2.5: Настройка OpenSearch Dashboards
- 8.2.6: Upgrading OpenSearch
- 8.2.6.1: Приложение по обновлениям
- 8.2.6.2: Постепенное обновление
- 8.2.6.3: Лаборатория последовательного обновления
- 8.2.7: Установка плагинов
- 8.2.7.1: Дополнительные плагины
- 8.2.7.2: mapper-size
- 8.2.7.3: ingest-attachment
- 8.2.8: Управление плагинами OpenSearch Dashboards
- 8.3: Query DSL - язык запросов OpenSearch
- 8.3.1: Контекст запроса и фильтра
- 8.3.2: Сравнение термовых и полнотекстовых запросов
- 8.3.3: Термино-уровневые запросы
- 8.3.3.1: exists
- 8.3.3.2: fuzzy
- 8.3.3.3: ids
- 8.3.3.4: prefix
- 8.3.3.5: range
- 8.3.3.6: regexp
- 8.3.3.7: term
- 8.3.3.8: terms
- 8.3.3.9: terms set
- 8.3.3.10: wildcard
- 8.3.4: full_text
- 8.3.4.1: match
- 8.3.4.2: match-bool-prefix
- 8.3.4.3: match-phrase
- 8.3.4.4: match-phrase-prefix
- 8.3.4.5: multi-match
- 8.3.4.6: query-string
- 8.3.4.7: simple-query-string
- 8.3.4.8: intervals query
- 8.3.5: compound queries
- 8.3.5.1: boolean query
- 8.3.5.2: boosting query
- 8.3.5.3: constant_score
- 8.3.5.4: disjunction_max
- 8.3.5.5: function_score
- 8.3.5.6: hibrid
- 8.3.6: geographic and xy query
- 8.3.6.1: Запрос по гео-ограничивающему прямоугольнику
- 8.3.6.2: Запрос по гео-расстоянию
- 8.3.6.3: Запрос по гео-многоугольнику
- 8.3.6.4: Запрос по гео-форме
- 8.3.6.5: xy запрос
- 8.3.7: Объединение запросов
- 8.3.7.1: Запрос has_child
- 8.3.7.2: Запрос has_parent
- 8.3.7.3: Вложенный запрос
- 8.3.7.4: Запрос по идентификатору родителя
- 8.3.8: Запросы Span
- 8.3.8.1: Запрос Span containing
- 8.3.8.2: Запрос Span field masking
- 8.3.8.3: Запрос Span first
- 8.3.8.4: Запрос Span multi-term
- 8.3.8.5: Запрос Span near
- 8.3.8.6: span_not
- 8.3.8.7: Запрос Span or
- 8.3.8.8: Запрос Span term
- 8.3.8.9: Запрос Span within
- 8.3.9: Запрос Match all
- 8.3.10: Специализированные запросы
- 8.3.10.1: distance_feature
- 8.3.10.2: k-NN
- 8.3.10.3: k-NN explain
- 8.3.10.4: neural
- 8.3.10.5: Нейронный разреженный запрос
- 8.3.10.6: Перколяция
- 8.3.10.7: script query
- 8.3.10.8: Запрос с оценкой скрипта
- 8.3.10.9: Запрос шаблона
- 8.3.10.10: Обертка
- 8.3.11: Minimum should match (Минимальное соответствие)
- 8.3.12: Синтаксис регулярных выражений
- 8.4: goclient
- 9: Визуализация графов библиотека Graphviz
- 10: Визуализация графиков и данных Chart.js
- 11: Emacs
- 11.1: LaTeX в Emacs
- 11.2: Yasnippet
- 11.3: Как настроить и работать с Go в Emacs?
- 11.4: Как настроить и работать с Python в Emacs?
- 11.5: Как настроить и работать с Magit?
- 12: GO
- 12.1: Полный гайд по установке и настройке Go для работы с базами данных (OpenSearch, PostgreSQL, SQLite)
- 12.2: Работа с JSON в Go
- 12.3: Работа с OpenSearch в Go для системы управления знаниями
- 12.4: Пакеты языка Go
- 12.4.1: Описание пакета html для GO
- 12.4.1.1: Описание пакета html/template в Go
- 12.4.1.1.1: Шпаргалка по html/template в Go
- 12.4.1.1.2: Подробное руководство по define, template и block в html/template
- 12.4.1.1.3: Шпаргалка по конвейерам и функциям в html/template (Go)
- 12.4.1.1.4: Функции экранирования HTML/JavaScript/URL пакета html/template языка Go
- 12.4.1.1.5: Типы экранирования HTML/JavaScript/URL пакета html/template языка Go
- 12.4.2: Пакет bufio встроенных функций Go
- 12.4.3: Пакет builtin встроенных функций Go
- 12.4.3.1: Функции builtin
- 12.4.3.2: Типы в пакете builtin
- 12.4.4: Описание пакета context языка программирования Go
- 12.4.4.1: Описание функций пакета Context
- 12.4.4.2: Описание типов пакета Context
- 12.4.5: Пакет bytes языка программирования Go
- 12.4.6: Описание пакета database языка программирования Go
- 12.4.6.1: Работа с пакетом database/sql в Go: ошибки и их обработка
- 12.4.6.2: Подробное описание функций пакета database/sql в Go
- 12.4.6.3: Контекст (context) в транзакциях database/sql
- 12.4.6.4: Описание типа database/sql DB
- 12.4.6.5: Описание типа database/sql ColumnType
- 12.4.6.6: Описание типа Conn database/sql
- 12.4.6.7: Описание типа DBStats database/sql
- 12.4.6.8: Описание типа Out database/sql
- 12.4.6.9: Описание типа Row database/sql
- 12.4.6.10: Описание типа Stmt database/sql
- 12.4.6.11: Описание типа Tx database/sql
- 12.4.7: Описание пакета flag языка программирования Go
- 12.4.7.1: Функции пакета flag
- 12.4.7.2: Типы пакета flag
- 12.4.8: Полный справочник по пакету fmt в Go
- 12.4.9: Описание пакета io языка программирования Go
- 12.4.9.1: Описание функций пакета io
- 12.4.9.2: Описание типов пакета io языка программирования GO
- 12.4.9.3: Пакет для работы с файловой системой io/fs
- 12.4.10: Пакет Sync для Go
- 12.4.10.1: Описание пакета sync/atomic
- 12.4.11: Пакет os языка программирования Go
- 12.4.11.1: Описание функций пакета os
- 12.4.11.2: Описание типов пакета os языка программирования Go
- 12.4.11.3: Описание функций и типов пакета os/exec языка программирования Go
- 12.4.11.4: Пакет os/user языка программирования Go
- 12.4.11.5: Пакет os/signal языка программирования Go
- 12.4.12: Описание пакета strconv
- 12.4.12.1: Описание функций пакета strconv
- 12.4.12.2: Тип NumError пакета strconv
- 12.4.13: Описание пакета error языка программирования Go
- 12.4.14: Описание пакета iter языка программирования Go
- 12.4.15: Пакет net встроенных функций и типов языка Go
- 12.4.15.1: Функции пакета net языка Go
- 12.4.15.2: Типы и методы пакета net языка Go
- 12.4.15.3: Пакет net/http встроенных функций и типов языка Go
- 12.4.15.3.1: Функции пакета net/http языка Go
- 12.4.15.3.2: Типы пакета net/http языка Go
- 12.4.15.4: Описание пакета для управления маршрутизацией github.com/julienschmidt/httprouter для GO
- 12.4.16: Пакет OAuth2 языка программирования Go
- 12.4.16.1: Пакет jwt (JSON Web Token)
- 12.4.16.2: Пакет jws (JSON Web Signature)
- 12.4.16.3: Пакет authhandler (Three-Legged OAuth 2.0)
- 12.4.16.4: Пакет clientcredentials OAuth 2.0 Client Credentials Flow
- 12.4.17: Описание пакета string языка программирования Go
- 12.4.17.1: Функции пакета string языка программирования Go
- 12.4.17.2: Описание типов пакета string языка программирования Go
- 12.4.18: Полное описание пакета log в Go
- 12.4.19: Описание пакета unsafe языка программирования Go
- 12.4.20: Пакет time языка программирования Go
- 12.4.21: SCS: Управление HTTP-сессиями для Go
- 12.5: Горутина (goroutine) в Go, Каналы (channels) в Go и Конвейеры (Pipelines) в Go.
- 12.6: Подключение к SQLite в Go: Полное руководство
- 12.7: Спецификация языка программирования Go
- 12.8: Спецификация по модулям языка программирования Go
- 12.9: Изучение языка Go
- 12.9.1: Alex Edwards Let's Go часть 1
- 12.9.2: Alex Edwards Let's Go часть 2
- 12.9.3: Alex Edwards Let's Go часть 3
- 12.9.4: Alex Edwards Let's Go часть 4
- 12.9.5: Alex Edwards Let's Go часть 5
- 12.10: Памятка по примерам GO
- 12.10.1: таблица с основными форматами Printf в Go
- 12.10.2: Closure
- 12.10.3: Создание модуля в GO
- 12.10.4: Создание тестов в GO
- 12.10.5: Работа с Workspace в Go: Полное руководство
- 12.10.6: массивы (arrays) и срезы (slices)
- 12.10.7: Назначение пакетов net и net/http
- 13: Linux
- 13.1: Шпаргалка по полезным командам Linux для работы с дисками и устройствами
- 13.2: Что такое PGP?
- 13.2.1: Структура хранения ключей
- 13.2.2: gpg-agent
- 13.2.3: dirmngr
- 13.2.4: gpg
- 13.2.4.1: Команды GPG
- 13.2.4.2: Опции PGP
- 13.2.4.3: Ввод и вывод
- 13.2.4.4: OpenGPG опции
- 13.2.4.5: Опции соответствия
- 13.2.4.6: Дополнительные опции
- 13.2.4.7: Config
- 13.2.5: gpgsm
- 13.2.6: scdaemon
- 13.2.7: user id
- 13.2.8: сравнение SSH и PGP
- 13.3: Инструкция по настройке клавиатуры для i2wm с xkb
- 13.4: JQ парсер JSON
- 13.5: Шпаргалка по основным командам nano
- 13.6: Шпаргалка по основным командам Vim
- 13.7: Пакет scrcpy для управления Android устройством через Linux
- 13.8: Установка виртуальных машин QEMU/KVM на рабочей станции или сервере
- 13.9: Шпаргалка по основным командам crone
- 13.10: Шпаргалка по работе с ядрами в Linux
- 13.11: Find and Sed
- 13.12: Управление пакетами PACMAN
- 13.13: UGREP и все о нем
- 13.14: Find
- 13.15: ZSH
- 13.16: Строчный редактор SED
- 13.17: SSH на все случаи жизни
- 13.18: i3
- 13.19: Файловый менеджер ranger
- 14: Mailu
- 15: Nginx
- 16: Управление базами данных: основные команды
1 - Искусственный интеллект
1.1 - Ollama
1.1.1 - Настройка запросов к моделям через Ollama
Структура JSON модели для передачи на сервер OLLAMA
{
"model": "qwen3:4b",
"prompt": "Ваш запрос",
"stream": false,
"format": "json",
"options": {
"temperature": 0.8,
"top_p": 0.9,
"top_k": 40,
"num_predict": 512,
"stop": ["\n", "###"],
"repeat_penalty": 1.1,
"presence_penalty": 0.0,
"frequency_penalty": 0.0,
"seed": 42,
"mirostat": 0,
"num_ctx": 2048,
"num_thread": 8
},
"template": "{{ .Prompt }}",
"context": [1, 2, 3]
}
Описание и назначение основных параметров для управления моделями в Ollama:
1. "model": "qwen3:4b"
- Что делает: Указывает, какую модель использовать
- Применение: Замените на нужную модель:
"llama3:8b","mistral:7b", etc - Пример:
"model": "llama3:8b"
2. "prompt": "Ваш запрос"
- Что делает: Текст запроса к модели
- Применение: Можно использовать многострочные промпты
- Пример:
"prompt": "Напиши рецепт пасты карбонара:\n"
3. "stream": false
- Что делает: Возвращать ответ потоком или целиком
- Применение:
false- весь ответ сразу (для скриптов)true- потоковая передача (для UI)
- Пример:
"stream": true
4. "format": "json"
- Что делает: Заставляет модель возвращать ответ в JSON формате
- Применение: Полезно для структурированных данных
- Пример:
"format": "json"+"prompt": "Верни JSON с именем и возрастом"
В Ollama параметр format поддерживает несколько значений:
Толкование
Поддерживаемые форматы
1. "format": "json"
- Описание: Заставляет модель возвращать ответ в валидном JSON формате
- Пример промпта:
"Верни JSON: {\\\"name\\\": \\\"John\\\", \\\"age\\\": 30}" - Пример вывода:
{"name": "John", "age": 30}
2. "format": "text" (по умолчанию)
- Описание: Обычный текстовый ответ без специального форматирования
- Пример промпта:
"Расскажи о космосе" - Пример вывода:
"Космос - это бескрайнее пространство..."
3. "format": "markdown"
- Описание: Ответ в формате Markdown
- Пример промпта:
"Напиши документацию в markdown" - Пример вывода:
# Заголовок - Список **Жирный текст**
4. "format": "html"
- Описание: Ответ в HTML формате
- Пример промпта:
"Создай HTML страницу" - Пример вывода:
<html><body><h1>Заголовок</h1></body></html>
5. "format": "xml"
- Описание: Ответ в XML формате
- Пример промпта:
"Верни данные в XML" - Пример вывода:
<data><name>John</name><age>30</age></data>
6. "format": "yaml"
- Описание: Ответ в YAML формате
- Пример промпта:
"Верни конфигурацию в YAML" - Пример вывода:
name: John age: 30
7. "format": "csv"
- Описание: Ответ в CSV формате
- Пример промпта:
"Верни данные в CSV" - Пример вывода:
name,age\nJohn,30\nJane,25
8. "format": "code"
- Описание: Для генерации кода (поддерживает подсветку синтаксиса)
- Пример промпта:
"Напиши функцию на Python" - Пример вывода:
def hello(): return "Hello World"
Практические примеры:
JSON запрос:
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Верни JSON с информацией о пользователе: имя, возраст, город",
"format": "json",
"stream": false
}'
Markdown запрос:
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Напиши руководство по Git в markdown",
"format": "markdown",
"stream": false
}'
HTML запрос:
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Создай простую HTML страницу с заголовком и параграфом",
"format": "html",
"stream": false
}'
Важные замечания:
- Не все модели одинаково хорошо поддерживают все форматы
- Формат - это указание модели, а не гарантия
- Лучше всего работают JSON и text
- Для сложных форматов лучше явно указывать в промпте
Комбинирование с промптом:
# Более надежный способ
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Верни ответ в формате JSON: {\"name\": \"string\", \"age\": number}",
"format": "json",
"stream": false
}'
Большинство моделей лучше всего работают с json и text форматами.
Параметры в options:
5. "temperature": 0.8
- Что делает: Контролирует случайность ответов (0.0-1.0)
- Применение:
0.1- детерминированные, повторяемые ответы0.8- креативные, разнообразные ответы1.0- максимальная случайность
- Пример:
"temperature": 0.3для фактологических ответов
6. "top_p": 0.9
- Что делает: nucleus sampling - учитывает только топ-N% вероятных слов
- Применение:
0.1- только самые вероятные слова0.9- более разнообразный выбор
- Пример:
"top_p": 0.7
7. "top_k": 40
- Что делает: Ограничивает выбор только топ-K слов
- Применение:
10- только 10 самых вероятных слов40- хороший баланс
- Пример:
"top_k": 20
Толкование
Подробное объяснение top_p и top_k
top_p (также known as nucleus sampling) - это алгоритм выборки, который ограничивает генерацию только теми словами, кумулятивная вероятность которых попадает в верхние P% распределения.
Как это работает:
- Сортировка вероятностей: Модель ранжирует все возможные следующие слова по вероятности
- Кумулятивная сумма: Складывает вероятности от самой высокой к самой низкой
- Выбор ядра: Берет только те слова, чья кумулятивная сумма ≤
top_p - Перераспределение вероятностей: Нормализует вероятности выбранных слов
Математическая формула:
Выбрать множество V таких что: ∑(p(x) для x в V) ≥ p
где p = значение top_p (0.0-1.0)
Практические примеры:
Пример 1: top_p = 0.3 (очень строгий)
Возможные слова:
- "кот" (p=0.25)
- "собака" (p=0.20)
- "птица" (p=0.15)
- "рыба" (p=0.10)
- ... остальные (сумма p=0.30)
Выбор: только "кот" (0.25 ≤ 0.3)
Пример 2: top_p = 0.6 (умеренный)
Выбор: "кот" + "собака" + "птица" (0.25+0.20+0.15=0.6)
Пример 3: top_p = 0.9 (либеральный)
Выбор: почти все вероятные слова кроме самых маловероятных
Сравнение с top_k:
| Параметр | Что делает | Преимущества | Недостатки |
|---|---|---|---|
top_p | Динамический выбор вероятностей | Автоматически адаптируется к распределению | Может быть непредсказуемым |
top_k | Фиксированное количество слов | Предсказуемость | Не учитывает распределение вероятностей |
Рекомендации по использованию:
Для точных ответов:
{
"top_p": 0.3,
"temperature": 0.1,
"top_k": 20
}
- Фактологические ответы
- Техническая документация
- Код генерация
Для творческих текстов:
{
"top_p": 0.9,
"temperature": 0.8,
"top_k": 60
}
- Поэзия
- Художественные тексты
- Креативные идеи
Для баланса:
{
"top_p": 0.7,
"temperature": 0.5,
"top_k": 40
}
- Диалоги
- Общие вопросы
- Аналитические тексты
Практические примеры запросов:
1. Строгий режим (top_p = 0.3)
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Столица Франции это",
"top_p": 0.3,
"temperature": 0.1,
"stream": false
}'
Результат: “Париж” (максимально точный ответ)
2. Творческий режим (top_p = 0.9)
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Опиши закат на море",
"top_p": 0.9,
"temperature": 0.8,
"stream": false
}'
Результат: Развернутое художественное описание
3. Комбинирование с другими параметрами
{
"top_p": 0.7,
"top_k": 50,
"temperature": 0.6,
"repeat_penalty": 1.1
}
Частые ошибки:
Слишком низкий top_p:
{"top_p": 0.1} # Может приводить к зацикливанию
Слишком высокий top_p:
{"top_p": 0.99} # Почти не фильтрует, может включать nonsense
Конфликт с temperature:
{"top_p": 0.3, "temperature": 0.9} # Противоречивые настройки
Золотые правила:
top_pиtemperatureдолжны быть согласованы- Низкий top_p + низкая temperature = точность
- Высокий top_p + высокая temperature = креативность
- Тестируйте разные значения для вашей задачи
Оптимальные значения для большинства задач: top_p: 0.7-0.9
8. "num_predict": 512
- Что делает: Максимальное количество генерируемых токенов
- Применение:
64- короткие ответы512- средние ответы2048- длинные тексты
- Пример:
"num_predict": 256
9. "stop": ["\n", "###"]
- Что делает: Символы/слова, при которых генерация останавливается
- Применение:
["\n"]- остановиться в конце строки["###", "Конец"]- кастомные стоп-слова
- Пример:
"stop": ["\n\n", "Ответ:"]
10. "repeat_penalty": 1.1
- Что делает: Штраф за повторения (>1.0 уменьшает повторения)
- Применение:
1.0- без штрафа1.2- сильный штраф за повторения
- Пример:
"repeat_penalty": 1.15
11. "presence_penalty": 0.0
- Что делает: Штраф за новые темы (положительные значения поощряют новизну)
- Применение:
-2.0до2.0
12. "frequency_penalty": 0.0
- Что делает: Штраф за частые слова
- Применение:
-2.0до2.0
13. "seed": 42
- Что делает: Seed для детерминированной генерации
- Применение: Одинаковый seed = одинаковые ответы
- Пример:
"seed": 12345
Толкование
Подробное объяснение SEED
Seed (сид) - это начальное значение для генератора псевдослучайных чисел. В контексте LLM это означает, что при одинаковых:
- Модели
- Промпте
- Параметрах
- И одинаковом seed
Вы получите идентичный результат каждый раз.
Как это работает технически:
- Инициализация:
seed = 42 - Детерминированность: Генератор случайных чисел начинает с одинаковой точки
- Воспроизводимость: Все “случайные” выборы становятся предсказуемыми
- Идентичный результат: Токен за токеном одинаковый вывод
Практические примеры:
Пример 1: Детерминированная генерация
# Первый запуск
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Напиши короткое стихотворение о весне",
"seed": 42,
"stream": false
}'
# Второй запуск (ТОЧНО такой же результат)
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Напиши короткое стихотворение о весне",
"seed": 42,
"stream": false
}'
Пример 2: Разные seed = разные результаты
# Seed 42
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Придумай название для кофе",
"seed": 42,
"stream": false
}'
# Результат: "Утренняя свежесть"
# Seed 43 (немного другой)
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Придумай название для кофе",
"seed": 43,
"stream": false
}'
# Результат: "Золотой эспрессо"
Ключевые особенности:
1. Полная детерминированность
{
"seed": 123,
"temperature": 0.1, // Должен быть низким!
"top_p": 0.3 // Должен быть низким!
}
- ✅ Работает с низкой temperature
- ✅ Работает с низким top_p
- ❌ Не работает с высокой temperature
2. Зависимость от всех параметров
# Изменится ЛЮБОЙ параметр → изменится результат
seed=42 + prompt="A" ≠ seed=42 + prompt="A "
3. Постоянство между запусками
# Сегодня
seed=42 → "Ответ А"
# Завтра
seed=42 → "Ответ А" (тот же самый)
# После перезагрузки
seed=42 → "Ответ А" (все равно тот же)
Практическое применение:
1. Тестирование и отладка
# Тестирование изменений промпта
seed=42 + prompt="Версия 1" → Результат А
seed=42 + prompt="Версия 2" → Результат Б
# Можно точно сравнить улучшения
2. Воспроизведение результатов
# Найден хороший результат → сохраняем seed
curl ... -d '{
"prompt": "Креативное название",
"seed": 78901, # ← ЗАПОМНИТЬ ЭТОТ SEED
"temperature": 0.3
}'
# Результат: "Небесный аромат" (сохраняем для производства)
3. A/B тестирование моделей
# Сравнение моделей на одинаковых данных
seed=42 + model="qwen3:4b" → Результат А
seed=42 + model="llama3:8b" → Результат Б
# Честное сравнение без случайности
4. Обучение и демонстрации
# Демо для клиента - всегда одинаковый результат
seed=12345 → "Ваш идеальный бизнес-план..."
Важные ограничения:
1. Temperature должен быть низким
{
"seed": 42,
"temperature": 0.9, // ❌ Высокая randomness
"top_p": 0.9 // ❌ Высокая randomness
}
// Результат НЕ будет детерминированным!
2. Оптимальные настройки для детерминированности
{
"seed": 42,
"temperature": 0.1, // ✅ Низкая случайность
"top_p": 0.3, // ✅ Строгая выборка
"top_k": 20, // ✅ Ограниченный выбор
"repeat_penalty": 1.1 // ✅ Предсказуемость
}
3. Зависит от версии модели
# Модель обновилась → результаты могут измениться
seed=42 + model=v1.0 → Результат А
seed=42 + model=v1.1 → Результат Б (может отличаться)
Практические примеры настроек:
Для детерминированного кода:
{
"seed": 12345,
"temperature": 0.1,
"top_p": 0.2,
"top_k": 10,
"prompt": "Напиши функцию на Python для сложения чисел"
}
Для воспроизводимых аналитических ответов:
{
"seed": 67890,
"temperature": 0.2,
"top_p": 0.4,
"prompt": "Проанализируй преимущества технологии блокчейн"
}
Для тестирования промптов:
{
"seed": 11111,
"temperature": 0.1,
"prompt": "Версия 1 промпта..."
}
// Меняем только промпт, сохраняем seed
Как выбрать хороший seed?
# Любое целое число
"seed": 42
"seed": 1234567890
"seed": 999888777
# Но лучше избегать:
"seed": 0 # Иногда особый случай
"seed": 1 # Слишком простой
"seed": 123456 # Нормально
Пример полного workflow:
- Экспериментируем без seed, находим хорошие параметры
- Фиксируем параметры и промпт
- Добавляем
"seed": 12345для воспроизводимости - Сохраняем конфигурацию для production
{
"model": "qwen3:4b",
"prompt": "Генерируй креативные названия для кофе",
"seed": 424242,
"temperature": 0.3,
"top_p": 0.6,
"top_k": 30,
"num_predict": 50
}
Seed - это мощный инструмент для обеспечения воспроизводимости и отладки LLM приложений!
14. "mirostat": 0
- Что делает: Алгоритм контроля перплексии (0, 1, 2)
- Применение:
0- выключено1или2- для контроля качества
Толкование
Подробное объяснение MIROSTAT
Mirostat - это алгоритм контроля качества текста, который динамически регулирует параметры генерации чтобы поддерживать заданный уровень перплексии (сложности/предсказуемости текста).
Как это работает:
Mirostat постоянно измеряет перплексию генерируемого текста и подстраивает параметры в реальном времени чтобы достичь целевого значения.
Аналогия:
Представьте круиз-контроль в автомобиле:
- Без mirostat: Вы сами управляете газом/тормозом
- С mirostat: Автоматически поддерживает заданную скорость
Режимы работы:
"mirostat": 0 - Выключено
{"mirostat": 0}
- Обычная генерация
- Без контроля качества
- По умолчанию
"mirostat": 1 - Mirostat 1.0
{
"mirostat": 1,
"mirostat_tau": 5.0,
"mirostat_eta": 0.1
}
- Более простой алгоритм
- Меньше вычислительных затрат
"mirostat": 2 - Mirostat 2.0
{
"mirostat": 2,
"mirostat_tau": 5.0,
"mirostat_eta": 0.1
}
- Улучшенная версия
- Более точный контроль
- Лучшее качество текста
Дополнительные параметры:
mirostat_tau - Целевая перплексия
{"mirostat_tau": 5.0}
- Низкие значения (2.0-4.0): Более предсказуемый, простой текст
- Средние значения (4.0-6.0): Баланс сложности и читаемости
- Высокие значения (6.0-8.0): Более сложный, креативный текст
mirostat_eta - Скорость обучения
{"mirostat_eta": 0.1}
- Низкие значения (0.01-0.1): Медленная адаптация, стабильность
- Высокие значения (0.1-0.3): Быстрая адаптация, агрессивные изменения
Практические примеры:
Пример 1: Техническая документация
{
"mirostat": 2,
"mirostat_tau": 3.0, // Низкая перплексия = простота
"mirostat_eta": 0.05,
"prompt": "Объясни концепцию API REST"
}
Результат: Четкий, структурированный текст без излишней сложности
Пример 2: Художественный текст
{
"mirostat": 2,
"mirostat_tau": 7.0, // Высокая перплексия = сложность
"mirostat_eta": 0.2,
"prompt": "Напиши поэтическое описание заката"
}
Результат: Богатый, образный язык с сложными конструкциями
Пример 3: Сбалансированный режим
{
"mirostat": 1,
"mirostat_tau": 5.0, // Баланс
"mirostat_eta": 0.1,
"prompt": "Напиши статью о искусственном интеллекте"
}
Сравнение с традиционными параметрами:
Без Mirostat:
{
"temperature": 0.7,
"top_p": 0.9,
"top_k": 40
}
// Качество может "плавать" в течение генерации
С Mirostat:
{
"mirostat": 2,
"mirostat_tau": 5.0,
"mirostat_eta": 0.1
}
// Постоянное качество throughout текста
Преимущества Mirostat:
- Стабильное качество: Избегает деградации в длинных текстах
- Автоматическая адаптация: Не нужно manually настраивать temperature
- Контроль сложности: Точная настройка уровня сложности текста
- Воспроизводимость: Предсказуемые результаты
Недостатки:
- Вычислительная стоимость: Дополнительные расчеты
- Сложность настройки: Нужно понимать перплексию
- Не для всех задач: Иногда проще использовать temperature
Рекомендации по настройке:
Для разных задач:
| Задача | mirostat_tau | mirostat_eta |
|---|---|---|
| Техническая документация | 2.0-4.0 | 0.05-0.1 |
| Новостные статьи | 4.0-6.0 | 0.1-0.2 |
| Художественная литература | 6.0-8.0 | 0.2-0.3 |
| Научные тексты | 5.0-7.0 | 0.1-0.15 |
Примеры полных конфигураций:
Высокое качество, стабильность:
{
"mirostat": 2,
"mirostat_tau": 5.0,
"mirostat_eta": 0.1,
"temperature": 0.3,
"top_p": 0.8
}
Креативность с контролем:
{
"mirostat": 2,
"mirostat_tau": 7.0,
"mirostat_eta": 0.25,
"temperature": 0.7
}
Практический пример запроса:
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Напиши подробное руководство по использованию Docker",
"mirostat": 2,
"mirostat_tau": 4.0,
"mirostat_eta": 0.08,
"temperature": 0.2,
"stream": false
}' | jq -r '.response'
Когда использовать Mirostat:
✅ Длинные тексты (избегает деградации качества)
✅ Консистентность (техдокументация, руководства)
✅ Точный контроль сложности текста
✅ Автоматизация генерации контента
Когда НЕ использовать:
❌ Короткие ответы (излишне сложно)
❌ Максимальная скорость (дополнительные вычисления)
❌ Эксперименты (проще использовать temperature)
❌ Очень креативные задачи (может ограничивать)
Отладка Mirostat:
Если текст слишком простой:
{"mirostat_tau": 6.0} // Увеличить перплексию
Если текст слишком сложный:
{"mirostat_tau": 3.0} // Уменьшить перплексию
Если качество нестабильное:
{"mirostat_eta": 0.05} // Уменьшить скорость обучения
15. "num_ctx": 2048
- Что делает: Размер контекстного окна
- Применение: Зависит от модели
16. "num_thread": 8
- Что делает: Количество потоков для вычислений
- Применение: Обычно равно количеству ядер CPU
Дополнительные параметры:
17. "template": "{{ .Prompt }}"
- Что делает: Шаблон для форматирования промпта
- Применение:
"template": "Ответь как эксперт: {{ .Prompt }}\nОтвет:"
18. "context": [1, 2, 3]
- Что делает: Контекст предыдущего взаимодействия
- Применение: Для продолжения диалога
Толкование
Подробное объяснение CONTEXT
Context - это массив чисел, который представляет собой “память” предыдущего взаимодействия с моделью. Это позволяет продолжить диалог или текст точно с того места, где остановились.
Как это работает технически:
Контекст содержит эмбеддинги (векторные представления) предыдущего взаимодействия:
- Кодирование: Текст → числовой вектор
- Сохранение: Вектор сохраняется в
context - Восстановление: При следующем запросе вектор передается обратно
- Продолжение: Модель “помнит” предыдущий разговор
Практический пример workflow:
Шаг 1: Первый запрос
response=$(curl -s http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Расскажи о преимуществах Python",
"stream": false
}')
# Извлекаем ответ И контекст
answer=$(echo $response | jq -r '.response')
context=$(echo $response | jq '.context')
Шаг 2: Продолжение с контекстом
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "А какие недостатки?",
"context": '"$context"',
"stream": false
}'
Полный пример скрипта:
#!/bin/bash
# Первый запрос
echo "Шаг 1: Первый запрос"
response1=$(curl -s http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Расскажи о Python для начинающих",
"stream": false
}')
answer1=$(echo $response1 | jq -r '.response')
context=$(echo $response1 | jq '.context')
echo "Ответ: $answer1"
echo "Контекст сохранен"
# Второй запрос с контекстом
echo -e "\nШаг 2: Продолжение диалога"
response2=$(curl -s http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Какие книги посоветуешь для изучения?",
"context": '"$context"',
"stream": false
}')
answer2=$(echo $response2 | jq -r '.response')
echo "Ответ: $answer2"
Формат контекста:
Контекст возвращается и принимается как массив чисел:
{
"context": [123, 456, 789, 12, 34, 56, 78, 90, ...]
}
Практические применения:
1. Многошаговые диалоги
# Пользователь: Привет
# Модель: Привет! Как дела?
# Пользователь: Хорошо, расскажи о погоде
# Модель: Помнит предыдущие реплики
2. Продолжение длинных текстов
# Начало: "В далекой галактике..."
# Продолжение: "где мы остановились..."
3. Технические консультации
# Шаг 1: Обсуждение проблемы
# Шаг 2: Уточняющие вопросы
# Шаг 3: Решение с учетом всей истории
4. Написание кода по частям
# Сначала: архитектура проекта
# Затем: реализация конкретных функций
# В конце: тестирование
Преимущества использования context:
По сравнению с передачей всей истории в prompt:
# Без context (громоздко):
"prompt": "Предыдущий разговор: Привет - Привет! Как дела? - Хорошо. Текущий вопрос: Что нового?"
# С context (эффективно):
"prompt": "Что нового?",
"context": [123, 456, 789]
Экономия токенов:
- ❌ Без context: Каждый раз передается вся история
- ✅ С context: Передаются только компактные эмбеддинги
Сохраняется состояние:
- Переменные
- Контекст разговора
- Стиль и тон
- Технические детали
Ограничения и важные моменты:
1. Совместимость моделей
# Контекст от одной модели может не работать с другой
context от "qwen3:4b" ≠ context для "llama3:8b"
2. Временные ограничения
# Контекст может "устаревать" после долгого времени
# Или после обновления модели
3. Размер контекста
# Слишком длинный контекст может быть обрезан
# Зависит от ограничений модели
4. Не для всех задач
# Для совершенно новых тем лучше не использовать context
# Чтобы избежать влияния предыдущего разговора
Пример с обработкой ошибок:
#!/bin/bash
ask_question() {
local prompt="$1"
local context="$2"
local data='{
"model": "qwen3:4b",
"prompt": "'"$prompt"'",
"stream": false'
if [ -n "$context" ] && [ "$context" != "null" ]; then
data+=', "context": '"$context"
fi
data+='}'
curl -s http://localhost:11434/api/generate -d "$data"
}
# Диалог
response1=$(ask_question "Привет! Как тебя зовут?")
answer1=$(echo $response1 | jq -r '.response')
context1=$(echo $response1 | jq '.context')
echo "Модель: $answer1"
response2=$(ask_question "А чем ты занимаешься?" "$context1")
answer2=$(echo $response2 | jq -r '.response')
echo "Модель: $answer2"
Использование в API чата:
Для чат-интерфейсов лучше использовать /api/chat:
curl http://localhost:11434/api/chat -d '{
"model": "qwen3:4b",
"messages": [
{"role": "user", "content": "Привет"},
{"role": "assistant", "content": "Привет! Как дела?"},
{"role": "user", "content": "Хорошо, а у тебя?"}
],
"stream": false
}'
Лучшие практики:
1. Сохраняйте контекст между запросами
# В приложении сохраняйте context в:
# - Базе данных
# - Файле
# - Памятии сессии
2. Очищайте контекст для новых тем
# Если тема полностью меняется:
context=null
3. Проверяйте валидность контекста
if [ "$context" != "null" ] && [ -n "$context" ]; then
# Используем контекст
else
# Новый разговор
fi
4. Ограничивайте длину диалога
# После N реплик начинайте новый контекст
# Чтобы избежать накопления ошибок
Продвинутое использование:
Сохранение контекста в файл:
# Сохраняем
echo $context > context.json
# Загружаем
context=$(cat context.json)
Многоуровневые диалоги:
# Разные контексты для разных тем
context_python=$(cat python_context.json)
context_js=$(cat js_context.json)
Воспроизведение диалогов:
# Для тестирования можно сохранить и воспроизвести
# exact диалог с одинаковым context
Пример для продакшена:
# Псевдокод для веб-приложения
sessions = {}
def handle_message(user_id, message):
if user_id not in sessions:
# Новый диалог
response = ollama.generate(prompt=message)
sessions[user_id] = {
'context': response['context'],
'history': [message, response['response']]
}
else:
# Продолжение диалога
response = ollama.generate(
prompt=message,
context=sessions[user_id]['context']
)
sessions[user_id]['context'] = response['context']
sessions[user_id]['history'].extend([message, response['response']])
return response['response']
Практические примеры настроек:
Для точных фактологических ответов:
{
"temperature": 0.1,
"top_p": 0.3,
"top_k": 20,
"repeat_penalty": 1.2
}
Для креативных текстов:
{
"temperature": 0.9,
"top_p": 0.95,
"top_k": 60,
"num_predict": 1024
}
Для детерминированных результатов:
{
"temperature": 0.1,
"seed": 42,
"top_p": 0.1
}
1.1.2 - Пример с curl и полным набором параметров
#!/bin/bash
# Первый запрос - получаем контекст
echo "=== Первый запрос ==="
response1=$(curl -s http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Расскажи о преимуществах языка Python",
"stream": false,
"format": "json",
"options": {
"temperature": 0.7,
"top_p": 0.9,
"top_k": 40,
"num_predict": 256,
"stop": ["\n", "###"],
"repeat_penalty": 1.1,
"presence_penalty": 0.0,
"frequency_penalty": 0.0,
"seed": 42,
"mirostat": 2,
"mirostat_tau": 5.0,
"mirostat_eta": 0.1,
"num_ctx": 2048,
"num_thread": 8
},
"template": "Ответь как эксперт: {{ .Prompt }}\n\nОтвет:"
}')
# Извлекаем ответ и контекст
answer1=$(echo $response1 | jq -r '.response')
context=$(echo $response1 | jq '.context')
echo "Ответ: $answer1"
echo "Контекст получен"
# Второй запрос с контекстом
echo -e "\n=== Второй запрос с контекстом ==="
response2=$(curl -s http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "А какие у Python недостатки?",
"context": '"$context"',
"stream": false,
"format": "text",
"options": {
"temperature": 0.5,
"top_p": 0.8,
"top_k": 30,
"num_predict": 200,
"stop": ["\n\n"],
"repeat_penalty": 1.2,
"seed": 123
}
}')
answer2=$(echo $response2 | jq -r '.response')
echo "Ответ: $answer2"
1.1.3 - Пример из командной строки с ollama run
# Создаем конфигурационный файл для первого запроса
cat > first_request.txt << 'EOF'
Расскажи о преимуществах языка Python для data science
EOF
# Первый запрос с полными параметрами через stdin
echo "=== Первый запрос ==="
response1=$(ollama run qwen3:4b --temperature 0.7 --top-p 0.9 --top-k 40 \
--num-predict 256 --seed 42 --mirostat 2 --mirostat-tau 5.0 --mirostat-eta 0.1 \
--repeat-penalty 1.1 --stop "\n" --stop "###" < first_request.txt)
echo "$response1"
# Сохраняем промпт для второго запроса
cat > second_request.txt << 'EOF'
А какие недостатки у Python для data science по сравнению с R?
EOF
# Второй запрос (Ollama run не поддерживает context напрямую,
# поэтому используем альтернативный подход)
echo -e "\n=== Второй запрос ==="
ollama run qwen3:4b --temperature 0.5 --top-p 0.8 --top-k 30 \
--num-predict 200 --seed 123 --repeat-penalty 1.2 < second_request.txt
1.1.4 - Alias для zsh с конфигурационным файлом YAML
Установите дополнительные зависимости
# Для Ubuntu/Debian
sudo apt-get install yq jq
#Для Arch
sudo pacman -S yq jq
Добавить настройку в ~/.zshrc:
# Alias для работы с конфигурационным файлом
alias ollama-config='func() {
local config_file="$1"
local prompt="$2"
if [ ! -f "$config_file" ]; then
echo "Config file $config_file not found!"
return 1
fi
# Читаем конфигурацию из файла
local model=$(yq eval ".model" "$config_file")
local temperature=$(yq eval ".options.temperature" "$config_file")
local top_p=$(yq eval ".options.top_p" "$config_file")
local top_k=$(yq eval ".options.top_k" "$config_file")
local num_predict=$(yq eval ".options.num_predict" "$config_file")
local seed=$(yq eval ".options.seed" "$config_file")
# Выполняем запрос
ollama run "$model" --temperature "$temperature" --top-p "$top_p" \
--top-k "$top_k" --num-predict "$num_predict" --seed "$seed" "$prompt"
}; func'
# Alias для JSON конфигурации
alias ollama-json='func() {
local config_file="$1"
local prompt="$2"
if [ ! -f "$config_file" ]; then
echo "Config file $config_file not found!"
return 1
fi
# Используем jq для извлечения параметров
local model=$(jq -r ".model" "$config_file")
local temperature=$(jq -r ".options.temperature" "$config_file")
local top_p=$(jq -r ".options.top_p" "$config_file")
ollama run "$model" --temperature "$temperature" --top-p "$top_p" "$prompt"
}; func'
Конфигурационный файл ollama_config.yaml:
model: qwen3:4b
options:
temperature: 0.7
top_p: 0.9
top_k: 40
num_predict: 256
seed: 42
repeat_penalty: 1.1
mirostat: 2
mirostat_tau: 5.0
mirostat_eta: 0.1
format: text
Использование
# Установите yq для работы с YAML: brew install yq
ollama-config ollama_config.yaml "Расскажи о machine learning"
# Или с JSON конфигом
ollama-json config.json "Напиши код на Python"
1.1.5 - Запуск модели из Ollama с конфигурационным файлом JSON
Командная строка с передачей JSON файла
Создаем конфигурационный файл request_config.json:
{
"model": "qwen3:4b",
"prompt": "Объясни концепцию искусственного интеллекта",
"stream": false,
"format": "markdown",
"options": {
"temperature": 0.7,
"top_p": 0.9,
"top_k": 40,
"num_predict": 300,
"stop": ["\n", "##"],
"repeat_penalty": 1.1,
"presence_penalty": 0.0,
"frequency_penalty": 0.0,
"seed": 424242,
"mirostat": 2,
"mirostat_tau": 5.0,
"mirostat_eta": 0.1,
"num_ctx": 2048,
"num_thread": 8
},
"template": "Ответь как эксперт по AI: {{ .Prompt }}\n\n"
}
Скрипт для обработки JSON конфига:
#!/bin/bash
process_ollama_config() {
local config_file="$1"
if [ ! -f "$config_file" ]; then
echo "Config file $config_file not found!"
return 1
fi
# Извлекаем параметры из JSON
local model=$(jq -r '.model' "$config_file")
local prompt=$(jq -r '.prompt' "$config_file")
local temperature=$(jq -r '.options.temperature' "$config_file")
local top_p=$(jq -r '.options.top_p' "$config_file")
local top_k=$(jq -r '.options.top_k' "$config_file")
local num_predict=$(jq -r '.options.num_predict' "$config_file")
local seed=$(jq -r '.options.seed' "$config_file")
local repeat_penalty=$(jq -r '.options.repeat_penalty' "$config_file")
# Строим команду ollama run
local command="ollama run '$model' --temperature $temperature --top-p $top_p --top-k $top_k --num-predict $num_predict --seed $seed --repeat-penalty $repeat_penalty"
# Добавляем stop слова если они есть
local stop_words=$(jq -r '.options.stop[]?' "$config_file" 2>/dev/null)
if [ -n "$stop_words" ]; then
while IFS= read -r word; do
command+=" --stop \"$word\""
done <<< "$stop_words"
fi
# Добавляем промпт
command+=" \"$prompt\""
echo "Выполняем команду: $command"
eval "$command"
}
# Использование
process_ollama_config "request_config.json"
Альтернативный вариант с прямым использованием curl:
#!/bin/bash
# Прямое использование JSON конфига с curl
curl -s http://localhost:11434/api/generate \
-H "Content-Type: application/json" \
-d "$(cat request_config.json)" \
| jq -r '.response'
1.1.6 - Запуск модели из Ollama с конфигурационным файлом JSON и контекстом
Продвинутый пример с контекстом и многошаговым диалогом
Создаем скрипт advanced_dialog.sh:
#!/bin/bash
CONFIG_FILE="dialog_config.json"
CONTEXT_FILE="context.json"
# Функция для отправки запроса
send_request() {
local prompt="$1"
local context="${2:-null}"
local request_data=$(jq --arg prompt "$prompt" --argjson context "$context" '
{
model: .model,
prompt: $prompt,
stream: false,
format: .format,
options: .options,
template: .template,
context: $context
}' "$CONFIG_FILE")
curl -s http://localhost:11434/api/generate \
-H "Content-Type: application/json" \
-d "$request_data"
}
# Основной диалог
echo "🤖 Начинаем диалог с AI"
# Шаг 1
echo "👤: Расскажи о Python"
response1=$(send_request "Расскажи о Python")
answer1=$(echo $response1 | jq -r '.response')
context=$(echo $response1 | jq '.context')
echo "🤖: $answer1"
# Сохраняем контекст
echo "$context" > "$CONTEXT_FILE"
# Шаг 2 с контекстом
echo -e "\n👤: А какие у него недостатки?"
response2=$(send_request "А какие у него недостатки?" "$(cat $CONTEXT_FILE)")
answer2=$(echo $response2 | jq -r '.response')
echo "🤖: $answer2"
# Обновляем контекст
echo "$(echo $response2 | jq '.context')" > "$CONTEXT_FILE"
# Шаг 3
echo -e "\n👤: Что посоветуешь для изучения?"
response3=$(send_request "Что посоветуешь для изучения?" "$(cat $CONTEXT_FILE)")
answer3=$(echo $response3 | jq -r '.response')
echo "🤖: $answer3"
Конфигурационный файл dialog_config.json:
{
"model": "qwen3:4b",
"format": "text",
"template": "Ответь дружелюбно и подробно: {{ .Prompt }}\n\n",
"options": {
"temperature": 0.7,
"top_p": 0.9,
"top_k": 40,
"num_predict": 200,
"stop": ["\n\n", "###"],
"repeat_penalty": 1.1,
"seed": 12345,
"mirostat": 1,
"mirostat_tau": 5.0,
"mirostat_eta": 0.1
}
}
Запуск:
chmod +x advanced_dialog.sh
./advanced_dialog.sh
1.1.7 - Запуск модели Ollama с конфигурационным файлом JSON из NODE.JS
JavaScript/Node.js пример с полными параметрами
Установите зависимости:
npm init -y
npm install axios
ollama-client.js:
const axios = require('axios');
class OllamaClient {
constructor(baseURL = 'http://localhost:11434') {
this.baseURL = baseURL;
this.context = null;
}
/**
* Генерация текста с полным набором параметров
*/
async generate({
prompt,
model = 'qwen3:4b',
stream = false,
format = 'text',
temperature = 0.7,
top_p = 0.9,
top_k = 40,
num_predict = 256,
stop = ['\n', '###'],
repeat_penalty = 1.1,
presence_penalty = 0.0,
frequency_penalty = 0.0,
seed = null,
mirostat = 0,
mirostat_tau = 5.0,
mirostat_eta = 0.1,
num_ctx = 2048,
num_thread = 8,
template = null,
useContext = true
}) {
const payload = {
model,
prompt,
stream,
format,
options: {
temperature,
top_p,
top_k,
num_predict,
stop,
repeat_penalty,
presence_penalty,
frequency_penalty,
mirostat,
mirostat_tau,
mirostat_eta,
num_ctx,
num_thread
}
};
// Добавляем опциональные параметры
if (seed !== null) {
payload.options.seed = seed;
}
if (template) {
payload.template = template;
}
if (useContext && this.context) {
payload.context = this.context;
}
try {
const response = await axios.post(`${this.baseURL}/api/generate`, payload, {
timeout: 30000
});
// Сохраняем контекст для следующего запроса
if (useContext && response.data.context) {
this.context = response.data.context;
}
return response.data;
} catch (error) {
console.error('Ошибка запроса:', error.message);
return { error: error.message };
}
}
/**
* Чат-интерфейс с поддержкой истории
*/
async chat(messages, model = 'qwen3:4b', options = {}) {
try {
const response = await axios.post(`${this.baseURL}/api/chat`, {
model,
messages,
stream: false,
options
}, {
timeout: 30000
});
return response.data;
} catch (error) {
console.error('Ошибка чата:', error.message);
return { error: error.message };
}
}
/**
* Очистить контекст
*/
clearContext() {
this.context = null;
}
/**
* Сохранить контекст в файл
*/
async saveContext(filename) {
const fs = require('fs').promises;
try {
await fs.writeFile(filename, JSON.stringify(this.context, null, 2));
console.log(`Контекст сохранен в ${filename}`);
} catch (error) {
console.error('Ошибка сохранения контекста:', error.message);
}
}
/**
* Загрузить контекст из файла
*/
async loadContext(filename) {
const fs = require('fs').promises;
try {
const data = await fs.readFile(filename, 'utf8');
this.context = JSON.parse(data);
console.log(`Контекст загружен из ${filename}`);
} catch (error) {
console.error('Ошибка загрузки контекста:', error.message);
}
}
}
// Пример использования
async function main() {
const client = new OllamaClient();
// Пример 1: Простая генерация
console.log('=== Пример 1: Простая генерация ===');
const result1 = await client.generate({
prompt: 'Расскажи о JavaScript и его особенностях',
model: 'qwen3:4b',
temperature: 0.7,
top_p: 0.9,
num_predict: 200,
seed: 42,
format: 'text'
});
console.log('Ответ:', result1.response || result1.error);
// Пример 2: Продолжение с контекстом
console.log('\n=== Пример 2: Продолжение с контекстом ===');
const result2 = await client.generate({
prompt: 'А какие современные фреймворки используются?',
temperature: 0.5,
top_p: 0.8
});
console.log('Ответ:', result2.response || result2.error);
// Пример 3: Чат с историей
console.log('\n=== Пример 3: Чат-интерфейс ===');
const chatResult = await client.chat([
{ role: 'user', content: 'Привет! Расскажи о Node.js' },
{ role: 'assistant', content: 'Node.js - это JavaScript runtime...' },
{ role: 'user', content: 'Какие пакеты самые популярные?' }
], 'qwen3:4b', {
temperature: 0.6,
top_p: 0.85
});
console.log('Чат ответ:', chatResult.message?.content || chatResult.error);
// Пример 4: Сохранение и загрузка контекста
await client.saveContext('context.json');
client.clearContext();
await client.loadContext('context.json');
// Пример 5: Генерация кода с специфическими параметрами
console.log('\n=== Пример 5: Генерация кода ===');
const codeResult = await client.generate({
prompt: 'Напиши простой HTTP сервер на Node.js',
temperature: 0.3,
top_p: 0.7,
num_predict: 300,
seed: 12345,
format: 'code',
stop: ['```']
});
console.log('Сгенерированный код:');
console.log(codeResult.response || codeResult.error);
}
// Запуск примера
main().catch(console.error);
package.json для JavaScript:
{
"name": "ollama-client",
"version": "1.0.0",
"description": "Ollama client with full parameters support",
"main": "ollama-client.js",
"scripts": {
"start": "node ollama-client.js",
"dev": "node ollama-client.js"
},
"dependencies": {
"axios": "^1.6.0"
},
"keywords": ["ollama", "ai", "llm", "javascript"],
"author": "Your Name",
"license": "MIT"
}
1.1.8 - Запуск модели Ollama на языке Go
Go пример с полными параметрами
Установите зависимости:
go mod init ollama-client
go get github.com/valyala/fasthttp
main.go:
package main
import (
"encoding/json"
"fmt"
"log"
"strings"
"time"
"github.com/valyala/fasthttp"
)
type OllamaOptions struct {
Temperature float32 `json:"temperature"`
TopP float32 `json:"top_p"`
TopK int `json:"top_k"`
NumPredict int `json:"num_predict"`
Stop []string `json:"stop"`
RepeatPenalty float32 `json:"repeat_penalty"`
PresencePenalty float32 `json:"presence_penalty"`
FrequencyPenalty float32 `json:"frequency_penalty"`
Seed int64 `json:"seed,omitempty"`
Mirostat int `json:"mirostat"`
MirostatTau float32 `json:"mirostat_tau"`
MirostatEta float32 `json:"mirostat_eta"`
NumCtx int `json:"num_ctx"`
NumThread int `json:"num_thread"`
}
type OllamaRequest struct {
Model string `json:"model"`
Prompt string `json:"prompt"`
Stream bool `json:"stream"`
Format string `json:"format,omitempty"`
Options OllamaOptions `json:"options"`
Template string `json:"template,omitempty"`
Context []int `json:"context,omitempty"`
}
type OllamaResponse struct {
Model string `json:"model"`
Response string `json:"response"`
Context []int `json:"context,omitempty"`
Done bool `json:"done"`
Error string `json:"error,omitempty"`
}
type OllamaClient struct {
BaseURL string
Context []int
}
func NewOllamaClient(baseURL string) *OllamaClient {
if baseURL == "" {
baseURL = "http://localhost:11434"
}
return &OllamaClient{BaseURL: baseURL}
}
func (c *OllamaClient) Generate(prompt string, options OllamaOptions) (OllamaResponse, error) {
request := OllamaRequest{
Model: "qwen3:4b",
Prompt: prompt,
Stream: false,
Format: "text",
Options: options,
}
if len(c.Context) > 0 {
request.Context = c.Context
}
requestBody, err := json.Marshal(request)
if err != nil {
return OllamaResponse{}, err
}
req := fasthttp.AcquireRequest()
defer fasthttp.ReleaseRequest(req)
req.SetRequestURI(c.BaseURL + "/api/generate")
req.Header.SetMethod("POST")
req.Header.SetContentType("application/json")
req.SetBody(requestBody)
resp := fasthttp.AcquireResponse()
defer fasthttp.ReleaseResponse(resp)
client := &fasthttp.Client{
ReadTimeout: 30 * time.Second,
}
if err := client.Do(req, resp); err != nil {
return OllamaResponse{}, err
}
var response OllamaResponse
if err := json.Unmarshal(resp.Body(), &response); err != nil {
return OllamaResponse{}, err
}
// Сохраняем контекст для следующих запросов
if response.Context != nil {
c.Context = response.Context
}
return response, nil
}
func (c *OllamaClient) ClearContext() {
c.Context = nil
}
func main() {
client := NewOllamaClient("")
// Пример 1: Простая генерация
options1 := OllamaOptions{
Temperature: 0.7,
TopP: 0.9,
TopK: 40,
NumPredict: 200,
Stop: []string{"\n", "###"},
RepeatPenalty: 1.1,
Seed: 42,
Mirostat: 2,
MirostatTau: 5.0,
MirostatEta: 0.1,
}
fmt.Println("=== Пример 1: Простая генерация ===")
response1, err := client.Generate("Расскажи о Go языке программирования", options1)
if err != nil {
log.Fatal("Ошибка:", err)
}
fmt.Printf("Ответ: %s\n", response1.Response)
// Пример 2: Продолжение с контекстом
options2 := OllamaOptions{
Temperature: 0.5,
TopP: 0.8,
TopK: 30,
NumPredict: 150,
RepeatPenalty: 1.2,
}
fmt.Println("\n=== Пример 2: Продолжение с контекстом ===")
response2, err := client.Generate("Какие у него преимущества?", options2)
if err != nil {
log.Fatal("Ошибка:", err)
}
fmt.Printf("Ответ: %s\n", response2.Response)
// Пример 3: Генерация кода
options3 := OllamaOptions{
Temperature: 0.3,
TopP: 0.7,
NumPredict: 300,
Seed: 12345,
}
fmt.Println("\n=== Пример 3: Генерация кода ===")
response3, err := client.Generate("Напиши HTTP сервер на Go", options3)
if err != nil {
log.Fatal("Ошибка:", err)
}
fmt.Printf("Код: %s\n", response3.Response)
// Очищаем контекст
client.ClearContext()
fmt.Println("\nКонтекст очищен")
}
1.1.9 - Запуск модели Ollama на языке программирования Python
Python пример с полными параметрами
Установите зависимости:
pip install requests python-dotenv
ollama_client.py:
import requests
import json
import os
from typing import Dict, Any, List, Optional
class OllamaClient:
def __init__(self, base_url: str = "http://localhost:11434"):
self.base_url = base_url
self.context = None
def generate(
self,
prompt: str,
model: str = "qwen3:4b",
stream: bool = False,
format: str = "text",
temperature: float = 0.7,
top_p: float = 0.9,
top_k: int = 40,
num_predict: int = 256,
stop: List[str] = None,
repeat_penalty: float = 1.1,
presence_penalty: float = 0.0,
frequency_penalty: float = 0.0,
seed: int = None,
mirostat: int = 0,
mirostat_tau: float = 5.0,
mirostat_eta: float = 0.1,
num_ctx: int = 2048,
num_thread: int = 8,
template: str = None,
use_context: bool = True
) -> Dict[str, Any]:
"""
Генерация текста с полным набором параметров
"""
if stop is None:
stop = ["\n", "###"]
payload = {
"model": model,
"prompt": prompt,
"stream": stream,
"format": format,
"options": {
"temperature": temperature,
"top_p": top_p,
"top_k": top_k,
"num_predict": num_predict,
"stop": stop,
"repeat_penalty": repeat_penalty,
"presence_penalty": presence_penalty,
"frequency_penalty": frequency_penalty,
"mirostat": mirostat,
"mirostat_tau": mirostat_tau,
"mirostat_eta": mirostat_eta,
"num_ctx": num_ctx,
"num_thread": num_thread
}
}
# Добавляем опциональные параметры
if seed is not None:
payload["options"]["seed"] = seed
if template:
payload["template"] = template
if use_context and self.context:
payload["context"] = self.context
try:
response = requests.post(
f"{self.base_url}/api/generate",
json=payload,
timeout=30
)
response.raise_for_status()
result = response.json()
# Сохраняем контекст для следующего запроса
if use_context and "context" in result:
self.context = result["context"]
return result
except requests.exceptions.RequestException as e:
print(f"Ошибка запроса: {e}")
return {"error": str(e)}
def chat(
self,
messages: List[Dict[str, str]],
model: str = "qwen3:4b",
**kwargs
) -> Dict[str, Any]:
"""
Чат-интерфейс с поддержкой истории сообщений
"""
payload = {
"model": model,
"messages": messages,
"stream": False,
"options": kwargs.get("options", {})
}
try:
response = requests.post(
f"{self.base_url}/api/chat",
json=payload,
timeout=30
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Ошибка чата: {e}")
return {"error": str(e)}
def clear_context(self):
"""Очистить контекст"""
self.context = None
# Пример использования
def main():
client = OllamaClient()
# Пример 1: Простая генерация
print("=== Пример 1: Простая генерация ===")
result1 = client.generate(
prompt="Расскажи о преимуществах Python для data science",
model="qwen3:4b",
temperature=0.7,
top_p=0.9,
num_predict=150,
seed=42,
format="text"
)
print("Ответ:", result1.get("response", "Ошибка"))
# Пример 2: Продолжение с контекстом
print("\n=== Пример 2: Продолжение с контекстом ===")
result2 = client.generate(
prompt="А какие недостатки у Python?",
temperature=0.5,
top_p=0.8
)
print("Ответ:", result2.get("response", "Ошибка"))
# Пример 3: Чат с историей
print("\n=== Пример 3: Чат-интерфейс ===")
chat_result = client.chat(
messages=[
{"role": "user", "content": "Привет! Как тебя зовут?"},
{"role": "assistant", "content": "Привет! Я помощник на основе AI."},
{"role": "user", "content": "Расскажи о машинном обучении"}
],
model="qwen3:4b",
options={
"temperature": 0.7,
"top_p": 0.9
}
)
print("Чат ответ:", chat_result.get("message", {}).get("content", "Ошибка"))
# Пример 4: Сброс контекста
client.clear_context()
print("\nКонтекст очищен")
if __name__ == "__main__":
main()
advanced_example.py - продвинутый пример:
import json
from ollama_client import OllamaClient
def advanced_example():
client = OllamaClient()
# Многошаговый диалог с сохранением контекста
steps = [
"Расскажи о языке программирования Go",
"Какие у него преимущества перед Python?",
"А недостатки какие?",
"Напиши простой HTTP сервер на Go"
]
for i, prompt in enumerate(steps, 1):
print(f"\n--- Шаг {i}: {prompt} ---")
result = client.generate(
prompt=prompt,
model="qwen3:4b",
temperature=0.7 if i > 1 else 0.5,
top_p=0.9,
num_predict=200 if i < 4 else 300,
seed=12345,
format="text" if i < 4 else "code"
)
if "response" in result:
print(f"Ответ: {result['response']}")
else:
print(f"Ошибка: {result.get('error', 'Неизвестная ошибка')}")
# Сохраняем контекст в файл
if client.context:
with open("context.json", "w") as f:
json.dump(client.context, f)
print("\nКонтекст сохранен в context.json")
if __name__ == "__main__":
advanced_example()
2 - Язык программирования LUA
Все версии доступны для загрузки. Эта документация пишется для текущей версии — Lua 5.4, а текущий релиз — Lua 5.4.8.
Lua
Lua — это бесплатное программное обеспечение, распространяемое в исходном коде. Его можно использовать для любых целей, включая коммерческие, совершенно бесплатно.
Все версии доступны для загрузки. Текущая версия — Lua 5.4, а текущий релиз — Lua 5.4.8.
Инструменты
Основной репозиторий модулей Lua — это LuaRocks. Также смотрите Awesome Lua. Предварительно скомпилированные библиотеки и исполняемые файлы Lua доступны на LuaBinaries. Вики lua-users содержит множество пользовательских дополнений для Lua.
Сборка
Lua реализован на чистом ANSI C и компилируется без изменений на всех платформах, где есть компилятор ANSI C. Lua также компилируется без проблем как C++.
Lua очень легко собрать и установить. В пакете есть подробные инструкции, но вот простой пример терминальной сессии, которая загружает текущий релиз Lua и собирает его на распространенных платформах:
curl -L -R -O https://www.lua.org/ftp/lua-5.4.8.tar.gz
tar zxf lua-5.4.8.tar.gz
cd lua-5.4.8
make all test
Введение
Lua — это мощный, эффективный, легковесный и встраиваемый язык сценариев. Он поддерживает процедурное программирование, объектно-ориентированное программирование, функциональное программирование, программирование на основе данных и описание данных.
Lua сочетает в себе простую процедурную синтаксис с мощными конструкциями описания данных, основанными на ассоциативных массивах и расширяемой семантике. Lua является динамически типизированным языком, работает путем интерпретации байт-кода с помощью виртуальной машины на основе регистров и имеет автоматическое управление памятью с помощью генерационного сборщика мусора, что делает его идеальным для конфигурации, сценариев и быстрого прототипирования.
Lua реализован как библиотека, написанная на чистом C, общепринятом подмножестве стандартного C и C++. Распределение Lua включает в себя хост-программу под названием lua, которая использует библиотеку Lua для предоставления полного, автономного интерпретатора Lua, как для интерактивного, так и для пакетного использования. Lua предназначен как мощный, легковесный, встраиваемый язык сценариев для любой программы, которая в этом нуждается, а также как мощный, но легковесный и эффективный автономный язык.
Как язык расширения, Lua не имеет понятия “главной” программы: он работает встраиваемым в хост-клиент, называемым программой встраивания или просто хостом. (Часто этот хост — это автономная программа lua.) Хост-программа может вызывать функции для выполнения фрагмента кода Lua, может записывать и считывать переменные Lua, а также может регистрировать функции C, которые будут вызываться кодом Lua. С помощью функций C Lua может быть расширен для работы с широким спектром различных областей, создавая таким образом настраиваемые языки программирования, которые разделяют синтаксическую основу.
Lua является бесплатным программным обеспечением и предоставляется, как обычно, без каких-либо гарантий, как указано в его лицензии. Реализация, описанная в этом руководстве, доступна на официальном сайте Lua, www.lua.org.
Как и любой другой справочный мануал, этот документ в некоторых местах может быть сухим. Для обсуждения решений, стоящих за дизайном Lua, смотрите технические статьи, доступные на сайте Lua. Для подробного введения в программирование на Lua смотрите книгу Роберто, “Программирование на Lua”.
2.1 - 2. Базовые концепции языка LUA
2.1 – Значения и типы
Lua — это динамически типизированный язык. Это означает, что переменные не имеют типов; только значения имеют типы. В языке отсутствуют определения типов. Все значения имеют свой собственный тип.
Все значения в Lua являются значениями первого класса. Это означает, что все значения могут храниться в переменных, передаваться в качестве аргументов другим функциям и возвращаться в качестве результатов.
В Lua есть восемь основных типов: nil, boolean, number, string, function, userdata, thread и table.
- Тип
nilимеет одно единственное значение —nil, основное свойство которого заключается в том, что оно отличается от любого другого значения; оно часто представляет отсутствие полезного значения. - Тип
booleanимеет два значения:falseиtrue. Оба nil и false делают условие ложным; их вместе называют ложными значениями. Любое другое значение делает условие истинным. Несмотря на свое название, false часто используется как альтернатива nil, с ключевым отличием в том, что false ведет себя как обычное значение в таблице, в то время как nil в таблице представляет отсутствующий ключ. - Тип
numberпредставляет как целые числа, так и вещественные (числа с плавающей запятой), используя два подтипа:integerиfloat. Стандартный Lua использует 64-битные целые числа и числа с двойной точностью (64 бита), но вы также можете скомпилировать Lua так, чтобы он использовал 32-битные целые числа и/или числа с одинарной точностью (32 бита). Опция с 32 битами как для целых чисел, так и для чисел с плавающей запятой особенно привлекательна для малых машин и встроенных систем. (Смотрите макрос LUA_32BITS в файле luaconf.h.)
Если не указано иное, любое переполнение при манипуляциях с целыми значениями оборачивается, согласно обычным правилам арифметики с дополнительным кодом. (Другими словами, фактический результат — это уникальное представимое целое число, которое равно математическому результату по модулю 2n, где n — это количество битов целого типа.)
Lua имеет явные правила о том, когда используется каждый подтип, но также автоматически выполняет преобразования между ними по мере необходимости (см. §3.4.3). Поэтому программист может в основном игнорировать разницу между целыми числами и числами с плавающей запятой или полностью контролировать представление каждого числа.
- Тип
stringпредставляет собой неизменяемые последовательности байтов. Lua является 8-битным чистым языком: строки могут содержать любое 8-битное значение, включая встроенные нули (’\0’). Lua также не зависит от кодировки; он не делает предположений о содержимом строки. Длина любой строки в Lua должна помещаться в целое число Lua.
Lua может вызывать (и манипулировать) функциями, написанными как на Lua, так и на C (см. §3.4.10). Обе они представлены типом function.
Тип userdata предоставляется для хранения произвольных данных C в переменных Lua. Значение
userdataпредставляет собой блок необработанной памяти. Существует два видаuserdata: полноеuserdata, которое является объектом с блоком памяти, управляемым Lua, и легкоеuserdata, которое просто представляет собой значение указателя C. Уuserdataнет предопределенных операций в Lua, кроме присваивания и теста идентичности. С помощью метатаблиц программист может определить операции для значений полногоuserdata(см. §2.4). Значенияuserdataне могут быть созданы или изменены в Lua, только через C API. Это гарантирует целостность данных, принадлежащих хост-программе и библиотекам C.Тип
threadпредставляет собой независимые потоки выполнения и используется для реализации корутин (см. §2.6). Потоки Lua не связаны с потоками операционной системы. Lua поддерживает корутины на всех системах, даже на тех, которые не поддерживают потоки нативно.Тип
tableреализует ассоциативные массивы, то есть массивы, которые могут иметь в качестве индексов не только числа, но и любое значение Lua, кроме nil и NaN. (Not a Number — это специальное значение с плавающей запятой, используемое стандартом IEEE 754 для представления неопределенных числовых результатов, таких как 0/0.) Таблицы могут быть гетерогенными; то есть они могут содержать значения всех типов (кроме nil). Любой ключ, связанный со значением nil, не считается частью таблицы. Напротив, любой ключ, который не является частью таблицы, имеет связанное значение nil.
Таблицы являются единственным механизмом структурирования данных в Lua; их можно использовать для представления обычных массивов, списков, символических таблиц, множеств, записей, графов, деревьев и т. д. Для представления записей Lua использует имя поля в качестве индекса. Язык поддерживает это представление, предоставляя a.name как синтаксический сахар для a[“name”]. В Lua есть несколько удобных способов создания таблиц (см. §3.4.9).
Как и индексы, значения полей таблицы могут быть любого типа. В частности, поскольку функции являются значениями первого класса, поля таблицы могут содержать функции. Таким образом, таблицы также могут содержать методы (см. §3.4.11).
Индексирование таблиц следует определению сырого равенства (raw equality) в языке. Выражения a[i] и a[j] обозначают один и тот же элемент таблицы тогда и только тогда, когда i и j сыро равны (то есть равны без учёта метаметодов).
В частности:
- Числа с плавающей точкой, имеющие целочисленные значения, считаются равными соответствующим целым числам (например,
1.0 == 1). - Чтобы избежать неоднозначностей, любое число с плавающей точкой, используемое в качестве ключа и равное целому числу, преобразуется в это целое число.
Пример:
Если написать a[2.0] = true, то фактически в таблицу будет вставлен ключ 2 (целое число), а не 2.0.
Ключевые моменты:
- Сырое равенство (
raw equality) — сравнение без метаметодов. - Целые и дробные числа —
1.0и1считаются одинаковыми ключами. - Автоматическое преобразование —
a[2.0]превращается вa[2].
Это важно учитывать при работе с таблицами, чтобы избежать неожиданного поведения.
Таблицы, функции, потоки и значения (полного) userdata являются объектами: переменные на самом деле не содержат эти значения, а только ссылки на них. Присваивание, передача параметров и возвращение функций всегда манипулируют ссылками на такие значения; эти операции не подразумевают никакого рода копирования.
Функция библиотеки type возвращает строку, описывающую тип данного значения (см. type).
2.2 – Окружения и глобальное окружение
Имена переменных, области их видимости, правила лексического скрытия (shadowing) и работа с окружениями _ENV в языке Lua.
Имя переменной ссылается на глобальную или локальную переменную в соответствии с объявлением, которое находится в контексте в данной точке кода. (Для целей данного обсуждения формальный параметр функции эквивалентен локальной переменной.)
Все чанки (блоки кода) начинаются с неявного объявления global *, которое объявляет все свободные имена как глобальные переменные; это вводное объявление становится недействительным (void) внутри области видимости любого другого объявления global, как показано в следующем примере:
X = 1 -- Ok, глобальная по умолчанию
do
global Y -- отменяет неявное начальное объявление
Y = 1 -- Ok, Y объявлена как глобальная
X = 1 -- ОШИБКА, X не объявлена
end
X = 2 -- Ok, снова глобальная по умолчанию
Таким образом, вне любого объявления global Lua работает по принципу “глобальные по умолчанию”. Внутри любого объявления global Lua работает без умолчания: все переменные должны быть объявлены.
Lua — это язык с лексической областью видимости. Область видимости объявления переменной начинается с первого оператора после объявления и длится до последнего не-пустого (non-void) оператора самого внутреннего блока, включающего это объявление. (Пустыми операторами считаются метки и пустые инструкции.)
Объявление скрывает (shadowing) любое другое объявление с тем же именем, находящееся в контексте в точке объявления. Внутри этой тени любое внешнее объявление для этого имени становится недействительным. Смотрите следующий пример:
global print, x
x = 10 -- глобальная переменная
do -- новый блок
local x = x -- новая 'x' со значением 10
print(x) --> 10
x = x+1
do -- еще один блок
local x = x+1 -- еще одна 'x'
print(x) --> 12
end
print(x) --> 11
end
print(x) --> 10 (глобальная)
Обратите внимание, что в объявлении вроде local x = x новая объявляемая x еще не находится в области видимости, поэтому x в правой части ссылается на внешнюю переменную.
Благодаря правилам лексической области видимости, локальные переменные могут свободно использоваться функциями, определенными внутри их области видимости. Локальная переменная, используемая внутренней функцией, называется upvalue (или внешней локальной переменной, или просто внешней переменной) внутри этой внутренней функции.
Обратите внимание, что каждое выполнение оператора local определяет новые локальные переменные. Рассмотрим следующий пример:
a = {}
local x = 20
for i = 1, 10 do
local y = 0
a[i] = function () y = y + 1; return x + y end
end
Цикл создает десять замыканий (то есть десять экземпляров анонимной функции). Каждое из этих замыканий использует свою отдельную переменную y, в то время как все они совместно используют одну и ту же x.
Как будет более подробно обсуждаться в §3.2 и §3.3.3, любая ссылка на глобальную переменную var синтаксически транслируется в _ENV.var. Более того, каждый чанк компилируется в области видимости внешней локальной переменной с именем _ENV (см. §3.3.2), поэтому само имя _ENV никогда не является свободным именем в чанке.
Несмотря на существование этой внешней переменной _ENV и трансляцию свободных имен, _ENV является обычным именем. В частности, вы можете определять новые переменные и параметры с этим именем. (Однако не следует определять _ENV как глобальную переменную, иначе _ENV.var транслировалось бы в _ENV._ENV.var и так далее, в бесконечном цикле.) Каждая ссылка на имя глобальной переменной использует ту _ENV, которая видна в данной точке программы.
Любая таблица, используемая в качестве значения _ENV, называется окружением (environment).
Lua поддерживает выделенное окружение, называемое глобальным окружением (global environment). Это значение хранится по специальному индексу в реестре C (см. §4.3). В Lua глобальная переменная _G инициализируется этим же значением. (_G никогда не используется внутри самого Lua, поэтому изменение ее значения повлияет только на ваш собственный код.)
Когда Lua загружает чанк, значением по умолчанию для его переменной _ENV является глобальное окружение (см. функцию load). Следовательно, по умолчанию глобальные переменные в коде Lua ссылаются на записи в глобальном окружении и, таким образом, ведут себя как обычные глобальные переменные. Более того, все стандартные библиотеки загружены в глобальное окружение, и некоторые функции там работают именно с этим окружением. Вы можете использовать load (или loadfile) для загрузки чанка с другим окружением. (В языке C для этого необходимо загрузить чанк, а затем изменить значение его первого upvalue; см. lua_setupvalue.)
2.3 – Обработка ошибок
Несколько операций в Lua могут вызывать ошибку. Ошибка прерывает нормальный поток выполнения программы, который может продолжиться, поймав ошибку.
Lua-код может явно вызвать ошибку, вызвав функцию error. (Эта функция никогда не возвращает значение.)
Чтобы поймать ошибки в Lua, вы можете выполнить защищенный вызов, используя pcall (или xpcall). Функция pcall вызывает заданную функцию в защищенном режиме. Любая ошибка во время выполнения функции останавливает ее выполнение, и управление немедленно возвращается в pcall, который возвращает код состояния.
Поскольку Lua является встроенным языком расширения, код Lua начинает выполняться по вызову из C-кода в хост-программе. (Когда вы используете Lua в автономном режиме, приложение lua является хост-программой.) Обычно этот вызов защищен; поэтому, когда происходит незащищенная ошибка во время компиляции или выполнения блока Lua, управление возвращается в хост, который может предпринять соответствующие меры, такие как вывод сообщения об ошибке.
Каждый раз, когда возникает ошибка, объект ошибки передается с информацией об ошибке. Сам Lua генерирует только ошибки, объект ошибки которых является строкой, но программы могут генерировать ошибки с любым значением в качестве объекта ошибки. Обработка таких объектов ошибок зависит от программы Lua или ее хоста. По историческим причинам объект ошибки часто называется сообщением об ошибке, даже если он не обязательно должен быть строкой.
Когда вы используете xpcall (или lua_pcall в C), вы можете передать обработчик сообщений, который будет вызван в случае ошибок. Эта функция вызывается с оригинальным объектом ошибки и возвращает новый объект ошибки. Она вызывается до того, как ошибка развернет стек, чтобы собрать больше информации об ошибке, например, проверяя стек и создавая трассировку стека. Этот обработчик сообщений также защищен защищенным вызовом; поэтому ошибка внутри обработчика сообщений снова вызовет обработчик сообщений. Если этот цикл продолжается слишком долго, Lua прерывает его и возвращает соответствующее сообщение. Обработчик сообщений вызывается только для обычных ошибок времени выполнения. Он не вызывается для ошибок выделения памяти и для ошибок при выполнении финализаторов или других обработчиков сообщений.
Lua также предлагает систему предупреждений (см. warn). В отличие от ошибок, предупреждения никоим образом не мешают выполнению программы. Обычно они просто генерируют сообщение для пользователя, хотя это поведение можно адаптировать из C (см. lua_setwarnf).
2.4 – Метатаблицы и метаметоды
Каждое значение в Lua может иметь метатаблицу. Эта метатаблица — это обычная таблица Lua, которая определяет поведение оригинального значения при определенных событиях. Вы можете изменить несколько аспектов поведения значения, установив конкретные поля в его метатаблице. Например, когда нечисловое значение является операндом сложения, Lua проверяет наличие функции в поле __add метатаблицы значения. Если она находит такую функцию, Lua вызывает ее для выполнения сложения.
Ключом для каждого события в метатаблице является строка с именем события, предшествующая двумя подчеркиваниями; соответствующее значение называется метазначением. Для большинства событий метазначение должно быть функцией, которая затем называется метаметодом. В предыдущем примере ключом является строка “__add”, а метаметодом — функция, выполняющая сложение. Если не указано иное, метаметодом может быть любое вызываемое значение, которое является либо функцией, либо значением с метаметодом __call.
Вы можете запросить метатаблицу любого значения, используя функцию getmetatable. Lua запрашивает метаметоды в метатаблицах, используя сырой доступ (см. rawget).
Вы можете заменить метатаблицу таблиц, используя функцию setmetatable. Вы не можете изменить метатаблицу других типов из кода Lua, кроме как с помощью библиотеки debug (§6.10).
Таблицы и полное userdata имеют индивидуальные метатаблицы, хотя несколько таблиц и userdata могут делить свои метатаблицы. Значения всех других типов делят одну единственную метатаблицу на тип; то есть, существует одна единственная метатаблица для всех чисел, одна для всех строк и т. д. По умолчанию значение не имеет метатаблицы, но библиотека строк устанавливает метатаблицу для типа строк (см. §6.4).
Подробный список операций, контролируемых метатаблицами, приведен ниже. Каждое событие идентифицируется своим соответствующим ключом. По соглашению, все ключи метатаблиц, используемые Lua, состоят из двух подчеркиваний, за которыми следуют строчные латинские буквы.
__add: операция сложения (+). Если любой операнд для сложения не является числом, Lua попытается вызвать метаметод. Он начинает с проверки первого операнда (даже если это число); если этот операнд не определяет метаметод для__add, то Lua проверит второй операнд. Если Lua находит метаметод, он вызывает этот метаметод с двумя операндами в качестве аргументов, и результат вызова (приведенный к одному значению) является результатом операции. В противном случае, если метаметод не найден, Lua вызывает ошибку.__sub: операция вычитания (-). Поведение аналогично операции сложения.__mul: операция умножения (*). Поведение аналогично операции сложения.__div: операция деления (/). Поведение аналогично операции сложения.__mod: операция взятия остатка (%) . Поведение аналогично операции сложения.__pow: операция возведения в степень (^). Поведение аналогично операции сложения.__unm: операция отрицания (унарный -). Поведение аналогично операции сложения.__idiv: операция целочисленного деления (//). Поведение аналогично операции сложения.__band: побитовая операция И (&). Поведение аналогично операции сложения, за исключением того, что Lua попытается вызвать метаметод, если любой операнд не является ни целым числом, ни числом с плавающей запятой, приводимым к целому (см. §3.4.3).__bor: побитовая операция ИЛИ (|). Поведение аналогично побитовой операции И.__bxor: побитовая операция исключающего ИЛИ (двойной ~). Поведение аналогично побитовой операции И.__bnot: побитовая операция НЕ (унарный ~). Поведение аналогично побитовой операции И.__shl: побитовый сдвиг влево («). Поведение аналогично побитовой операции И.__shr: побитовый сдвиг вправо (»). Поведение аналогично побитовой операции И.__concat: операция конкатенации (..). Поведение аналогично операции сложения, за исключением того, что Lua попытается вызвать метаметод, если любой операнд не является ни строкой, ни числом (которое всегда приводимо к строке).__len: операция длины (#). Если объект не является строкой, Lua попытается вызвать его метаметод. Если метаметод существует, Lua вызывает его с объектом в качестве аргумента, и результат вызова (всегда приведенный к одному значению) является результатом операции. Если метаметода нет, но объект является таблицей, то Lua использует операцию длины таблицы (см. §3.4.7). В противном случае Lua вызывает ошибку.__eq: операция равенства (==). Поведение аналогично операции сложения, за исключением того, что Lua попытается вызвать метаметод только тогда, когда сравниваемые значения являются либо обеими таблицами, либо обоими полными userdata и они не равны по примитивному сравнению. Результат вызова всегда преобразуется в логическое значение.__lt: операция “меньше чем” (<). Поведение аналогично операции сложения, за исключением того, что Lua попытается вызвать метаметод только тогда, когда сравниваемые значения не являются ни обоими числами, ни обеими строками. Более того, результат вызова всегда преобразуется в логическое значение.__le: операция “меньше или равно” (<=). Поведение аналогично операции “меньше чем”.__index: операция доступа по индексу table[key]. Это событие происходит, когда table не является таблицей или когда ключ отсутствует в таблице. Метазначение ищется в метатаблице таблицы. Метазначение для этого события может быть либо функцией, либо таблицей, либо любым значением с метазначением__index. Если это функция, она вызывается с таблицей и ключом в качестве аргументов, и результат вызова (приведенный к одному значению) является результатом операции. В противном случае окончательный результат — это результат индексации этого метазначения с ключом. Эта индексация является обычной, а не сырой, и, следовательно, может вызвать другой метаметод__index.__newindex: операция присваивания по индексу table[key] = value. Как и событие индексации, это событие происходит, когда table не является таблицей или когда ключ отсутствует в таблице. Метазначение ищется в метатаблице таблицы. Как и в случае с индексацией, метазначение для этого события может быть либо функцией, либо таблицей, либо любым значением с метазначением__newindex. Если это функция, она вызывается с таблицей, ключом и значением в качестве аргументов. В противном случае Lua повторяет присваивание индексации для этого метазначения с тем же ключом и значением. Это присваивание является обычным, а не сырым, и, следовательно, может вызвать другой метаметод__newindex.
Каждый раз, когда вызывается метазначение __newindex, Lua не выполняет примитивное присваивание. Если это необходимо, сам метаметод может вызвать rawset для выполнения присваивания.
__call: операция вызоваfunc(args). Это событие происходит, когда Lua пытается вызвать значение, не являющееся функцией (то есть func не является функцией). Метаметод ищется в func. Если он присутствует, метаметод вызывается с func в качестве первого аргумента, за которым следуют аргументы оригинального вызова (args). Все результаты вызова являются результатами операции. Это единственный метаметод, который позволяет возвращать несколько результатов.
2.5 – Сборка мусора
Lua осуществляет автоматическое управление памятью. Это означает, что вам не нужно беспокоиться о выделении памяти для новых объектов или ее освобождении, когда объекты больше не нужны. Lua управляет памятью автоматически, запуская сборщик мусора для сбора всех мертвых объектов. Вся память, используемая Lua, подлежит автоматическому управлению: строки, таблицы, пользовательские данные (userdata), функции, потоки, внутренние структуры и т.д.
Объект считается мертвым, как только сборщик может быть уверен, что к объекту больше не будет обращений при нормальном выполнении программы. («Нормальное выполнение» здесь исключает финализаторы, которые воскрешают мертвые объекты (см. §2.5.3), а также исключает некоторые операции с использованием библиотеки отладки.) Обратите внимание, что момент, когда сборщик может быть уверен в том, что объект мертв, может не совпадать с ожиданиями программиста. Единственными гарантиями являются то, что Lua не будет собирать объект, к которому все еще можно обратиться при нормальном выполнении программы, и что в конечном итоге он соберет объект, который недоступен из Lua. (Здесь «недоступен из Lua» означает, что ни переменная, ни другой живой объект не ссылаются на данный объект.) Поскольку Lua ничего не знает о коде C, он никогда не собирает объекты, доступные через реестр (см. §4.3), который включает глобальное окружение (см. §2.2) и главный поток.
Сборщик мусора (GC) в Lua может работать в двух режимах: инкрементальном и поколенческом (generational).
Режим GC по умолчанию с параметрами по умолчанию подходит для большинства случаев использования. Однако программы, которые тратят большую часть своего времени на выделение и освобождение памяти, могут выиграть от других настроек. Имейте в виду, что поведение GC непереносимо как между платформами, так и между разными версиями Lua; следовательно, оптимальные настройки также непереносимы.
Вы можете изменить режим и параметры GC, вызвав lua_gc в C или collectgarbage в Lua. Вы также можете использовать эти функции для прямого управления сборщиком, например, для его остановки или перезапуска.
2.5.1 – Инкрементальная сборка мусора
В инкрементальном режиме каждый цикл GC выполняет сборку с пометкой и очисткой (mark-and-sweep) небольшими шагами, чередующимися с выполнением программы. В этом режиме сборщик использует три числа для управления своими циклами сборки мусора: паузу сборщика мусора, множитель шага сборщика мусора и размер шага сборщика мусора.
Пауза сборщика мусора управляет тем, как долго сборщик ждет перед началом нового цикла. Сборщик начинает новый цикл, когда количество байтов достигает n% от общего количества после предыдущей сборки. Большие значения делают сборщик менее агрессивным. Значения, равные или меньшие 100, означают, что сборщик не будет ждать начала нового цикла. Значение 200 означает, что сборщик ждет, пока общее количество байтов удвоится, прежде чем начать новый цикл.
Размер шага сборщика мусора управляет размером каждого инкрементального шага, а именно тем, сколько байтов выделяет интерпретатор перед выполнением шага: Значение n означает, что интерпретатор выделит примерно n байтов между шагами.
Множитель шага сборщика мусора управляет тем, сколько работы выполняет каждый инкрементальный шаг. Значение n означает, что интерпретатор выполнит n% единиц работы на каждое выделенное слово. Единица работы примерно соответствует обходу одного слота или очистке одного объекта. Большие значения делают сборщик более агрессивным. Остерегайтесь слишком малых значений, так как они могут сделать сборщик слишком медленным, чтобы вообще когда-либо завершить цикл. В качестве особого случая, нулевое значение означает неограниченную работу, фактически создавая неинкрементальный сборщик, останавливающий весь мир (stop-the-world).
2.5.2 – Поколенческая сборка мусора
В поколенческом режиме сборщик выполняет частые малые сборки, которые обходят только недавно созданные объекты. Если после малой сборки количество байтов превышает лимит, сборщик переключается на большую сборку, которая обходит все объекты. Затем сборщик продолжает выполнять большие сборки до тех пор, пока не обнаружит, что программа генерирует достаточно мусора, чтобы оправдать возврат к малым сборкам.
Поколенческий режим использует три параметра: множитель малой сборки (minor multiplier), множитель перехода от малой к большой сборке (minor-major multiplier) и множитель перехода от большой к малой сборке (major-minor multiplier).
Множитель малой сборки управляет частотой малых сборок. Для множителя x новая малая сборка будет выполнена, когда количество байтов станет на x% больше, чем количество используемых байтов сразу после последней большой сборки. Например, при множителе 20 сборщик выполнит малую сборку, когда количество байтов станет на 20% больше, чем общее количество после последней большой сборки.
Множитель перехода от малой к большой сборке управляет переходом к большим сборкам. Для множителя x сборщик переключится на большую сборку, когда количество байтов от старых объектов станет на x% больше, чем общее количество после предыдущей большой сборки. Например, при множителе 100 сборщик выполнит большую сборку, когда количество старых байтов превысит удвоенное общее количество после предыдущей большой сборки. В качестве особого случая, значение 0 останавливает выполнение сборщиком больших сборок.
Множитель перехода от большой к малой сборке управляет возвратом к малым сборкам. Для множителя x сборщик вернется к малым сборкам после того, как большая сборка соберет не менее x% байтов, выделенных во время последнего цикла. В частности, при множителе 0 сборщик немедленно вернется к малым сборкам после выполнения одной большой сборки.
2.5.3 – Метаметоды сборки мусора
Вы можете установить метаметоды сборщика мусора для таблиц и, используя C API, для полных пользовательских данных (userdata) (см. §2.4). Эти метаметоды, называемые финализаторами, вызываются, когда сборщик мусора обнаруживает, что соответствующая таблица или userdata мертвы. Финализаторы позволяют вам координировать сборку мусора Lua с управлением внешними ресурсами, такими как закрытие файлов, сетевых соединений или соединений с базами данных, или освобождение вашей собственной памяти.
Чтобы объект (таблица или userdata) был финализирован при сборе, вы должны пометить его для финализации. Вы помечаете объект для финализации, когда устанавливаете его метатаблицу, и эта метатаблица имеет метаметод __gc. Обратите внимание, что если вы установите метатаблицу без поля __gc и позже создадите это поле в метатаблице, объект не будет помечен для финализации.
Когда помеченный объект становится мертвым, он не собирается сборщиком мусора немедленно. Вместо этого Lua помещает его в список. После сборки Lua проходит по этому списку. Для каждого объекта в списке он проверяет метаметод __gc объекта: Если он присутствует, Lua вызывает его, передавая объект в качестве единственного аргумента.
В конце каждого цикла сборки мусора финализаторы вызываются в порядке, обратном тому, в котором объекты были помечены для финализации, среди тех, что были собраны в этом цикле; то есть первым вызывается финализатор, связанный с объектом, помеченным последним в программе. Выполнение каждого финализатора может произойти в любой момент во время выполнения обычного кода.
Поскольку собираемый объект все еще должен использоваться финализатором, этот объект (и другие объекты, доступные только через него) должны быть воскрешены Lua. Обычно это воскрешение является временным, и память объекта освобождается в следующем цикле сборки мусора. Однако, если финализатор сохраняет объект в каком-либо глобальном месте (например, в глобальной переменной), то воскрешение становится постоянным. Более того, если финализатор снова помечает финализируемый объект для финализации, его финализатор будет вызван снова в следующем цикле, когда объект будет мертв. В любом случае память объекта освобождается только в том цикле GC, когда объект мертв и не помечен для финализации.
Когда вы закрываете состояние (см. lua_close), Lua вызывает финализаторы всех объектов, помеченных для финализации, следуя обратному порядку их пометки. Если какой-либо финализатор помечает объекты для сбора на этом этапе, эти пометки не имеют эффекта.
Финализаторы не могут прерываться (yield) и не могут запускать сборщик мусора. Поскольку они могут выполняться в непредсказуемые моменты времени, хорошей практикой является ограничение каждого финализатора минимумом, необходимым для надлежащего освобождения связанного с ним ресурса.
Любая ошибка во время выполнения финализатора генерирует предупреждение; ошибка не распространяется дальше.
2.5.4 – Слабые таблицы
Слабая таблица — это таблица, элементы которой являются слабыми ссылками. Слабая ссылка игнорируется сборщиком мусора. Другими словами, если единственными ссылками на объект являются слабые ссылки, то сборщик мусора соберет этот объект.
Слабая таблица может иметь слабые ключи, слабые значения или и то, и другое. Таблица со слабыми значениями позволяет собирать свои значения, но предотвращает сбор своих ключей. Таблица со слабыми и ключами, и значениями позволяет собирать как ключи, так и значения. В любом случае, если либо ключ, либо значение собраны, вся пара удаляется из таблицы. Слабость таблицы контролируется полем __mode ее метатаблицы. Это метазначение, если присутствует, должно быть одной из следующих строк: "k" для таблицы со слабыми ключами; "v" для таблицы со слабыми значениями; или "kv" для таблицы со слабыми и ключами, и значениями.
Таблица со слабыми ключами и сильными значениями также называется эфемеронной таблицей (ephemeron table). В эфемеронной таблице значение считается достижимым, только если достижим его ключ. В частности, если единственная ссылка на ключ исходит из его значения, пара удаляется.
Любое изменение слабости таблицы может вступить в силу только на следующем цикле сбора. В частности, если вы меняете слабость на более сильный режим, Lua все еще может собрать некоторые элементы из этой таблицы до того, как изменение вступит в силу.
Только объекты, имеющие явное построение, удаляются из слабых таблиц. Значения, такие как числа и легкие C-функции, не подлежат сборке мусора и, следовательно, не удаляются из слабых таблиц (если только не собраны связанные с ними значения). Хотя строки подлежат сборке мусора, они не имеют явного построения, и их равенство определяется по значению; они ведут себя скорее как значения, чем как объекты. Поэтому они не удаляются из слабых таблиц.
Воскрешенные объекты (то есть объекты, находящиеся в процессе финализации, и объекты, доступные только через финализируемые объекты) имеют особое поведение в слабых таблицах. Они удаляются из слабых значений перед запуском их финализаторов, но удаляются из слабых ключей только при следующей сборке после запуска финализаторов, когда такие объекты фактически освобождаются. Это поведение позволяет финализатору получать доступ к свойствам, связанным с объектом, через слабые таблицы.
Если слабая таблица находится среди воскрешенных объектов в цикле сборки, она может быть не очищена должным образом до следующего цикла.
2.6 – Сопрограммы
Lua поддерживает сопрограммы (coroutines), также называемые совместной многопоточностью. Сопрограмма в Lua представляет собой независимый поток выполнения. Однако, в отличие от потоков в многопоточных системах, сопрограмма приостанавливает свое выполнение только путем явного вызова функции прерывания (yield).
Вы создаете сопрограмму, вызывая coroutine.create. Ее единственным аргументом является функция, которая является главной функцией сопрограммы. Функция create только создает новую сопрограмму и возвращает дескриптор на нее (объект типа thread); она не запускает сопрограмму.
Вы выполняете сопрограмму, вызывая coroutine.resume. Когда вы впервые вызываете coroutine.resume, передавая в качестве первого аргумента поток, возвращенный coroutine.create, сопрограмма начинает свое выполнение с вызова своей главной функции. Дополнительные аргументы, переданные в coroutine.resume, передаются в качестве аргументов этой функции. После того как сопрограмма начинает работать, она выполняется до тех пор, пока не завершится или не прервется (yield).
Сопрограмма может завершить свое выполнение двумя способами: нормально, когда ее главная функция возвращает управление (явно или неявно, после последней инструкции); и аварийно, если происходит незащищенная ошибка. В случае нормального завершения coroutine.resume возвращает true плюс любые значения, возвращенные главной функцией сопрограммы. В случае ошибок coroutine.resume возвращает false плюс объект ошибки. В этом случае сопрограмма не разворачивает свой стек, так что после ошибки его можно проверить с помощью API отладки.
Сопрограмма прерывается (yield) вызовом coroutine.yield. Когда сопрограмма прерывается, соответствующий coroutine.resume возвращается немедленно, даже если прерывание происходит внутри вложенных вызовов функций (то есть не в главной функции, а в функции, прямо или косвенно вызванной главной функцией). В случае прерывания coroutine.resume также возвращает true плюс любые значения, переданные в coroutine.yield. В следующий раз, когда вы возобновите ту же сопрограмму, она продолжит свое выполнение с точки прерывания, при этом вызов coroutine.yield вернет любые дополнительные аргументы, переданные в coroutine.resume.
Как и coroutine.create, функция coroutine.wrap также создает сопрограмму, но вместо возврата самой сопрограммы она возвращает функцию, которая при вызове возобновляет сопрограмму. Любые аргументы, переданные этой функции, идут как дополнительные аргументы в coroutine.resume. coroutine.wrap возвращает все значения, возвращенные coroutine.resume, кроме первого (булева кода ошибки). В отличие от coroutine.resume, функция, созданная coroutine.wrap, распространяет любую ошибку вызывающей стороне. В этом случае функция также закрывает сопрограмму (см. coroutine.close).
В качестве примера того, как работают сопрограммы, рассмотрим следующий код:
function foo (a)
print("foo", a)
return coroutine.yield(2*a)
end
co = coroutine.create(function (a,b)
print("co-body", a, b)
local r = foo(a+1)
print("co-body", r)
local r, s = coroutine.yield(a+b, a-b)
print("co-body", r, s)
return b, "end"
end)
print("main", coroutine.resume(co, 1, 10))
print("main", coroutine.resume(co, "r"))
print("main", coroutine.resume(co, "x", "y"))
print("main", coroutine.resume(co, "x", "y"))
Когда вы запустите его, он выдаст следующий вывод:
co-body 1 10
foo 2
main true 4
co-body r
main true 11 -9
co-body x y
main true 10 end
main false cannot resume dead coroutine
Вы также можете создавать сопрограммы и управлять ими через C API: см. функции lua_newthread, lua_resume и lua_yield.
2.2 - 3 – Язык Lua: Лексика и синтаксис
Оглавление
3 – Язык
В этом разделе описываются лексика, синтаксис и семантика Lua. Другими словами, здесь описывается, какие лексемы допустимы, как их можно комбинировать и что означают их комбинации.
Языковые конструкции будут объясняться с использованием обычной расширенной формы Бэкуса-Наура (РБНФ), в которой {a} означает 0 или более a, а [a] означает необязательное a. Нетерминалы показаны как нетерминал, ключевые слова показаны как kword, а другие терминальные символы показаны как ‘=’. Полный синтаксис Lua можно найти в §9 в конце этого руководства.
3.1 – Лексические соглашения
Lua — это язык со свободной формой записи. Он игнорирует пробелы и комментарии между лексическими элементами (токенами), за исключением случаев, когда они выступают в роли разделителей между двумя токенами. В исходном коде Lua распознает как пробелы стандартные пробельные символы ASCII: пробел, перевод страницы, перевод строки, возврат каретки, горизонтальную табуляцию и вертикальную табуляцию.
Имена (также называемые идентификаторами) в Lua могут быть любой строкой, состоящей из латинских букв, арабско-индийских цифр и символов подчеркивания, не начинающейся с цифры и не являющейся зарезервированным словом. Идентификаторы используются для именования переменных, полей таблиц и меток.
Следующие ключевые слова зарезервированы и не могут использоваться в качестве имен:
and break do else elseif end
false for function global goto if
in local nil not or repeat
return then true until while
Lua — регистрозависимый язык: and — зарезервированное слово, но And и AND — два разных допустимых имени. В соответствии с соглашением, в программах следует избегать создания имен, начинающихся с подчеркивания, за которым следует одна или несколько заглавных букв (например, _VERSION).
Следующие строки обозначают другие токены:
+ - * / % ^ #
& ~ | << >> //
== ~= <= >= < > =
( ) { } [ ] ::
; : , . .. ...
Короткая литеральная строка может быть ограничена парными одинарными или двойными кавычками и может содержать следующие C-подобные escape-последовательности: \a (звонок), \b (забой), \f (перевод страницы), \n (перевод строки), \r (возврат каретки), \t (горизонтальная табуляция), \v (вертикальная табуляция), \\ (обратная косая черта), \" (кавычка [двойная]) и \' (апостроф [одинарная кавычка]). Обратная косая черта, за которой следует разрыв строки, приводит к появлению символа новой строки в строке. Escape-последовательность \z пропускает следующий за ней диапазон пробельных символов, включая разрывы строк; это особенно полезно для разбиения и отступа длинной литеральной строки на несколько строк без добавления символов новой строки и пробелов в содержимое строки. Короткая литеральная строка не может содержать неэкранированные разрывы строк или escape-последовательности, не образующие допустимую управляющую последовательность.
Мы можем указать любой байт в короткой литеральной строке, включая встроенные нули, по его числовому значению. Это можно сделать с помощью escape-последовательности \xXX, где XX — это последовательность ровно из двух шестнадцатеричных цифр, или с помощью escape-последовательности \ddd, где ddd — последовательность до трех десятичных цифр. (Обратите внимание, что если за десятичной escape-последовательностью должна следовать цифра, она должна быть выражена ровно тремя цифрами).
Кодировка UTF-8 символа Unicode может быть вставлена в литеральную строку с помощью escape-последовательности \u{XXX} (с обязательными фигурными скобками), где XXX — это последовательность из одной или более шестнадцатеричных цифр, представляющих кодовую точку символа. Эта кодовая точка может быть любым значением меньше 231. (Здесь Lua использует оригинальную спецификацию UTF-8, которая не ограничена допустимыми кодовыми точками Unicode).
Литеральные строки также могут быть определены с использованием длинного формата, заключенного в длинные скобки. Мы определяем открывающую длинную скобку уровня n как открывающую квадратную скобку, за которой следует n знаков равенства, а затем еще одна открывающая квадратная скобка. Так, открывающая длинная скобка уровня 0 записывается как [[, уровня 1 — как [=[, и так далее. Закрывающая длинная скобка определяется аналогично; например, закрывающая длинная скобка уровня 4 записывается как ]====]. Длинный литерал начинается с открывающей длинной скобки любого уровня и заканчивается на первой закрывающей длинной скобке того же уровня. Он может содержать любой текст, кроме закрывающей скобки того же уровня. Литералы в этой скобочной форме могут занимать несколько строк, не интерпретируют никакие escape-последовательности и игнорируют длинные скобки любых других уровней. Любой вид последовательности конца строки (возврат каретки, перевод строки, возврат каретки с последующим переводом строки или перевод строки с последующим возвратом каретки) преобразуется в простой перевод строки. Если за открывающей длинной скобкой сразу следует перевод строки, этот перевод строки не включается в строку.
В качестве примера, в системе, использующей ASCII (где ‘a’ кодируется как 97, перевод строки как 10, а ‘1’ как 49), следующие пять литеральных строк обозначают одну и ту же строку:
a = 'alo\n123"'
a = "alo\n123\""
a = '\97lo\10\04923"'
a = [[alo
123"]]
a = [==[
alo
123"]==]
Любой байт в литеральной строке, на который явно не повлияли предыдущие правила, представляет сам себя. Однако Lua открывает файлы для разбора в текстовом режиме, и файловые функции системы могут иметь проблемы с некоторыми управляющими символами. Поэтому безопаснее представлять двоичные данные в виде закавыченного литерала с явными escape-последовательностями для нетекстовых символов.
Числовая константа (или число) может быть записана с необязательной дробной частью и необязательным десятичным порядком, обозначаемым буквой ’e’ или ‘E’. Lua также принимает шестнадцатеричные константы, начинающиеся с 0x или 0X. Шестнадцатеричные константы также могут иметь необязательную дробную часть плюс необязательный двоичный порядок, обозначаемый буквой ‘p’ или ‘P’ и записываемый в десятичном виде. (Например, 0x1.fp10 обозначает 1984, то есть 0x1f / 16, умноженное на 210).
Числовая константа с десятичной точкой или порядком обозначает число с плавающей запятой (float); в противном случае, если ее значение помещается в целое число или она является шестнадцатеричной константой, она обозначает целое число (integer); в противном случае (то есть десятичное целое число, вызывающее переполнение) она обозначает float. Шестнадцатеричные числа без точки и порядка всегда обозначают целое значение; если значение переполняется, оно “сворачивается” (wrap around), чтобы соответствовать допустимому целому числу.
Примеры допустимых целочисленных констант:
3 345 0xff 0xBEBADA
Примеры допустимых констант с плавающей запятой:
3.0 3.1416 314.16e-2 0.31416E1 34e1
0x0.1E 0xA23p-4 0X1.921FB54442D18P+1
Комментарий начинается с двойного дефиса (--) в любом месте вне строки. Если текст сразу после -- не является открывающей длинной скобкой, комментарий является коротким комментарием, который длится до конца строки. В противном случае это длинный комментарий, который длится до соответствующей закрывающей длинной скобки.
3.2 – Переменные
Переменные — это места, хранящие значения. В Lua существует три вида переменных: глобальные переменные, локальные переменные и поля таблиц.
Одиночное имя может обозначать глобальную переменную или локальную переменную (или формальный параметр функции, который является особым видом локальной переменной) (см. §2.2):
var ::= Name
Name обозначает идентификаторы (см. §3.1).
Поскольку переменные имеют лексическую область видимости, локальные переменные могут свободно использоваться функциями, определенными внутри их области видимости (см. §2.2).
До первого присваивания переменной ее значение равно nil.
Квадратные скобки используются для индексации таблицы:
var ::= prefixexp ‘[’ exp ‘]’
Значение доступов к полям таблицы может быть изменено через метатаблицы (см. §2.4).
Синтаксис var.Name — это просто синтаксический сахар для var["Name"]:
var ::= prefixexp ‘.’ Name
Доступ к глобальной переменной x эквивалентен _ENV.x.
3.3 – Инструкции (Statements)
Lua поддерживает почти общепринятый набор инструкций, похожий на те, что есть в других обычных языках. Этот набор включает блоки, присваивания, управляющие структуры, вызовы функций и объявления переменных.
3.3.1 – Блоки
Блок — это список инструкций, которые выполняются последовательно:
block ::= {stat}
В Lua есть пустые инструкции, которые позволяют разделять инструкции точкой с запятой, начинать блок с точки с запятой или писать две точки с запятой подряд:
stat ::= ‘;’
Как вызовы функций, так и присваивания могут начинаться с открывающей скобки. Эта возможность приводит к неоднозначности в грамматике Lua. Рассмотрим следующий фрагмент:
a = b + c
(print or io.write)('done')
Грамматика может интерпретировать этот фрагмент двумя способами:
a = b + c(print or io.write)('done')
a = b + c; (print or io.write)('done')
Текущий парсер всегда интерпретирует такие конструкции первым способом, рассматривая открывающую скобку как начало аргументов вызова. Чтобы избежать этой неоднозначности, рекомендуется всегда предварять точкой с запятой инструкции, начинающиеся со скобки:
;(print or io.write)('done')
Блок может быть явно выделен для создания одиночной инструкции:
stat ::= do block end
Явные блоки полезны для управления областью видимости объявлений переменных. Явные блоки также иногда используются для добавления инструкции return в середине другого блока (см. §3.3.4).
3.3.2 – Чанки
Единица компиляции Lua называется чанком (chunk). Синтаксически чанк — это просто блок:
chunk ::= block
Lua обрабатывает чанк как тело анонимной функции с переменным числом аргументов (см. §3.4.11). Таким образом, чанки могут определять локальные переменные, получать аргументы и возвращать значения. Более того, такая анонимная функция компилируется как находящаяся в области видимости внешней локальной переменной с именем _ENV (см. §2.2). Результирующая функция всегда имеет _ENV в качестве своей единственной внешней переменной, даже если она не использует эту переменную.
Чанк может храниться в файле или в строке внутри программы-хоста. Чтобы выполнить чанк, Lua сначала загружает его, предварительно компилируя код чанка в инструкции для виртуальной машины, а затем Lua выполняет скомпилированный код с помощью интерпретатора виртуальной машины.
Чанки также могут быть предварительно скомпилированы в двоичную форму; подробности см. в программе luac и функции string.dump. Программы в исходной и скомпилированной формах взаимозаменяемы; Lua автоматически определяет тип файла и действует соответственно (см. load). Имейте в виду, что, в отличие от исходного кода, злонамеренно созданные двоичные чанки могут вызвать крах интерпретатора.
3.3.3 – Присваивание
Lua допускает множественное присваивание. Поэтому синтаксис присваивания определяет список переменных слева и список выражений справа. Элементы в обоих списках разделяются запятыми:
stat ::= varlist ‘=’ explist
varlist ::= var {‘,’ var}
explist ::= exp {‘,’ exp}
Выражения обсуждаются в §3.4.
Перед присваиванием список значений выравнивается по длине списка переменных (см. §3.4.12).
Если переменная одновременно присваивается и читается внутри множественного присваивания, Lua гарантирует, что все чтения получат значение переменной до присваивания. Таким образом, код
i = 3
i, a[i] = i+1, 20
устанавливает a[3] в 20, не затрагивая a[4], потому что i в a[i] вычисляется (в 3) до того, как ей присваивается 4. Аналогично, строка
x, y = y, x
обменивает значения x и y, а
x, y, z = y, z, x
циклически переставляет значения x, y и z.
Обратите внимание, что эта гарантия распространяется только на доступы, синтаксически находящиеся внутри инструкции присваивания. Если функция или метаметод, вызванные во время присваивания, изменяют значение переменной, Lua не дает никаких гарантий относительно порядка этого доступа.
Присваивание глобальному имени x = val эквивалентно присваиванию _ENV.x = val (см. §2.2).
Значение присваиваний полям таблиц и глобальным переменным (которые на самом деле тоже являются полями таблиц) может быть изменено через метатаблицы (см. §2.4).
3.3.4 – Управляющие структуры
Управляющие структуры if, while и repeat имеют обычный смысл и знакомый синтаксис:
stat ::= while exp do block end
stat ::= repeat block until exp
stat ::= if exp then block {elseif exp then block} [else block] end
В Lua также есть инструкция for в двух вариантах (см. §3.3.5).
Выражение-условие управляющей структуры может возвращать любое значение. И false, и nil проверяются как ложь. Все значения, отличные от nil и false, проверяются как истина. В частности, число 0 и пустая строка также проверяются как истина.
В цикле repeat–until внутренний блок не заканчивается на ключевом слове until, а только после условия. Таким образом, условие может ссылаться на локальные переменные, объявленные внутри блока цикла.
Инструкция goto передает управление программой на метку. По синтаксическим причинам метки в Lua также считаются инструкциями:
stat ::= goto Name
stat ::= label
label ::= ‘::’ Name ‘::’
Метка видна во всем блоке, где она определена, за исключением вложенных функций. goto может переходить на любую видимую метку, если при этом не происходит входа в область видимости объявления переменной. Метка не должна быть объявлена там, где видна предыдущая метка с тем же именем, даже если эта другая метка была объявлена в охватывающем блоке.
Инструкция break завершает выполнение цикла while, repeat или for, переходя к следующей инструкции после цикла:
stat ::= break
break завершает самый внутренний объемлющий цикл.
Инструкция return используется для возврата значений из функции или чанка (который обрабатывается как анонимная функция). Функции могут возвращать более одного значения, поэтому синтаксис инструкции return таков:
stat ::= return [explist] [‘;’]
Инструкция return может быть записана только как последняя инструкция блока. Если необходимо выполнить возврат в середине блока, можно использовать явный внутренний блок, как в идиоме do return end, потому что теперь return является последней инструкцией в своем (внутреннем) блоке.
3.3.5 – Инструкция For
Инструкция for имеет две формы: числовую и обобщенную.
Числовой цикл for
Числовой цикл for повторяет блок кода, пока управляющая переменная проходит через арифметическую прогрессию. Он имеет следующий синтаксис:
stat ::= for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end
Заданный идентификатор (Name) определяет управляющую переменную, которая является новой переменной только для чтения (const), локальной для тела цикла (block).
Цикл начинается с однократного вычисления трех управляющих выражений. Их значения называются соответственно начальным значением, пределом и шагом. Если шаг отсутствует, по умолчанию он равен 1.
Если и начальное значение, и шаг являются целыми числами, цикл выполняется с целыми числами; обратите внимание, что предел может не быть целым числом. В противном случае три значения преобразуются в числа с плавающей запятой, и цикл выполняется с плавающей запятой. В этом случае следует опасаться точности чисел с плавающей запятой.
После этой инициализации тело цикла повторяется, при этом значение управляющей переменной проходит через арифметическую прогрессию, начиная с начального значения, с разностью, заданной шагом. Отрицательный шаг создает убывающую последовательность; шаг, равный нулю, вызывает ошибку. Цикл продолжается, пока значение меньше или равно пределу (больше или равно для отрицательного шага). Если начальное значение уже больше предела (или меньше, если шаг отрицательный), тело не выполняется.
Для целочисленных циклов управляющая переменная никогда не “сворачивается” (wrap around); вместо этого цикл заканчивается в случае переполнения.
Обобщенный цикл for
Обобщенная инструкция for работает с функциями, называемыми итераторами. На каждой итерации функция-итератор вызывается для получения нового значения, останавливаясь, когда это новое значение равно nil. Обобщенный цикл for имеет следующий синтаксис:
stat ::= for namelist in explist do block end
namelist ::= Name {‘,’ Name}
Инструкция for, такая как
for var_1, ···, var_n in explist do body end
работает следующим образом.
Имена var_i объявляют переменные цикла, локальные для тела цикла. Первая из этих переменных является управляющей переменной, которая является переменной только для чтения (const).
Цикл начинается с вычисления explist для получения четырех значений: функции-итератора, состояния, начального значения для управляющей переменной и закрывающего значения.
Затем, на каждой итерации, Lua вызывает функцию-итератор с двумя аргументами: состоянием и управляющей переменной. Результаты этого вызова затем присваиваются переменным цикла в соответствии с правилами множественного присваивания (см. §3.3.3). Если управляющая переменная становится nil, цикл завершается. В противном случае выполняется тело, и цикл переходит к следующей итерации.
Закрывающее значение ведет себя как закрываемая переменная (to-be-closed variable) (см. §3.3.8), которая может использоваться для освобождения ресурсов при завершении цикла. В остальном оно не влияет на цикл.
3.3.6 – Вызовы функций как инструкции
Для обеспечения возможных побочных эффектов вызовы функций могут выполняться как инструкции:
stat ::= functioncall
В этом случае все возвращаемые значения отбрасываются. Вызовы функций объясняются в §3.4.10.
3.3.7 – Объявления переменных
Локальные и глобальные переменные могут быть объявлены в любом месте внутри блока. Объявление может включать инициализацию:
stat ::= local attnamelist [‘=’ explist]
stat ::= global attnamelist [‘=’ explist]
Если инициализация отсутствует, локальные переменные инициализируются значением nil; глобальные переменные остаются без изменений. В противном случае инициализация подвергается тому же выравниванию, что и множественное присваивание (см. §3.3.3). Более того, для глобальных переменных инициализация вызовет ошибку времени выполнения, если переменная уже определена, то есть имеет значение, отличное от nil.
Список имен может иметь префиксный атрибут (имя в угловых скобках), и каждое имя переменной может иметь постфиксный атрибут:
attnamelist ::= [attrib] Name [attrib] {‘,’ Name [attrib]}
attrib ::= ‘<’ Name ‘>’
Префиксный атрибут применяется ко всем именам в списке; постфиксный атрибут применяется к конкретному имени. Существует два возможных атрибута: const, который объявляет константу или переменную только для чтения, то есть переменную, которая не может использоваться в левой части присваивания, и close, который объявляет закрываемую переменную (to-be-closed variable) (см. §3.3.8). Только локальные переменные могут иметь атрибут close. Список переменных может содержать не более одной закрываемой переменной.
Lua предлагает также коллективное объявление для глобальных переменных:
stat ::= global [attrib] ‘*’
Эта специальная форма неявно объявляет как глобальные все имена, которые ранее не были объявлены явно. В частности, global<const> * неявно объявляет как глобальные только для чтения все имена, не объявленные ранее явно; см. следующий пример:
global X
global<const> *
print(math.pi) -- Ok, 'print' и 'math' только для чтения
X = 1 -- Ok, объявлена как для чтения-записи
Y = 1 -- Ошибка, Y только для чтения
Как отмечено в §2.2, все чанки начинаются с неявного объявления global *, но это вводное объявление становится недействительным внутри области видимости любого другого объявления global. Следовательно, программа, которая не использует объявления global или начинается с global *, имеет свободный доступ на чтение и запись к любой глобальной переменной; программа, которая начинается с global<const> *, имеет свободный доступ только для чтения к любой глобальной переменной; а программа, которая начинается с любого другого объявления global (например, global none), может ссылаться только на объявленные переменные.
Обратите внимание, что для глобальных переменных эффект любого объявления является чисто синтаксическим (за исключением необязательного присваивания):
global X <const>, _G
X = 1 -- ОШИБКА
_ENV.X = 1 -- Ok
_G.print(X) -- Ok
foo() -- 'foo' может свободно изменять любую глобальную переменную
Чанк также является блоком (см. §3.3.2), поэтому переменные могут быть объявлены в чанке вне любого явного блока.
Правила видимости для объявлений переменных объясняются в §2.2.
3.3.8 – Закрываемые переменные (To-be-closed Variables)
Закрываемая переменная ведет себя как константная локальная переменная, за исключением того, что ее значение закрывается всякий раз, когда переменная выходит из области видимости, включая нормальное завершение блока, выход из блока по break/goto/return или выход из-за ошибки.
Здесь закрыть значение означает вызвать его метаметод __close. При вызове метаметода само значение передается в качестве первого аргумента. Если произошла ошибка, объект ошибки, вызвавший выход, передается в качестве второго аргумента; в противном случае второй аргумент отсутствует.
Значение, присваиваемое закрываемой переменной, должно иметь метаметод __close или быть ложным значением. (nil и false игнорируются как закрываемые значения).
Если несколько закрываемых переменных выходят из области видимости при одном и том же событии, они закрываются в порядке, обратном порядку их объявления.
Если во время выполнения метода закрытия возникает ошибка, эта ошибка обрабатывается как ошибка в обычном коде, где была определена переменная. После ошибки остальные ожидающие методы закрытия все равно будут вызваны.
Если сопрограмма (coroutine) выполняет yield и никогда не возобновляется, некоторые переменные могут никогда не выйти из области видимости и, следовательно, никогда не будут закрыты. (Эти переменные — те, которые созданы внутри сопрограммы и находятся в области видимости в точке, где сопрограмма выполнила yield). Аналогично, если сопрограмма завершается с ошибкой, она не разворачивает свой стек, поэтому не закрывает никакие переменные. В обоих случаях вы можете либо использовать финализаторы, либо вызвать coroutine.close для закрытия переменных. Однако если сопрограмма была создана через coroutine.wrap, то соответствующая функция закроет сопрограмму в случае ошибок.
3.4 – Выражения
Базовыми выражениями в Lua являются следующие:
exp ::= prefixexp
exp ::= nil | false | true
exp ::= Numeral
exp ::= LiteralString
exp ::= functiondef
exp ::= tableconstructor
exp ::= ‘...’
exp ::= exp binop exp
exp ::= unop exp
prefixexp ::= var | functioncall | ‘(’ exp ‘)’
Числа и литеральные строки объясняются в §3.1; переменные — в §3.2; определения функций — в §3.4.11; вызовы функций — в §3.4.10; конструкторы таблиц — в §3.4.9. Выражения vararg, обозначаемые тремя точками ('...'), могут использоваться только непосредственно внутри вариадической функции; они объясняются в §3.4.11.
Бинарные операторы включают арифметические операторы (см. §3.4.1), побитовые операторы (см. §3.4.2), операторы отношения (см. §3.4.4), логические операторы (см. §3.4.5) и оператор конкатенации (см. §3.4.6). Унарные операторы включают унарный минус (см. §3.4.1), унарное побитовое НЕ (см. §3.4.2), унарное логическое not (см. §3.4.5) и унарный оператор длины (см. §3.4.7).
3.4.1 – Арифметические операторы
Lua поддерживает следующие арифметические операторы:
+: сложение-: вычитание*: умножение/: деление с плавающей запятой (float division)//: деление нацело вниз (floor division)%: остаток от деления (modulo)^: возведение в степень-: унарный минус
За исключением возведения в степень и деления с плавающей запятой, арифметические операторы работают следующим образом: Если оба операнда являются целыми числами, операция выполняется над целыми числами, и результат является целым числом. В противном случае, если оба операнда — числа, они преобразуются в числа с плавающей запятой, операция выполняется в соответствии с машинными правилами арифметики с плавающей запятой (обычно стандарт IEEE 754), и результатом является число с плавающей запятой. (Библиотека string приводит строки к числам в арифметических операциях; подробности см. в §3.4.3).
Возведение в степень и деление с плавающей запятой (/) всегда преобразуют свои операнды в числа с плавающей запятой, и результатом всегда является число с плавающей запятой. Возведение в степень использует функцию pow стандарта ISO C, поэтому оно работает и для нецелочисленных показателей.
Деление нацело вниз (//) — это деление, которое округляет частное в сторону минус бесконечности, в результате чего получается пол (floor) от деления операндов.
Остаток от деления (%) определяется как остаток от деления, которое округляет частное в сторону минус бесконечности (деление нацело вниз).
В случае переполнения в целочисленной арифметике все операции “сворачиваются” (wrap around).
3.4.2 – Побитовые операторы
Lua поддерживает следующие побитовые операторы:
&: побитовое И (AND)|: побитовое ИЛИ (OR)~: побитовое исключающее ИЛИ (XOR)>>: сдвиг вправо<<: сдвиг влево~: унарное побитовое НЕ (NOT)
Все побитовые операции преобразуют свои операнды в целые числа (см. §3.4.3), работают со всеми битами этих целых чисел и дают в результате целое число.
Как правый, так и левый сдвиги заполняют освобождающиеся биты нулями. Отрицательные сдвиги смещают в противоположном направлении; сдвиги с абсолютными значениями, равными или превышающими количество бит в целом числе, дают в результате ноль (поскольку все биты сдвигаются за пределы).
3.4.3 – Приведения и преобразования
Lua предоставляет некоторые автоматические преобразования между типами и представлениями во время выполнения. Побитовые операторы всегда преобразуют операнды с плавающей запятой в целые числа. Возведение в степень и деление с плавающей запятой всегда преобразуют целочисленные операнды в числа с плавающей запятой. Все другие арифметические операции, применяемые к смешанным числам (целым и с плавающей запятой), преобразуют целочисленный операнд в число с плавающей запятой. C API также преобразует целые числа в числа с плавающей запятой и наоборот по мере необходимости. Более того, конкатенация строк принимает числа в качестве аргументов, помимо строк.
При преобразовании из целого числа в число с плавающей запятой, если целое значение имеет точное представление в виде числа с плавающей запятой, то оно и является результатом. В противном случае преобразование дает ближайшее большее или ближайшее меньшее представимое значение. Такой вид преобразования никогда не завершается неудачей.
Преобразование из числа с плавающей запятой в целое проверяет, имеет ли число с плавающей запятой точное представление в виде целого числа (то есть число с плавающей запятой имеет целое значение и находится в диапазоне целочисленного представления). Если да, то это представление является результатом. В противном случае преобразование завершается неудачей.
В нескольких местах Lua приводит строки к числам, когда это необходимо. В частности, библиотека string устанавливает метаметоды, которые пытаются привести строки к числам во всех арифметических операциях. Если преобразование не удается, библиотека вызывает метаметод другого операнда (если он присутствует) или вызывает ошибку. Обратите внимание, что побитовые операторы не выполняют этого приведения.
Всегда рекомендуется не полагаться на неявные приведения строк к числам, поскольку они применяются не всегда; в частности, "1"==1 ложно, а "1"<1 вызывает ошибку (см. §3.4.4). Эти приведения существуют в основном для совместимости и могут быть удалены в будущих версиях языка.
Строка преобразуется в целое число или число с плавающей запятой в соответствии со своим синтаксисом и правилами лексера Lua. Строка также может иметь начальные и конечные пробелы и знак. Все преобразования строк в числа принимают как точку, так и текущий локальный разделитель целой и дробной части в качестве символа десятичной точки. (Однако лексер Lua принимает только точку). Если строка не является допустимым числом, преобразование завершается неудачей. При необходимости результат этого первого шага затем преобразуется в конкретный числовой подтип в соответствии с предыдущими правилами для преобразований между числами с плавающей запятой и целыми числами.
Преобразование чисел в строки использует неуказанный человекочитаемый формат. Для преобразования чисел в строки каким-либо определенным способом используйте функцию string.format.
3.4.4 – Операторы отношения
Lua поддерживает следующие операторы отношения:
==: равенство~=: неравенство<: меньше>: больше<=: меньше или равно>=: больше или равно
Эти операторы всегда дают результат false или true.
Равенство (==) сначала сравнивает типы своих операндов. Если типы различны, то результатом является false. В противном случае сравниваются значения операндов. Строки равны, если они имеют одинаковое байтовое содержимое. Числа равны, если они обозначают одно и то же математическое значение.
Таблицы, пользовательские данные (userdata) и потоки (threads) сравниваются по ссылке: два объекта считаются равными, только если это один и тот же объект. Каждый раз, когда вы создаете новый объект (таблицу, userdata или поток), этот новый объект отличается от любого ранее существовавшего объекта. Функция всегда равна самой себе. Функции с любым обнаруживаемым различием (разное поведение, разное определение) всегда различны. Функции, созданные в разное время, но без обнаруживаемых различий, могут быть классифицированы как равные или нет (в зависимости от деталей внутреннего кэширования).
Вы можете изменить способ сравнения таблиц и userdata в Lua, используя метаметод __eq (см. §2.4).
Сравнения на равенство не преобразуют строки в числа или наоборот. Таким образом, "0"==0 дает false, а t[0] и t["0"] обозначают разные записи в таблице.
Оператор ~= является точным отрицанием равенства (==).
Операторы порядка работают следующим образом. Если оба аргумента — числа, то они сравниваются в соответствии с их математическими значениями, независимо от их подтипов. В противном случае, если оба аргумента — строки, то их значения сравниваются в соответствии с текущей локалью. В противном случае Lua пытается вызвать метаметод __lt или __le (см. §2.4). Сравнение a > b транслируется в b < a, а a >= b транслируется в b <= a.
В соответствии со стандартом IEEE 754, специальное значение NaN не считается ни меньше, ни равным, ни больше какого-либо значения, включая само себя.
3.4.5 – Логические операторы
Логическими операторами в Lua являются and, or и not. Как и управляющие структуры (см. §3.3.4), все логические операторы считают false и nil ложью, а все остальное — истиной.
Оператор отрицания not всегда возвращает false или true. Оператор конъюнкции and возвращает свой первый аргумент, если это значение ложно (false или nil); в противном случае and возвращает свой второй аргумент. Оператор дизъюнкции or возвращает свой первый аргумент, если это значение отличается от nil и false; в противном случае or возвращает свой второй аргумент. И and, и or используют сокращенное вычисление (short-circuit evaluation); то есть второй операнд вычисляется, только если это необходимо. Вот несколько примеров:
10 or 20 --> 10
10 or error() --> 10
nil or "a" --> "a"
nil and 10 --> nil
false and error() --> false
false and nil --> false
false or nil --> nil
10 and 20 --> 20
3.4.6 – Конкатенация
Оператор конкатенации строк в Lua обозначается двумя точками ('..'). Если оба операнда являются строками или числами, то числа преобразуются в строки в неуказанном формате (см. §3.4.3). В противном случае вызывается метаметод __concat (см. §2.4).
3.4.7 – Оператор длины
Оператор длины обозначается унарным префиксным оператором #.
Длина строки — это количество ее байтов. (Это обычный смысл длины строки, когда каждый символ занимает один байт).
Оператор длины, примененный к таблице, возвращает границу (border) в этой таблице. Граница в таблице t — это любое неотрицательное целое число, которое удовлетворяет следующему условию:
(border == 0 or t[border] ~= nil) and
(t[border + 1] == nil or border == math.maxinteger)
Другими словами, граница — это любой положительный целочисленный индекс, присутствующий в таблице, за которым следует отсутствующий индекс, плюс два предельных случая: ноль, когда индекс 1 отсутствует; и максимальное значение для целого числа, когда этот индекс присутствует. Обратите внимание, что ключи, не являющиеся положительными целыми числами, не влияют на границы.
Таблица ровно с одной границей называется последовательностью (sequence). Например, таблица {10,20,30,40,50} является последовательностью, так как у нее только одна граница (5). Таблица {10,20,30,nil,50} имеет две границы (3 и 5) и, следовательно, не является последовательностью. (nil по индексу 4 называется дырой). Таблица {nil,20,30,nil,nil,60,nil} имеет три границы (0, 3 и 6), поэтому она тоже не является последовательностью. Таблица {} является последовательностью с границей 0.
Когда t — последовательность, #t возвращает ее единственную границу, что соответствует интуитивному понятию длины последовательности. Когда t не является последовательностью, #t может вернуть любую из ее границ. (Конкретная граница зависит от деталей внутреннего представления таблицы, которые, в свою очередь, могут зависеть от того, как таблица была заполнена, и от адресов памяти ее нечисловых ключей).
Вычисление длины таблицы имеет гарантированное наихудшее время O(log n), где n — наибольший целочисленный ключ в таблице.
Программа может изменить поведение оператора длины для любого значения, кроме строк, через метаметод __len (см. §2.4).
3.4.8 – Приоритет операторов
Приоритет операторов в Lua соответствует таблице ниже, от низшего к высшему:
or
and
< > <= >= ~= ==
|
~
&
<< >>
..
+ -
* / // %
унарные операторы (not # - ~)
^
Как обычно, вы можете использовать скобки для изменения приоритетов в выражении. Операторы конкатенации ('..') и возведения в степень ('^') правоассоциативны. Все остальные бинарные операторы левоассоциативны.
3.4.9 – Конструкторы таблиц
Конструкторы таблиц — это выражения, которые создают таблицы. Каждый раз, когда конструктор вычисляется, создается новая таблица. Конструктор можно использовать для создания пустой таблицы или для создания таблицы и инициализации некоторых ее полей. Общий синтаксис конструкторов таков:
tableconstructor ::= ‘{’ [fieldlist] ‘}’
fieldlist ::= field {fieldsep field} [fieldsep]
field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp
fieldsep ::= ‘,’ | ‘;’
Каждое поле вида [exp1] = exp2 добавляет в новую таблицу запись с ключом exp1 и значением exp2. Поле вида name = exp эквивалентно ["name"] = exp. Поля вида exp эквивалентны [i] = exp, где i — последовательные целые числа, начиная с 1; поля в других форматах не влияют на этот подсчет. Например,
a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }
эквивалентно
do
local t = {}
t[f(1)] = g
t[1] = "x" -- 1-е exp
t[2] = "y" -- 2-е exp
t.x = 1 -- t["x"] = 1
t[3] = f(x) -- 3-е exp
t[30] = 23
t[4] = 45 -- 4-е exp
a = t
end
Порядок присваиваний в конструкторе не определен. (Этот порядок имел бы значение только при наличии повторяющихся ключей).
Если последнее поле в списке имеет вид exp и выражение является выражением с множественными результатами (multires expression), то все значения, возвращаемые этим выражением, последовательно входят в список (см. §3.4.12).
Список полей может иметь необязательный завершающий разделитель для удобства машинно-генерируемого кода.
3.4.10 – Вызовы функций
Вызов функции в Lua имеет следующий синтаксис:
functioncall ::= prefixexp args
При вызове функции сначала вычисляются prefixexp и args. Если значение prefixexp имеет тип function, то эта функция вызывается с заданными аргументами. В противном случае, если присутствует метаметод __call у prefixexp, он вызывается: его первым аргументом является значение prefixexp, за которым следуют исходные аргументы вызова (см. §2.4).
Форма
functioncall ::= prefixexp ‘:’ Name args
может использоваться для эмуляции методов. Вызов v:name(args) является синтаксическим сахаром для v.name(v, args), за исключением того, что v вычисляется только один раз.
Аргументы имеют следующий синтаксис:
args ::= ‘(’ [explist] ‘)’
args ::= tableconstructor
args ::= LiteralString
Все выражения-аргументы вычисляются перед вызовом. Вызов формы f{fields} является синтаксическим сахаром для f({fields}); то есть список аргументов — это единственная новая таблица. Вызов формы f'string' (или f"string", или f[[string]]) является синтаксическим сахаром для f('string'); то есть список аргументов — это единственная литеральная строка.
Вызов формы return functioncall, не находящийся в области видимости закрываемой переменной, называется хвостовым вызовом (tail call). Lua реализует правильные хвостовые вызовы (proper tail calls или proper tail recursion): при хвостовом вызове вызываемая функция повторно использует стековый фрейм вызывающей функции. Следовательно, нет ограничения на количество вложенных хвостовых вызовов, которые может выполнить программа. Однако хвостовой вызов стирает любую отладочную информацию о вызывающей функции. Обратите внимание, что хвостовой вызов происходит только при определенном синтаксисе, когда return имеет один-единственный вызов функции в качестве аргумента, и это происходит вне области видимости любой закрываемой переменной. Этот синтаксис заставляет вызывающую функцию возвращать в точности то, что возвращает вызываемая функция, без каких-либо промежуточных действий. Таким образом, ни один из следующих примеров не является хвостовым вызовом:
return (f(x)) -- результаты выравниваются до 1
return 2 * f(x) -- результат умножается на 2
return x, f(x) -- дополнительные результаты
f(x); return -- результаты отбрасываются
return x or f(x) -- результаты выравниваются до 1
3.4.11 – Определения функций
Синтаксис определения функции следующий:
functiondef ::= function funcbody
funcbody ::= ‘(’ [parlist] ‘)’ block end
Следующий синтаксический сахар упрощает определения функций:
stat ::= function funcname funcbody
stat ::= local function Name funcbody
stat ::= global function Name funcbody
funcname ::= Name {‘.’ Name} [‘:’ Name]
Инструкция
function f () body end
транслируется в
f = function () body end
Инструкция
function t.a.b.c.f () body end
транслируется в
t.a.b.c.f = function () body end
Инструкция
local function f () body end
транслируется в
local f; f = function () body end
а не в
local f = function () body end
(Это имеет значение только тогда, когда тело функции содержит рекурсивные ссылки на f). Аналогично, инструкция
global function f () body end
транслируется в
global f; global f = function () body end
Второе global делает присваивание инициализацией, которая вызовет ошибку, если эта глобальная переменная уже определена.
Синтаксис с двоеточием используется для эмуляции методов, добавляя неявный дополнительный параметр self в функцию. Таким образом, инструкция
function t.a.b.c:f (params) body end
является синтаксическим сахаром для
t.a.b.c.f = function (self, params) body end
Определение функции — это выполняемое выражение, значением которого является значение типа function. Когда Lua предкомпилирует чанк, все тела его функций также предкомпилируются, но они еще не создаются. Затем, когда Lua выполняет определение функции, функция инстанцируется (или замыкается). Этот экземпляр функции, или замыкание (closure), является окончательным значением выражения.
Результаты возвращаются с помощью инструкции return (см. §3.3.4). Если управление достигает конца функции без встречи инструкции return, то функция возвращается без результатов.
Существует системно-зависимое ограничение на количество значений, которые может вернуть функция. Гарантируется, что этот предел составляет не менее 1000.
Параметры
Параметры действуют как локальные переменные, которые инициализируются значениями аргументов:
parlist ::= namelist [‘,’ varargparam] | varargparam
varargparam ::= ‘...’ [Name]
Когда функция Lua вызывается, она выравнивает свой список аргументов по длине списка параметров (см. §3.4.12), если только функция не является вариадической, что указывается тремя точками ('...') в конце ее списка параметров. Вариадическая функция не выравнивает свой список аргументов; вместо этого она собирает все дополнительные аргументы и предоставляет их функции через vararg-таблицу. В этой таблице значения с индексами 1, 2 и т. д. являются дополнительными аргументами, а значение с индексом "n" — это количество дополнительных аргументов.
В качестве примера рассмотрим следующие определения:
function f(a, b) end
function g(a, b, ...) end
function r() return 1,2,3 end
Тогда мы имеем следующее отображение аргументов в параметры и в vararg-таблицу:
CALL PARAMETERS
f(3) a=3, b=nil
f(3, 4) a=3, b=4
f(3, 4, 5) a=3, b=4
f(r(), 10) a=1, b=10
f(r()) a=1, b=2
g(3) a=3, b=nil, va. table -> {n = 0}
g(3, 4) a=3, b=4, va. table -> {n = 0}
g(3, 4, 5, 8) a=3, b=4, va. table -> {5, 8, n = 2}
g(5, r()) a=5, b=1, va. table -> {2, 3, n = 2}
Vararg-таблица в вариадической функции может иметь необязательное имя, указанное после трех точек. Если оно присутствует, это имя обозначает локальную переменную только для чтения, которая ссылается на vararg-таблицу. Если у vararg-таблицы нет имени, доступ к ней можно получить только через vararg-выражение.
Vararg-выражение также записывается как три точки, и его значением является список значений в vararg-таблице от 1 до целочисленного значения по индексу "n". (Следовательно, если код не изменяет vararg-таблицу, этот список соответствует дополнительным аргументам в вызове функции). Этот список ведет себя как результаты функции с множественными результатами (см. §3.4.12).
В качестве оптимизации, если vararg-таблица удовлетворяет некоторым условиям, код не создает фактическую таблицу, а вместо этого транслирует индексные выражения и vararg-выражения в доступы к внутренним данным vararg. Условия следующие: если у vararg-таблицы есть имя, это имя не является upvalue во вложенной функции, и оно используется только как базовая таблица в синтаксических конструкциях t[exp] или t.id. Обратите внимание, что анонимная vararg-таблица всегда удовлетворяет этим условиям.
3.4.12 – Списки выражений, множественные результаты и выравнивание
Как вызовы функций, так и vararg-выражения могут давать множественные значения. Эти выражения называются выражениями с множественными результатами (multires expressions).
Когда выражение с множественными результатами используется как последний элемент списка выражений, все результаты выражения добавляются к списку значений, создаваемому списком выражений. Обратите внимание, что одиночное выражение в месте, где ожидается список выражений, является последним выражением в этом (одноэлементном) списке.
Вот места, где Lua ожидает список выражений:
- Инструкция
return, напримерreturn e1,e2,e3(см. §3.3.4). - Конструктор таблицы, например
{e1,e2,e3}(см. §3.4.9). - Аргументы вызова функции, например
foo(e1,e2,e3)(см. §3.4.10). - Множественное присваивание, например
a,b,c = e1,e2,e3(см. §3.3.3). - Объявление
localилиglobal, которое аналогично множественному присваиванию. - Начальные значения в обобщенном цикле
for, напримерfor k in e1,e2,e3 do ... end(см. §3.3.5).
В последних четырех случаях список значений из списка выражений должен быть выровнен до определенной длины: количество параметров при вызове невариадической функции (см. §3.4.11), количество переменных в множественном присваивании или объявлении и ровно четыре значения для обобщенного цикла for. Выравнивание следует этим правилам: если значений больше, чем нужно, лишние значения отбрасываются; если значений меньше, чем нужно, список дополняется значениями nil. Когда список выражений заканчивается выражением с множественными результатами, все результаты этого выражения входят в список значений до выравнивания.
Когда выражение с множественными результатами используется в списке выражений, не будучи последним элементом, или в месте, где синтаксис ожидает одиночное выражение, Lua выравнивает список результатов этого выражения до одного элемента. Как частный случай, синтаксис ожидает одиночное выражение внутри выражения в скобках; следовательно, добавление скобок вокруг выражения с множественными результатами заставляет его выдавать ровно один результат.
Нам редко нужно использовать vararg-выражение в месте, где синтаксис ожидает одиночное выражение. (Обычно проще добавить обычный параметр перед вариадической частью и использовать этот параметр). Когда такая необходимость возникает, мы рекомендуем присвоить vararg-выражение одиночной переменной и использовать эту переменную вместо него.
Вот несколько примеров использования выражений с множественными результатами. Во всех случаях, когда конструкции нужен “n-й результат”, а такого результата нет, используется nil.
print(x, f()) -- печатает x и все результаты из f().
print(x, (f())) -- печатает x и первый результат из f().
print(f(), x) -- печатает первый результат из f() и x.
print(1 + f()) -- печатает 1, сложенную с первым результатом из f().
local x = ... -- x получает первый vararg-аргумент.
x,y = ... -- x получает первый vararg-аргумент,
-- y получает второй vararg-аргумент.
x,y,z = w, f() -- x получает w, y получает первый результат из f(),
-- z получает второй результат из f().
x,y,z = f() -- x получает первый результат из f(),
-- y получает второй результат из f(),
-- z получает третий результат из f().
x,y,z = f(), g() -- x получает первый результат из f(),
-- y получает первый результат из g(),
-- z получает второй результат из g().
x,y,z = (f()) -- x получает первый результат из f(), y и z получают nil.
return f() -- возвращает все результаты из f().
return x, ... -- возвращает x и все полученные vararg-аргументы.
return x,y,f() -- возвращает x, y и все результаты из f().
{f()} -- создает список со всеми результатами из f().
{...} -- создает список со всеми vararg-аргументами.
{f(), 5} -- создает список с первым результатом из f() и 5.
2.3 - 4 – Интерфейс прикладного программирования (API)
Оглавление
4 – Интерфейс прикладного программирования
В этом разделе описывается C API для Lua, то есть набор функций C, доступных программе-хосту для взаимодействия с Lua. Все функции API и связанные с ними типы и константы объявлены в заголовочном файле lua.h.
Даже когда мы используем термин “функция”, любое средство в API может быть предоставлено в виде макроса. За исключением случаев, где указано иное, все такие макросы используют каждый из своих аргументов ровно один раз (кроме первого аргумента, который всегда является состоянием Lua), и поэтому не генерируют никаких скрытых побочных эффектов.
Как и в большинстве библиотек C, функции Lua API не проверяют свои аргументы на допустимость или согласованность. Однако вы можете изменить это поведение, скомпилировав Lua с определенным макросом LUA_USE_APICHECK.
Библиотека Lua полностью реентерабельна: у нее нет глобальных переменных. Она хранит всю необходимую информацию в динамической структуре, называемой состоянием Lua (Lua state).
Каждое состояние Lua имеет один или несколько потоков (threads), которые соответствуют независимым, кооперативным линиям выполнения. Тип lua_State (несмотря на свое имя) ссылается на поток. (Косвенно, через поток, он также ссылается на состояние Lua, связанное с потоком.)
Указатель на поток должен передаваться в качестве первого аргумента каждой функции в библиотеке, кроме lua_newstate, которая создает состояние Lua с нуля и возвращает указатель на главный поток в новом состоянии.
4.1 – Стек
Lua использует виртуальный стек для передачи значений в C и из C. Каждый элемент в этом стеке представляет значение Lua (nil, число, строка и т. д.). Функции в API могут обращаться к этому стеку через параметр состояния Lua, который они получают.
Всякий раз, когда Lua вызывает C, вызываемая функция получает новый стек, который независим от предыдущих стеков и от стеков функций C, которые все еще активны. Этот стек изначально содержит любые аргументы для функции C, и именно в нем функция C может хранить временные значения Lua и должна помещать свои результаты для возврата вызывающей стороне (см. lua_CFunction).
Для удобства большинство операций запроса в API не следуют строгой стековой дисциплине. Вместо этого они могут ссылаться на любой элемент в стеке, используя индекс: Положительный индекс представляет абсолютную позицию в стеке, начиная с 1 как дна стека; отрицательный индекс представляет смещение относительно вершины стека. Более конкретно, если в стеке n элементов, то индекс 1 представляет первый элемент (то есть элемент, который был помещен в стек первым), а индекс n представляет последний элемент; индекс -1 также представляет последний элемент (то есть элемент на вершине), а индекс -n представляет первый элемент.
4.1.1 – Размер стека
При взаимодействии с Lua API вы несете ответственность за обеспечение согласованности. В частности, вы отвечаете за контроль переполнения стека. При вызове любой функции API вы должны убедиться, что в стеке достаточно места для размещения результатов.
Из вышеуказанного правила есть одно исключение: когда вы вызываете функцию Lua без фиксированного количества результатов (см. lua_call), Lua гарантирует, что в стеке достаточно места для всех результатов. Однако она не гарантирует никакого дополнительного места. Поэтому перед тем, как помещать что-либо в стек после такого вызова, следует использовать lua_checkstack.
Всякий раз, когда Lua вызывает C, он гарантирует, что в стеке есть место как минимум для LUA_MINSTACK дополнительных элементов; то есть вы можете безопасно поместить в него до LUA_MINSTACK значений. LUA_MINSTACK определено как 20, так что обычно вам не нужно беспокоиться о пространстве стека, если только ваш код не содержит циклов, помещающих элементы в стек. При необходимости вы можете использовать функцию lua_checkstack, чтобы убедиться, что в стеке достаточно места для размещения новых элементов.
4.1.2 – Допустимые и приемлемые индексы
Любая функция в API, которая получает индексы стека, работает только с допустимыми индексами (valid indices) или приемлемыми индексами (acceptable indices).
Допустимый индекс — это индекс, который ссылается на позицию, хранящую изменяемое значение Lua. Он включает индексы стека между 1 и вершиной стека (1 ≤ abs(index) ≤ top) плюс псевдоиндексы, которые представляют некоторые позиции, доступные коду C, но не находящиеся в стеке. Псевдоиндексы используются для доступа к реестру (см. §4.3) и к upvalue функции C (см. §4.2).
Функции, которым не нужна конкретная изменяемая позиция, а только значение (например, функции запроса), могут вызываться с приемлемыми индексами. Приемлемый индекс может быть любым допустимым индексом, но также может быть любым положительным индексом после вершины стека в пределах пространства, выделенного для стека, то есть индексами вплоть до размера стека. (Обратите внимание, что 0 никогда не является приемлемым индексом.) Индексы к upvalue (см. §4.2), превышающие реальное количество upvalue в текущей функции C, также являются приемлемыми (но недопустимыми). За исключением случаев, когда указано иное, функции в API работают с приемлемыми индексами.
Приемлемые индексы служат для избежания дополнительных проверок вершины стека при запросе стека. Например, функция C может запросить свой третий аргумент без необходимости проверять, существует ли третий аргумент, то есть без необходимости проверять, является ли 3 допустимым индексом.
Для функций, которые могут вызываться с приемлемыми индексами, любой недопустимый индекс обрабатывается так, как если бы он содержал значение виртуального типа LUA_TNONE, которое ведет себя как значение nil.
4.1.3 – Указатели на строки
Несколько функций в API возвращают указатели (const char*) на строки Lua в стеке. (См. lua_pushfstring, lua_pushlstring, lua_pushstring и lua_tolstring. См. также luaL_checklstring, luaL_checkstring и luaL_tolstring во вспомогательной библиотеке.)
В общем случае сборщик мусора Lua может освобождать или перемещать память и, таким образом, делать недействительными указатели на строки, обрабатываемые состоянием Lua. Чтобы обеспечить безопасное использование этих указателей, API гарантирует, что любой указатель на строку в индексе стека действителен, пока строковое значение по этому индексу не удалено из стека. (Однако оно может быть перемещено на другой индекс). Когда индекс является псевдоиндексом (ссылающимся на upvalue), указатель действителен, пока активен соответствующий вызов и соответствующее upvalue не изменено.
Некоторые функции в отладочном интерфейсе также возвращают указатели на строки, а именно lua_getlocal, lua_getupvalue, lua_setlocal и lua_setupvalue. Для этих функций гарантируется, что указатель действителен, пока активна функция-вызыватель и данное замыкание (если оно было дано) находится в стеке.
За исключением этих гарантий, сборщик мусора может свободно делать недействительным любой указатель на внутренние строки.
4.2 – Замыкания C
При создании функции C с ней можно связать некоторые значения, создавая таким образом замыкание C (C closure) (см. lua_pushcclosure); эти значения называются upvalue и доступны функции при каждом ее вызове.
Всякий раз, когда вызывается функция C, ее upvalue располагаются по определенным псевдоиндексам. Эти псевдоиндексы создаются макросом lua_upvalueindex. Первое upvalue, связанное с функцией, находится по индексу lua_upvalueindex(1), и так далее. Любой доступ к lua_upvalueindex(n), где n больше количества upvalue текущей функции (но не больше 256, что на единицу больше максимального количества upvalue в замыкании), дает приемлемый, но недопустимый индекс.
Замыкание C также может изменять значения своих соответствующих upvalue.
4.3 – Реестр
Lua предоставляет реестр (registry) — предопределенную таблицу, которая может использоваться любым кодом C для хранения любых значений Lua, которые ему необходимо сохранить. Таблица реестра всегда доступна по псевдоиндексу LUA_REGISTRYINDEX. Любая библиотека C может хранить данные в этой таблице, но она должна позаботиться о выборе ключей, отличных от тех, что используются другими библиотеками, чтобы избежать коллизий. Обычно в качестве ключа следует использовать строку, содержащую имя вашей библиотеки, или легкий userdata с адресом объекта C в вашем коде, или любой объект Lua, созданный вашим кодом. Как и в случае с именами переменных, строковые ключи, начинающиеся с подчеркивания, за которым следуют заглавные буквы, зарезервированы для Lua.
Целочисленные ключи в реестре используются механизмом ссылок (см. luaL_ref) и имеют некоторые предопределенные значения. Поэтому целочисленные ключи в реестре не должны использоваться для других целей.
При создании нового состояния Lua его реестр содержит некоторые предопределенные значения. Эти предопределенные значения индексируются целочисленными ключами, определенными как константы в lua.h. Определены следующие константы:
LUA_RIDX_MAINTHREAD: По этому индексу в реестре находится главный поток состояния. (Главный поток — это тот, который создается вместе с состоянием).LUA_RIDX_GLOBALS: По этому индексу в реестре находится глобальное окружение.
4.4 – Обработка ошибок в C
Внутренне Lua использует средство C longjmp для обработки ошибок. (Lua будет использовать исключения, если вы компилируете его как C++; подробности ищите в исходном коде по LUAI_THROW). Когда Lua сталкивается с какой-либо ошибкой, такой как ошибка выделения памяти или ошибка типа, он возбуждает ошибку (raises an error); то есть выполняет длинный переход (long jump). Защищенное окружение использует setjmp для установки точки восстановления; любая ошибка переходит к самой последней активной точке восстановления.
Внутри функции C вы можете явно возбудить ошибку, вызвав lua_error.
Большинство функций в API могут возбуждать ошибки, например, из-за ошибки выделения памяти. Документация для каждой функции указывает, может ли она возбуждать ошибки.
Если ошибка происходит вне любого защищенного окружения, Lua вызывает функцию паники (panic function) (см. lua_atpanic), а затем вызывает abort, завершая таким образом хостовое приложение. Ваша функция паники может избежать этого завершения, никогда не возвращаясь (например, выполняя длинный переход к вашей собственной точке восстановления вне Lua).
Функция паники, как следует из ее названия, является механизмом “последней надежды”. Программы должны избегать ее. Как общее правило, когда функция C вызывается из Lua с состоянием Lua, она может делать с этим состоянием все, что угодно, так как оно уже должно быть защищено. Однако когда код C работает с другими состояниями Lua (например, аргумент-состояние Lua для функции, состояние Lua, сохраненное в реестре, или результат lua_newthread), он должен использовать их только в вызовах API, которые не могут возбуждать ошибки.
Функция паники работает так, как если бы она была обработчиком сообщений (см. §2.3); в частности, объект ошибки находится на вершине стека. Однако нет никаких гарантий относительно пространства стека. Чтобы поместить что-либо в стек, функция паники должна сначала проверить доступное пространство (см. §4.1.1).
4.4.1 – Коды состояния
Некоторые функции, сообщающие об ошибках в API, используют следующие коды состояния для указания различных видов ошибок или других условий:
LUA_OK(0): нет ошибок.LUA_ERRRUN: ошибка времени выполнения.LUA_ERRMEM: ошибка выделения памяти. Для таких ошибок Lua не вызывает обработчик сообщений.LUA_ERRERR: переполнение стека при выполнении обработчика сообщений из-за другого переполнения стека. Чаще всего эта ошибка является результатом какой-либо другой ошибки во время выполнения обработчика сообщений. Ошибка в обработчике сообщений вызовет обработчик снова, что снова сгенерирует ошибку, и так далее, пока этот цикл не исчерпает стек и не вызовет эту ошибку.LUA_ERRSYNTAX: синтаксическая ошибка во время предкомпиляции или ошибка формата в двоичном чанке.LUA_YIELD: поток (сопрограмма) выполняет yield.LUA_ERRFILE: ошибка, связанная с файлом; например, невозможно открыть или прочитать файл.
Эти константы определены в заголовочном файле lua.h.
4.5 – Обработка yield в C
Внутренне Lua использует средство C longjmp для выполнения yield в сопрограмме. Следовательно, если функция C foo вызывает функцию API, и эта функция API выполняет yield (прямо или косвенно, вызывая другую функцию, которая выполняет yield), Lua больше не может вернуться в foo, потому что longjmp удаляет ее фрейм из стека C.
Чтобы избежать подобной проблемы, Lua возбуждает ошибку всякий раз, когда пытается выполнить yield через вызов API, за исключением трех функций: lua_yieldk, lua_callk и lua_pcallk. Все эти функции получают функцию продолжения (continuation function) (в качестве параметра с именем k) для продолжения выполнения после yield.
Нам необходимо установить некоторую терминологию для объяснения продолжений. У нас есть функция C, вызванная из Lua, которую мы будем называть исходной функцией (original function). Эта исходная функция затем вызывает одну из этих трех функций в C API, которую мы будем называть вызываемой функцией (callee function), которая затем выполняет yield текущего потока. Это может произойти, когда вызываемая функция — lua_yieldk, или когда вызываемая функция — lua_callk либо lua_pcallk, и функция, вызываемая ими, выполняет yield.
Предположим, что выполняющийся поток делает yield во время выполнения вызываемой функции. После возобновления потока он в конечном итоге завершит выполнение вызываемой функции. Однако вызываемая функция не может вернуться в исходную функцию, потому что ее фрейм в стеке C был уничтожен при yield. Вместо этого Lua вызывает функцию продолжения, которая была передана в качестве аргумента вызываемой функции. Как следует из названия, функция продолжения должна продолжить задачу исходной функции.
В качестве иллюстрации рассмотрим следующую функцию:
int original_function (lua_State *L) {
... /* код 1 */
status = lua_pcall(L, n, m, h); /* вызывает Lua */
... /* код 2 */
}
Теперь мы хотим позволить коду Lua, выполняемому lua_pcall, делать yield. Во-первых, мы можем переписать нашу функцию следующим образом:
int k (lua_State *L, int status, lua_KContext ctx) {
... /* код 2 */
}
int original_function (lua_State *L) {
... /* код 1 */
return k(L, lua_pcall(L, n, m, h), ctx);
}
В приведенном выше коде новая функция k является функцией продолжения (с типом lua_KFunction), которая должна выполнять всю ту работу, которую исходная функция выполняла после вызова lua_pcall. Теперь мы должны сообщить Lua, что он должен вызвать k, если код Lua, выполняемый lua_pcall, будет прерван каким-либо образом (ошибки или yield), поэтому мы переписываем код следующим образом, заменяя lua_pcall на lua_pcallk:
int original_function (lua_State *L) {
... /* код 1 */
return k(L, lua_pcallk(L, n, m, h, ctx2, k), ctx1);
}
Обратите внимание на внешний явный вызов продолжения: Lua вызовет продолжение только при необходимости, то есть в случае ошибок или возобновления после yield. Если вызываемая функция возвращается нормально, ни разу не выполнив yield, lua_pcallk (и lua_callk) также вернется нормально. (Конечно, вместо вызова продолжения в этом случае вы можете выполнить эквивалентную работу непосредственно внутри исходной функции).
Помимо состояния Lua, функция продолжения имеет два других параметра: окончательный статус вызова и значение контекста (ctx), которое было изначально передано в lua_pcallk. Lua не использует это значение контекста; он только передает это значение от исходной функции к функции продолжения. Для lua_pcallk статус — это то же значение, которое было бы возвращено lua_pcallk, за исключением того, что это LUA_YIELD при выполнении после yield (вместо LUA_OK). Для lua_yieldk и lua_callk статус всегда LUA_YIELD, когда Lua вызывает продолжение. (Для этих двух функций Lua не будет вызывать продолжение в случае ошибок, потому что они не обрабатывают ошибки). Аналогично, при использовании lua_callk вы должны вызвать функцию продолжения с LUA_OK в качестве статуса. (Для lua_yieldk нет особого смысла вызывать функцию продолжения напрямую, потому что lua_yieldk обычно не возвращается).
Lua обрабатывает функцию продолжения так, как если бы она была исходной функцией. Функция продолжения получает тот же стек Lua от исходной функции, в том же состоянии, в котором он был бы, если бы вызываемая функция вернулась. (Например, после lua_callk функция и ее аргументы удаляются из стека и заменяются результатами вызова). Она также имеет те же upvalue. Все, что она возвращает, обрабатывается Lua так, как если бы это был возврат исходной функции.
4.6 – Функции и типы
Здесь мы перечисляем все функции и типы из C API в алфавитном порядке. Каждая функция имеет индикатор вида: [-o, +p, x]
Первое поле, o, — сколько элементов функция извлекает из стека. Второе поле, p, — сколько элементов функция помещает в стек. (Любая функция всегда помещает свои результаты после извлечения своих аргументов.) Поле вида x|y означает, что функция может поместить (или извлечь) x или y элементов, в зависимости от ситуации; знак вопроса '?' означает, что мы не можем узнать, сколько элементов функция извлекает/помещает, глядя только на ее аргументы. (Например, это может зависеть от того, что находится в стеке). Третье поле, x, сообщает, может ли функция возбуждать ошибки: '-' означает, что функция никогда не возбуждает ошибок; 'm' означает, что функция может возбуждать только ошибки нехватки памяти; 'v' означает, что функция может возбуждать ошибки, объясненные в тексте; 'e' означает, что функция может выполнять произвольный код Lua, либо напрямую, либо через метаметоды, и поэтому может возбуждать любые ошибки.
lua_absindex
[-0, +0, –]
int lua_absindex (lua_State *L, int idx);
Преобразует приемлемый индекс idx в эквивалентный абсолютный индекс (то есть такой, который не зависит от размера стека).
lua_Alloc
typedef void * (*lua_Alloc) (void *ud,
void *ptr,
size_t osize,
size_t nsize);
Тип функции распределения памяти, используемой состояниями Lua. Функция-аллокатор должна обеспечивать функциональность, аналогичную realloc, но не точно такую же. Ее аргументы: ud — непрозрачный указатель, переданный в lua_newstate; ptr — указатель на выделяемый/перераспределяемый/освобождаемый блок; osize — исходный размер блока или некоторый код о том, что выделяется; и nsize — новый размер блока.
Когда ptr не равен NULL, osize — это размер блока, на который указывает ptr, то есть размер, указанный при его выделении или перераспределении.
Когда ptr равен NULL, osize кодирует тип объекта, который Lua выделяет. osize равен LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA или LUA_TTHREAD, когда (и только когда) Lua создает новый объект этого типа. Когда osize имеет какое-либо другое значение, Lua выделяет память для чего-то другого.
Lua предполагает следующее поведение от функции-аллокатора:
Когда nsize равно нулю, аллокатор должен вести себя как free и затем возвращать NULL.
Когда nsize не равно нулю, аллокатор должен вести себя как realloc. В частности, аллокатор возвращает NULL тогда и только тогда, когда он не может выполнить запрос.
Вот простая реализация функции-аллокатора, соответствующая функции luaL_alloc из вспомогательной библиотеки.
void *luaL_alloc (void *ud, void *ptr, size_t osize,
size_t nsize) {
(void)ud; (void)osize; /* не используется */
if (nsize == 0) {
free(ptr);
return NULL;
}
else
return realloc(ptr, nsize);
}
Обратите внимание, что стандарт ISO C гарантирует, что free(NULL) не имеет эффекта, и что realloc(NULL,size) эквивалентно malloc(size).
lua_arith
[-(2|1), +1, e]
void lua_arith (lua_State *L, int op);
Выполняет арифметическую или побитовую операцию над двумя значениями (или одним, в случае отрицаний) на вершине стека, при этом значение на вершине является вторым операндом, извлекает эти значения и помещает результат операции в стек. Функция следует семантике соответствующего оператора Lua (то есть может вызывать метаметоды).
Значение op должно быть одной из следующих констант:
| Константа | Операция |
|---|---|
LUA_OPADD | сложение (+) |
LUA_OPSUB | вычитание (-) |
LUA_OPMUL | умножение (*) |
LUA_OPDIV | деление с плавающей запятой (/) |
LUA_OPIDIV | деление нацело вниз (//) |
LUA_OPMOD | остаток от деления (%) |
LUA_OPPOW | возведение в степень (^) |
LUA_OPUNM | унарный минус (унарный -) |
LUA_OPBNOT | побитовое НЕ (~) |
LUA_OPBAND | побитовое И (&) |
LUA_OPBOR | побитовое ИЛИ (|) |
LUA_OPBXOR | побитовое исключающее ИЛИ (~) |
LUA_OPSHL | сдвиг влево (<<) |
LUA_OPSHR | сдвиг вправо (>>) |
lua_atpanic
[-0, +0, –]
lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
Устанавливает новую функцию паники и возвращает старую (см. §4.4).
lua_call
[-(nargs+1), +nresults, e]
void lua_call (lua_State *L, int nargs, int nresults);
Вызывает функцию. Как и обычные вызовы Lua, lua_call учитывает метаметод __call. Таким образом, здесь слово “функция” означает любое вызываемое значение.
Для выполнения вызова необходимо использовать следующий протокол: сначала функция, которую нужно вызвать, помещается в стек; затем аргументы вызова помещаются в прямом порядке, то есть первый аргумент помещается первым. Наконец, вы вызываете lua_call; nargs — это количество аргументов, которое вы поместили в стек. Когда функция возвращается, все аргументы и значение функции извлекаются, а результаты вызова помещаются в стек. Количество результатов выравнивается до nresults, если только nresults не равно LUA_MULTRET, что приводит к помещению всех результатов функции. В первом случае (явное количество результатов) вызывающая сторона должна убедиться, что в стеке достаточно места для возвращаемых значений. Во втором случае (все результаты) Lua заботится о том, чтобы возвращаемые значения поместились в пространство стека, но не гарантирует никакого дополнительного места в стеке. Результаты функции помещаются в стек в прямом порядке (первый результат помещается первым), так что после вызова последний результат находится на вершине стека.
Максимальное значение для nresults — 250.
Любая ошибка при вызове и выполнении функции распространяется вверх (с помощью longjmp).
Следующий пример показывает, как программа-хост может выполнить эквивалент этого кода Lua:
a = f("how", t.x, 14)
Вот это на C:
lua_getglobal(L, "f"); /* функция для вызова */
lua_pushliteral(L, "how"); /* 1-й аргумент */
lua_getglobal(L, "t"); /* таблица для индексации */
lua_getfield(L, -1, "x"); /* поместить результат t.x (2-й аргумент) */
lua_remove(L, -2); /* удалить 't' из стека */
lua_pushinteger(L, 14); /* 3-й аргумент */
lua_call(L, 3, 1); /* вызвать 'f' с 3 аргументами и 1 результатом */
lua_setglobal(L, "a"); /* установить глобальную 'a' */
Обратите внимание, что приведенный выше код сбалансирован: в конце стек возвращается к своей исходной конфигурации. Это считается хорошей практикой программирования.
lua_callk
[-(nargs + 1), +nresults, e]
void lua_callk (lua_State *L,
int nargs,
int nresults,
lua_KContext ctx,
lua_KFunction k);
Эта функция ведет себя точно так же, как lua_call, но позволяет вызываемой функции выполнять yield (см. §4.5).
lua_CFunction
typedef int (*lua_CFunction) (lua_State *L);
Тип для функций C.
Чтобы правильно взаимодействовать с Lua, функция C должна использовать следующий протокол, который определяет способ передачи параметров и результатов: функция C получает свои аргументы от Lua в своем стеке в прямом порядке (первый аргумент помещается первым). Таким образом, когда функция запускается, lua_gettop(L) возвращает количество аргументов, полученных функцией. Первый аргумент (если есть) находится по индексу 1, а последний аргумент — по индексу lua_gettop(L). Чтобы вернуть значения в Lua, функция C просто помещает их в стек в прямом порядке (первый результат помещается первым) и возвращает в C количество результатов. Любые другие значения в стеке ниже результатов будут корректно отброшены Lua. Как и функция Lua, функция C, вызванная из Lua, также может возвращать много результатов.
В качестве примера, следующая функция получает переменное количество числовых аргументов и возвращает их среднее значение и сумму:
static int foo (lua_State *L) {
int n = lua_gettop(L); /* количество аргументов */
lua_Number sum = 0.0;
int i;
for (i = 1; i <= n; i++) {
if (!lua_isnumber(L, i)) {
lua_pushliteral(L, "неверный аргумент");
lua_error(L);
}
sum += lua_tonumber(L, i);
}
lua_pushnumber(L, sum/n); /* первый результат */
lua_pushnumber(L, sum); /* второй результат */
return 2; /* количество результатов */
}
lua_checkstack
[-0, +0, –]
int lua_checkstack (lua_State *L, int n);
Гарантирует, что в стеке есть место как минимум для n дополнительных элементов, то есть что вы можете безопасно поместить в него до n значений. Возвращает false, если не может выполнить запрос, либо потому, что это привело бы к превышению фиксированного максимального размера стека (обычно не менее нескольких тысяч элементов), либо потому, что не может выделить память для дополнительного пространства. Эта функция никогда не уменьшает стек; если в стеке уже есть место для дополнительных элементов, он остается без изменений.
lua_close
[-0, +0, –]
void lua_close (lua_State *L);
Закрывает все активные закрываемые переменные (to-be-closed variables) в главном потоке, освобождает все объекты в данном состоянии Lua (вызывая соответствующие метаметоды сборки мусора, если таковые имеются) и освобождает всю динамическую память, используемую этим состоянием.
На некоторых платформах вам может не потребоваться вызывать эту функцию, потому что все ресурсы естественным образом освобождаются при завершении программы-хоста. С другой стороны, долго работающим программам, создающим несколько состояний, таким как демоны или веб-серверы, вероятно, потребуется закрывать состояния, как только они становятся ненужными.
lua_closeslot
[-0, +0, e]
void lua_closeslot (lua_State *L, int index);
Закрывает закрываемый слот (to-be-closed slot) по заданному индексу и устанавливает его значение в nil. Индекс должен быть последним индексом, ранее отмеченным для закрытия (см. lua_toclose), который все еще активен (то есть еще не закрыт).
Метаметод __close не может выполнять yield при вызове через эту функцию.
lua_closethread
[-0, +?, –]
int lua_closethread (lua_State *L, lua_State *from);
Сбрасывает поток, очищая его стек вызовов и закрывая все ожидающие закрываемые переменные. Параметр from представляет сопрограмму, которая сбрасывает L. Если такой сопрограммы нет, этот параметр может быть NULL.
Если L не равен from, вызов возвращает код состояния: LUA_OK при отсутствии ошибок в потоке (либо исходная ошибка, остановившая поток, либо ошибки в методах закрытия), или статус ошибки в противном случае. В случае ошибки объект ошибки помещается на вершину стека.
Если L равен from, это соответствует потоку, закрывающему сам себя. В этом случае вызов не возвращается; вместо этого возвращается resume, который (пере)запустил поток. Поток должен выполняться внутри resume.
lua_compare
[-0, +0, e]
int lua_compare (lua_State *L, int index1, int index2, int op);
Сравнивает два значения Lua. Возвращает 1, если значение по индексу index1 удовлетворяет условию op при сравнении со значением по индексу index2, следуя семантике соответствующего оператора Lua (то есть может вызывать метаметоды). В противном случае возвращает 0. Также возвращает 0, если какой-либо из индексов недействителен.
Значение op должно быть одной из следующих констант:
LUA_OPEQ: сравнение на равенство (==)LUA_OPLT: сравнение на меньше (<)LUA_OPLE: сравнение на меньше или равно (<=)
lua_concat
[-n, +1, e]
void lua_concat (lua_State *L, int n);
Конкатенирует n значений на вершине стека, извлекает их и оставляет результат на вершине. Если n равно 1, результатом является единственное значение в стеке (то есть функция ничего не делает); если n равно 0, результатом является пустая строка. Конкатенация выполняется в соответствии с обычной семантикой Lua (см. §3.4.6).
lua_copy
[-0, +0, –]
void lua_copy (lua_State *L, int fromidx, int toidx);
Копирует элемент по индексу fromidx в допустимый индекс toidx, заменяя значение в этой позиции. Значения в других позициях не затрагиваются.
lua_createtable
[-0, +1, m]
void lua_createtable (lua_State *L, int nseq, int nrec);
Создает новую пустую таблицу и помещает ее в стек. Параметр nseq — это подсказка о том, сколько элементов таблица будет иметь в качестве последовательности; параметр nrec — подсказка о том, сколько других элементов будет иметь таблица. Lua может использовать эти подсказки для предварительного выделения памяти для новой таблицы. Это предварительное выделение может помочь производительности, когда вы заранее знаете, сколько элементов будет в таблице. В противном случае следует использовать функцию lua_newtable.
lua_dump
[-0, +0, –]
int lua_dump (lua_State *L,
lua_Writer writer,
void *data,
int strip);
Дамп функции в виде двоичного чанка. Получает функцию Lua на вершине стека и создает двоичный чанк, который, будучи загруженным снова, дает функцию, эквивалентную дампнутой. По мере создания частей чанка lua_dump вызывает функцию writer (см. lua_Writer) с заданными data для их записи.
Функция lua_dump полностью сохраняет стек Lua при вызовах функции-писателя, за исключением того, что она может поместить некоторые значения для внутреннего использования перед первым вызовом и восстанавливает размер стека до исходного после последнего вызова.
Если strip истинно, двоичное представление может не включать всю отладочную информацию о функции для экономии места.
Возвращаемое значение — это код ошибки, возвращенный последним вызовом writer; 0 означает отсутствие ошибок.
lua_error
[-1, +0, v]
int lua_error (lua_State *L);
Возбуждает ошибку Lua, используя значение на вершине стека в качестве объекта ошибки. Эта функция выполняет длинный переход и, следовательно, никогда не возвращается (см. luaL_error).
lua_gc
[-0, +0, –]
int lua_gc (lua_State *L, int what, ...);
Управляет сборщиком мусора.
Эта функция выполняет несколько задач в зависимости от значения параметра what. Для опций, требующих дополнительных аргументов, они перечислены после опции.
LUA_GCCOLLECT: Выполняет полный цикл сборки мусора.LUA_GCSTOP: Останавливает сборщик мусора.LUA_GCRESTART: Перезапускает сборщик мусора.LUA_GCCOUNT: Возвращает текущий объем памяти (в Кбайтах), используемый Lua.LUA_GCCOUNTB: Возвращает остаток от деления текущего объема памяти в байтах, используемого Lua, на 1024.LUA_GCSTEP(size_t n): Выполняет шаг сборки мусора.LUA_GCISRUNNING: Возвращает булево значение, указывающее, работает ли сборщик (т.е. не остановлен).LUA_GCINC: Переключает сборщик в инкрементальный режим. Возвращает предыдущий режим (LUA_GCGENилиLUA_GCINC).LUA_GCGEN: Переключает сборщик в поколенческий режим. Возвращает предыдущий режим (LUA_GCGENилиLUA_GCINC).LUA_GCPARAM(int param, int val): Изменяет и/или возвращает значение параметра сборщика. Еслиvalравно -1, вызов только возвращает текущее значение. Аргументparamдолжен иметь одно из следующих значений:LUA_GCPMINORMUL: Множитель minor.LUA_GCPMAJORMINOR: Множитель major-minor.LUA_GCPMINORMAJOR: Множитель minor-major.LUA_GCPPAUSE: Пауза сборщика мусора.LUA_GCPSTEPMUL: Множитель шага.LUA_GCPSTEPSIZE: Размер шага.
Для получения более подробной информации об этих опциях см. collectgarbage.
Эта функция не должна вызываться финализатором.
lua_getallocf
[-0, +0, –]
lua_Alloc lua_getallocf (lua_State *L, void **ud);
Возвращает функцию-аллокатор памяти для данного состояния. Если ud не NULL, Lua сохраняет в *ud непрозрачный указатель, переданный при установке функции-аллокатора.
lua_getfield
[-0, +1, e]
int lua_getfield (lua_State *L, int index, const char *k);
Помещает в стек значение t[k], где t — это значение по заданному индексу. Как и в Lua, эта функция может вызвать метаметод для события “index” (см. §2.4).
Возвращает тип помещенного значения.
lua_getextraspace
[-0, +0, –]
void *lua_getextraspace (lua_State *L);
Возвращает указатель на область сырой памяти, связанную с данным состоянием Lua. Приложение может использовать эту область для любых целей; Lua не использует ее ни для чего.
Каждый новый поток имеет эту область, инициализированную копией области главного потока.
По умолчанию эта область имеет размер указателя на void, но вы можете перекомпилировать Lua с другим размером для этой области. (См. LUA_EXTRASPACE в luaconf.h).
lua_getglobal
[-0, +1, e]
int lua_getglobal (lua_State *L, const char *name);
Помещает в стек значение глобальной переменной name. Возвращает тип этого значения.
lua_geti
[-0, +1, e]
int lua_geti (lua_State *L, int index, lua_Integer i);
Помещает в стек значение t[i], где t — это значение по заданному индексу. Как и в Lua, эта функция может вызвать метаметод для события “index” (см. §2.4).
Возвращает тип помещенного значения.
lua_getmetatable
[-0, +(0|1), –]
int lua_getmetatable (lua_State *L, int index);
Если значение по заданному индексу имеет метатаблицу, функция помещает эту метатаблицу в стек и возвращает 1. В противном случае функция возвращает 0 и ничего не помещает в стек.
lua_gettable
[-1, +1, e]
int lua_gettable (lua_State *L, int index);
Помещает в стек значение t[k], где t — это значение по заданному индексу, а k — значение на вершине стека.
Эта функция извлекает ключ из стека, помещая результирующее значение на его место. Как и в Lua, эта функция может вызвать метаметод для события “index” (см. §2.4).
Возвращает тип помещенного значения.
lua_gettop
[-0, +0, –]
int lua_gettop (lua_State *L);
Возвращает индекс верхнего элемента в стеке. Поскольку индексы начинаются с 1, этот результат равен количеству элементов в стеке; в частности, 0 означает пустой стек.
lua_getiuservalue
[-0, +1, –]
int lua_getiuservalue (lua_State *L, int index, int n);
Помещает в стек n-е пользовательское значение (user value), связанное с полным userdata по заданному индексу, и возвращает тип помещенного значения.
Если userdata не имеет такого значения, помещает nil и возвращает LUA_TNONE.
lua_insert
[-1, +1, –]
void lua_insert (lua_State *L, int index);
Перемещает верхний элемент в заданный допустимый индекс, сдвигая вверх элементы над этим индексом для освобождения места. Эта функция не может вызываться с псевдоиндексом, поскольку псевдоиндекс не является фактической позицией в стеке.
lua_Integer
typedef ... lua_Integer;
Тип целых чисел в Lua.
По умолчанию этот тип — long long (обычно 64-битное целое число в дополнительном коде), но его можно изменить на long или int (обычно 32-битное целое число в дополнительном коде). (См. LUA_INT_TYPE в luaconf.h).
Lua также определяет константы LUA_MININTEGER и LUA_MAXINTEGER с минимальным и максимальным значениями, которые помещаются в этот тип.
lua_isboolean
[-0, +0, –]
int lua_isboolean (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является булевым, и 0 в противном случае.
lua_iscfunction
[-0, +0, –]
int lua_iscfunction (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является функцией C, и 0 в противном случае.
lua_isfunction
[-0, +0, –]
int lua_isfunction (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является функцией (либо C, либо Lua), и 0 в противном случае.
lua_isinteger
[-0, +0, –]
int lua_isinteger (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является целым числом (то есть значение является числом и представлено как целое), и 0 в противном случае.
lua_islightuserdata
[-0, +0, –]
int lua_islightuserdata (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является легким userdata, и 0 в противном случае.
lua_isnil
[-0, +0, –]
int lua_isnil (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу равно nil, и 0 в противном случае.
lua_isnone
[-0, +0, –]
int lua_isnone (lua_State *L, int index);
Возвращает 1, если заданный индекс недействителен, и 0 в противном случае.
lua_isnoneornil
[-0, +0, –]
int lua_isnoneornil (lua_State *L, int index);
Возвращает 1, если заданный индекс недействителен или если значение по этому индексу равно nil, и 0 в противном случае.
lua_isnumber
[-0, +0, –]
int lua_isnumber (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является числом или строкой, преобразуемой в число, и 0 в противном случае.
lua_isstring
[-0, +0, –]
int lua_isstring (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является строкой или числом (которое всегда можно преобразовать в строку), и 0 в противном случае.
lua_istable
[-0, +0, –]
int lua_istable (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является таблицей, и 0 в противном случае.
lua_isthread
[-0, +0, –]
int lua_isthread (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является потоком, и 0 в противном случае.
lua_isuserdata
[-0, +0, –]
int lua_isuserdata (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является userdata (полным или легким), и 0 в противном случае.
lua_isyieldable
[-0, +0, –]
int lua_isyieldable (lua_State *L);
Возвращает 1, если данная сопрограмма может выполнить yield, и 0 в противном случае.
lua_KContext
typedef ... lua_KContext;
Тип для контекстов функций продолжения. Должен быть числовым типом. Этот тип определен как intptr_t, когда intptr_t доступен, чтобы он мог хранить и указатели. В противном случае он определен как ptrdiff_t.
lua_KFunction
typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);
Тип для функций продолжения (см. §4.5).
lua_len
[-0, +1, e]
void lua_len (lua_State *L, int index);
Возвращает длину значения по заданному индексу. Эквивалентно оператору # в Lua (см. §3.4.7) и может вызвать метаметод для события “length” (см. §2.4). Результат помещается в стек.
lua_load
[-0, +1, –]
int lua_load (lua_State *L,
lua_Reader reader,
void *data,
const char *chunkname,
const char *mode);
Загружает чанк Lua без его выполнения. Если ошибок нет, lua_load помещает скомпилированный чанк как функцию Lua на вершину стека. В противном случае она помещает сообщение об ошибке.
Функция lua_load использует предоставленную пользователем функцию-читатель (reader) для чтения чанка (см. lua_Reader). Аргумент data — это непрозрачное значение, передаваемое в функцию-читатель.
Аргумент chunkname дает имя чанку, которое используется для сообщений об ошибках и в отладочной информации (см. §4.7).
lua_load автоматически определяет, является ли чанк текстовым или двоичным, и загружает его соответствующим образом (см. программу luac). Строка mode работает как в функции load, с тем дополнением, что значение NULL эквивалентно строке "bt". Более того, она может содержать 'B' вместо 'b', что означает фиксированный буфер (fixed buffer) с двоичным дампом.
Фиксированный буфер означает, что адрес, возвращаемый функцией-читателем, будет содержать чанк до тех пор, пока все, созданное чанком, не будет собрано сборщиком мусора; таким образом, Lua может избежать копирования некоторых частей чанка во внутренние структуры. (В общем случае фиксированный буфер будет сохранять свое содержимое до конца программы, например, при чанке в ПЗУ). Более того, для фиксированного буфера функция-читатель должна вернуть весь чанк при первом чтении. (В качестве примера, luaL_loadbufferx делает это, что означает, что вы можете использовать ее для загрузки фиксированных буферов).
Функция lua_load полностью сохраняет стек Lua при вызовах функции-читателя, за исключением того, что она может поместить некоторые значения для внутреннего использования перед первым вызовом и восстанавливает размер стека до исходного размера плюс один (для помещенного результата) после последнего вызова.
lua_load может возвращать LUA_OK, LUA_ERRSYNTAX или LUA_ERRMEM. Функция также может возвращать другие значения, соответствующие ошибкам, возбужденным функцией чтения (см. §4.4.1).
Если результирующая функция имеет upvalue, ее первое upvalue устанавливается в значение глобального окружения, хранящееся по индексу LUA_RIDX_GLOBALS в реестре (см. §4.3). При загрузке главных чанков этим upvalue будет переменная _ENV (см. §2.2). Остальные upvalue инициализируются значением nil.
lua_newstate
[-0, +0, –]
lua_State *lua_newstate (lua_Alloc f, void *ud,
unsigned int seed);
Создает новое независимое состояние и возвращает его главный поток. Возвращает NULL, если не может создать состояние (из-за нехватки памяти). Аргумент f — это функция-аллокатор; Lua будет выполнять все выделение памяти для этого состояния через эту функцию (см. lua_Alloc). Второй аргумент, ud, — непрозрачный указатель, который Lua передает аллокатору при каждом вызове. Третий аргумент, seed, — это начальное значение для хеширования строк.
lua_newtable
[-0, +1, m]
void lua_newtable (lua_State *L);
Создает новую пустую таблицу и помещает ее в стек. Эквивалентно lua_createtable(L,0,0).
lua_newthread
[-0, +1, m]
lua_State *lua_newthread (lua_State *L);
Создает новый поток, помещает его в стек и возвращает указатель на lua_State, представляющий этот новый поток. Новый поток, возвращаемый этой функцией, разделяет с исходным потоком его глобальное окружение, но имеет независимый стек выполнения.
Потоки подлежат сборке мусора, как и любой объект Lua.
lua_newuserdatauv
[-0, +1, m]
void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue);
Эта функция создает и помещает в стек новый полный userdata с nuvalue связанными значениями Lua, называемыми пользовательскими значениями (user values), плюс связанный блок сырой памяти размером size байт. (Пользовательские значения можно устанавливать и читать с помощью функций lua_setiuservalue и lua_getiuservalue).
Функция возвращает адрес блока памяти. Lua гарантирует, что этот адрес действителен, пока соответствующий userdata жив (см. §2.5). Более того, если userdata помечен для финализации (см. §2.5.3), его адрес действителен по крайней мере до вызова его финализатора.
lua_next
[-1, +(2|0), v]
int lua_next (lua_State *L, int index);
Извлекает ключ из стека и помещает пару ключ-значение из таблицы по заданному индексу — “следующую” пару после данного ключа. Если в таблице больше нет элементов, lua_next возвращает 0 и ничего не помещает.
Типичный обход таблицы выглядит так:
/* таблица находится в стеке по индексу 't' */
lua_pushnil(L); /* первый ключ */
while (lua_next(L, t) != 0) {
/* используем 'key' (по индексу -2) и 'value' (по индексу -1) */
printf("%s - %s\n",
lua_typename(L, lua_type(L, -2)),
lua_typename(L, lua_type(L, -1)));
/* удаляем 'value'; сохраняем 'key' для следующей итерации */
lua_pop(L, 1);
}
При обходе таблицы избегайте вызова lua_tolstring непосредственно для ключа, если вы не уверены, что ключ действительно является строкой. Напомним, что lua_tolstring может изменить значение по заданному индексу; это собьет следующий вызов lua_next.
Эта функция может возбудить ошибку, если данный ключ не равен nil и не присутствует в таблице. См. функцию next для предостережений относительно модификации таблицы во время ее обхода.
lua_Number
typedef ... lua_Number;
Тип чисел с плавающей запятой в Lua.
По умолчанию этот тип — double, но его можно изменить на float или long double. (См. LUA_FLOAT_TYPE в luaconf.h).
lua_numbertointeger
int lua_numbertointeger (lua_Number n, lua_Integer *p);
Пытается преобразовать число Lua с плавающей запятой в целое число Lua; число n должно иметь целое значение. Если это значение находится в диапазоне целых чисел Lua, оно преобразуется в целое и присваивается *p. Макрос возвращает булево значение, указывающее, было ли преобразование успешным. (Обратите внимание, что эту проверку диапазона трудно выполнить корректно без этого макроса из-за округления).
Этот макрос может вычислять свои аргументы более одного раза.
lua_numbertocstring
[-0, +0, –]
unsigned lua_numbertocstring (lua_State *L, int idx,
char *buff);
Преобразует число по приемлемому индексу idx в строку и помещает результат в buff. Буфер должен иметь размер не менее LUA_N2SBUFFSZ байт. Преобразование следует неуказанному формату (см. §3.4.3). Функция возвращает количество байт, записанных в буфер (включая завершающий ноль), или ноль, если значение по idx не является числом.
lua_pcall
[-(nargs + 1), +(nresults|1), –]
int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);
Вызывает функцию (или вызываемый объект) в защищенном режиме.
И nargs, и nresults имеют то же значение, что и в lua_call. Если во время вызова нет ошибок, lua_pcall ведет себя точно так же, как lua_call. Однако, если возникает какая-либо ошибка, lua_pcall перехватывает ее, помещает в стек единственное значение (объект ошибки) и возвращает код ошибки. Как и lua_call, lua_pcall всегда удаляет функцию и ее аргументы из стека.
Если msgh равно 0, то объект ошибки, возвращаемый в стеке, является в точности исходным объектом ошибки. В противном случае msgh — это индекс в стеке обработчика сообщений. (Этот индекс не может быть псевдоиндексом). В случае ошибок времени выполнения этот обработчик будет вызван с объектом ошибки, и его возвращаемое значение будет объектом, возвращенным в стеке функцией lua_pcall.
Обычно обработчик сообщений используется для добавления дополнительной отладочной информации к объекту ошибки, такой как трассировка стека. Такую информацию невозможно собрать после возврата lua_pcall, поскольку к тому времени стек уже свернут.
Функция lua_pcall возвращает один из следующих кодов состояния: LUA_OK, LUA_ERRRUN, LUA_ERRMEM или LUA_ERRERR.
lua_pcallk
[-(nargs + 1), +(nresults|1), –]
int lua_pcallk (lua_State *L,
int nargs,
int nresults,
int msgh,
lua_KContext ctx,
lua_KFunction k);
Эта функция ведет себя точно так же, как lua_pcall, за исключением того, что она позволяет вызываемой функции выполнять yield (см. §4.5).
lua_pop
[-n, +0, e]
void lua_pop (lua_State *L, int n);
Извлекает n элементов из стека. Реализован как макрос над lua_settop.
lua_pushboolean
[-0, +1, –]
void lua_pushboolean (lua_State *L, int b);
Помещает булево значение со значением b в стек.
lua_pushcclosure
[-n, +1, m]
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
Помещает новое замыкание C в стек. Эта функция получает указатель на функцию C и помещает в стек значение Lua типа function, которое при вызове вызывает соответствующую функцию C. Параметр n сообщает, сколько upvalue будет у этой функции (см. §4.2).
Любая функция, вызываемая из Lua, должна следовать правильному протоколу для получения параметров и возврата результатов (см. lua_CFunction).
При создании функции C с ней можно связать некоторые значения, так называемые upvalue; эти upvalue затем доступны функции при каждом ее вызове. Эта связь называется замыканием C (см. §4.2). Чтобы создать замыкание C, сначала начальные значения для его upvalue должны быть помещены в стек. (Если upvalue несколько, первое значение помещается первым). Затем вызывается lua_pushcclosure для создания и помещения функции C в стек, при этом аргумент n сообщает, сколько значений будет связано с функцией. lua_pushcclosure также извлекает эти значения из стека.
Максимальное значение для n — 255.
Когда n равно нулю, эта функция создает легкую функцию C (light C function), которая является просто указателем на функцию C. В этом случае она никогда не вызывает ошибку памяти.
lua_pushcfunction
[-0, +1, –]
void lua_pushcfunction (lua_State *L, lua_CFunction f);
Помещает функцию C в стек. Эта функция эквивалентна lua_pushcclosure без upvalue.
lua_pushexternalstring
[-0, +1, m]
const char *lua_pushexternalstring (lua_State *L,
const char *s, size_t len, lua_Alloc falloc, void *ud);
Создает внешнюю строку (external string), то есть строку, использующую память, не управляемую Lua. Указатель s указывает на внешний буфер, содержащий содержимое строки, а len — это длина строки. Строка должна иметь ноль в конце, то есть должно выполняться условие s[len] == '\0'. Как и для любой строки в Lua, длина должна помещаться в целое число Lua.
Если falloc отличается от NULL, эта функция будет вызвана Lua, когда внешний буфер больше не нужен. Содержимое буфера не должно изменяться до этого вызова. Функция будет вызвана с заданным ud, строкой s в качестве блока, длиной плюс один (для учета завершающего нуля) в качестве старого размера и 0 в качестве нового размера.
Даже при использовании внешнего буфера Lua все равно должен выделить заголовок для строки. В случае ошибки выделения памяти Lua вызовет falloc перед возбуждением ошибки.
Функция возвращает указатель на строку (то есть s).
lua_pushfstring
[-0, +1, v]
const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
Помещает в стек форматированную строку и возвращает указатель на эту строку (см. §4.1.3). Результат — это копия fmt, в которой каждый спецификатор преобразования заменен строковым представлением соответствующего дополнительного аргумента. Спецификатор преобразования (и соответствующий ему дополнительный аргумент) может быть: '%%' (вставляет символ '%'), '%s' (вставляет строку с завершающим нулем, без ограничений по размеру), '%f' (вставляет lua_Number), '%I' (вставляет lua_Integer), '%p' (вставляет указатель void*), '%d' (вставляет int), '%c' (вставляет int как однобайтовый символ) и '%U' (вставляет unsigned long как последовательность байт UTF-8).
Каждое вхождение '%' в строке fmt должно образовывать допустимый спецификатор преобразования.
Помимо ошибок выделения памяти, эта функция может возбудить ошибку, если результирующая строка слишком велика.
lua_pushglobaltable
[-0, +1, –]
void lua_pushglobaltable (lua_State *L);
Помещает глобальное окружение в стек.
lua_pushinteger
[-0, +1, –]
void lua_pushinteger (lua_State *L, lua_Integer n);
Помещает целое число со значением n в стек.
lua_pushlightuserdata
[-0, +1, –]
void lua_pushlightuserdata (lua_State *L, void *p);
Помещает легкий userdata в стек.
Userdata представляют значения C в Lua. Легкий userdata представляет указатель, void*. Это значение (как число): вы его не создаете, у него нет индивидуальной метатаблицы, и оно не собирается сборщиком мусора (поскольку никогда не создавалось). Легкий userdata равен “любому” легкому userdata с тем же адресом C.
lua_pushliteral
[-0, +1, v]
const char *lua_pushliteral (lua_State *L, const char *s);
Этот макрос эквивалентен lua_pushstring, но должен использоваться только тогда, когда s является литеральной строкой. (Lua может оптимизировать этот случай).
lua_pushlstring
[-0, +1, v]
const char *lua_pushlstring (lua_State *L, const char *s, size_t len);
Помещает строку, на которую указывает s, размером len, в стек. Lua создаст или повторно использует внутреннюю копию данной строки, так что память по адресу s может быть освобождена или повторно использована сразу после возврата функции. Строка может содержать любые двоичные данные, включая встроенные нули.
Возвращает указатель на внутреннюю копию строки (см. §4.1.3).
Помимо ошибок выделения памяти, эта функция может возбудить ошибку, если строка слишком велика.
lua_pushnil
[-0, +1, –]
void lua_pushnil (lua_State *L);
Помещает значение nil в стек.
lua_pushnumber
[-0, +1, –]
void lua_pushnumber (lua_State *L, lua_Number n);
Помещает число с плавающей запятой со значением n в стек.
lua_pushstring
[-0, +1, m]
const char *lua_pushstring (lua_State *L, const char *s);
Помещает строку с завершающим нулем, на которую указывает s, в стек. Lua создаст или повторно использует внутреннюю копию данной строки, так что память по адресу s может быть освобождена или повторно использована сразу после возврата функции.
Возвращает указатель на внутреннюю копию строки (см. §4.1.3).
Если s равен NULL, помещает nil и возвращает NULL.
lua_pushthread
[-0, +1, –]
int lua_pushthread (lua_State *L);
Помещает поток, представленный L, в стек. Возвращает 1, если этот поток является главным потоком своего состояния.
lua_pushvalue
[-0, +1, –]
void lua_pushvalue (lua_State *L, int index);
Помещает копию элемента по заданному индексу в стек.
lua_pushvfstring
[-0, +1, –]
const char *lua_pushvfstring (lua_State *L,
const char *fmt,
va_list argp);
Эквивалентно lua_pushfstring, за исключением того, что получает va_list вместо переменного количества аргументов и не возбуждает ошибок. Вместо этого в случае ошибок помещает сообщение об ошибке и возвращает NULL.
lua_rawequal
[-0, +0, –]
int lua_rawequal (lua_State *L, int index1, int index2);
Возвращает 1, если два значения по индексам index1 и index2 примитивно равны (то есть равны без вызова метаметода __eq). В противном случае возвращает 0. Также возвращает 0, если какой-либо из индексов недействителен.
lua_rawget
[-1, +1, –]
int lua_rawget (lua_State *L, int index);
Аналогично lua_gettable, но выполняет сырой доступ (т.е. без метаметодов). Значение по индексу index должно быть таблицей.
lua_rawgeti
[-0, +1, –]
int lua_rawgeti (lua_State *L, int index, lua_Integer n);
Помещает в стек значение t[n], где t — таблица по заданному индексу. Доступ сырой, то есть не использует метазначение __index.
Возвращает тип помещенного значения.
lua_rawgetp
[-0, +1, –]
int lua_rawgetp (lua_State *L, int index, const void *p);
Помещает в стек значение t[k], где t — таблица по заданному индексу, а k — указатель p, представленный как легкий userdata. Доступ сырой, то есть не использует метазначение __index.
Возвращает тип помещенного значения.
lua_rawlen
[-0, +0, –]
lua_Unsigned lua_rawlen (lua_State *L, int index);
Возвращает сырую “длину” значения по заданному индексу: для строк это длина строки; для таблиц это результат оператора длины (#) без метаметодов; для userdata это размер блока памяти, выделенного для userdata. Для других значений этот вызов возвращает 0.
lua_rawset
[-2, +0, m]
void lua_rawset (lua_State *L, int index);
Аналогично lua_settable, но выполняет сырое присваивание (т.е. без метаметодов). Значение по индексу index должно быть таблицей.
lua_rawseti
[-1, +0, m]
void lua_rawseti (lua_State *L, int index, lua_Integer i);
Выполняет эквивалент t[i] = v, где t — таблица по заданному индексу, а v — значение на вершине стека.
Эта функция извлекает значение из стека. Присваивание сырое, то есть не использует метазначение __newindex.
lua_rawsetp
[-1, +0, m]
void lua_rawsetp (lua_State *L, int index, const void *p);
Выполняет эквивалент t[p] = v, где t — таблица по заданному индексу, p закодировано как легкий userdata, а v — значение на вершине стека.
Эта функция извлекает значение из стека. Присваивание сырое, то есть не использует метазначение __newindex.
lua_Reader
typedef const char * (*lua_Reader) (lua_State *L,
void *data,
size_t *size);
Функция-читатель, используемая lua_load. Каждый раз, когда lua_load нуждается в очередной части чанка, она вызывает читатель, передавая его параметр data. Читатель должен вернуть указатель на блок памяти с новым куском чанка и установить size в размер блока. Блок должен существовать до тех пор, пока функция-читатель не будет вызвана снова. Чтобы сигнализировать о конце чанка, читатель должен вернуть NULL или установить size в ноль. Функция-читатель может возвращать куски любого размера больше нуля.
lua_register
[-0, +0, e]
void lua_register (lua_State *L, const char *name, lua_CFunction f);
Устанавливает функцию C f как новое значение глобальной переменной name. Определено как макрос:
#define lua_register(L,n,f) \
(lua_pushcfunction(L, f), lua_setglobal(L, n))
lua_remove
[-1, +0, –]
void lua_remove (lua_State *L, int index);
Удаляет элемент по заданному допустимому индексу, сдвигая вниз элементы над этим индексом для заполнения промежутка. Эта функция не может вызываться с псевдоиндексом, поскольку псевдоиндекс не является фактической позицией в стеке.
lua_replace
[-1, +0, –]
void lua_replace (lua_State *L, int index);
Перемещает верхний элемент в заданный допустимый индекс без сдвига каких-либо элементов (таким образом, заменяя значение по этому заданному индексу), а затем извлекает верхний элемент.
lua_resume
[-?, +?, –]
int lua_resume (lua_State *L, lua_State *from, int nargs,
int *nresults);
Запускает и возобновляет сопрограмму в заданном потоке L.
Чтобы запустить сопрограмму, вы помещаете главную функцию и все аргументы в пустой стек потока, затем вызываете lua_resume, где nargs — количество аргументов. Функция возвращается, когда сопрограмма приостанавливается, завершает свое выполнение или возбуждает незащищенную ошибку. Когда она возвращается без ошибок, *nresults обновляется, и вершина стека содержит *nresults значений, переданных в lua_yield или возвращенных функцией тела. lua_resume возвращает LUA_YIELD, если сопрограмма выполняет yield, LUA_OK, если сопрограмма завершает выполнение без ошибок, или код ошибки в случае ошибок (см. §4.4.1). В случае ошибок объект ошибки помещается на вершину стека. (В этом случае nresults не обновляется, так как его значение должно было бы быть 1 для единственного объекта ошибки).
Чтобы возобновить приостановленную сопрограмму, вы удаляете *nresults значений, возвращенных yield, из ее стека, помещаете значения, которые будут переданы как результаты из yield, а затем вызываете lua_resume.
Параметр from представляет сопрограмму, которая возобновляет L. Если такой сопрограммы нет, этот параметр может быть NULL.
lua_rotate
[-0, +0, –]
void lua_rotate (lua_State *L, int idx, int n);
Вращает элементы стека между допустимым индексом idx и вершиной стека. Элементы вращаются на n позиций в направлении вершины для положительного n или на -n позиций в направлении дна для отрицательного n. Абсолютное значение n не должно превышать размер вращаемого среза. Эта функция не может вызываться с псевдоиндексом, поскольку псевдоиндекс не является фактической позицией в стеке.
lua_setallocf
[-0, +0, –]
void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
Изменяет функцию-аллокатор данного состояния на f с пользовательскими данными ud.
lua_setfield
[-1, +0, e]
void lua_setfield (lua_State *L, int index, const char *k);
Выполняет эквивалент t[k] = v, где t — значение по заданному индексу, а v — значение на вершине стека.
Эта функция извлекает значение из стека. Как и в Lua, эта функция может вызвать метаметод для события “newindex” (см. §2.4).
lua_setglobal
[-1, +0, e]
void lua_setglobal (lua_State *L, const char *name);
Извлекает значение из стека и устанавливает его как новое значение глобальной переменной name.
lua_seti
[-1, +0, e]
void lua_seti (lua_State *L, int index, lua_Integer n);
Выполняет эквивалент t[n] = v, где t — значение по заданному индексу, а v — значение на вершине стека.
Эта функция извлекает значение из стека. Как и в Lua, эта функция может вызвать метаметод для события “newindex” (см. §2.4).
lua_setiuservalue
[-1, +0, –]
int lua_setiuservalue (lua_State *L, int index, int n);
Извлекает значение из стека и устанавливает его как новое n-е пользовательское значение, связанное с полным userdata по заданному индексу. Возвращает 0, если userdata не имеет такого значения.
lua_setmetatable
[-1, +0, –]
int lua_setmetatable (lua_State *L, int index);
Извлекает таблицу или nil из стека и устанавливает это значение как новую метатаблицу для значения по заданному индексу. (nil означает отсутствие метатаблицы).
(По историческим причинам эта функция возвращает int, который теперь всегда равен 1).
lua_settable
[-2, +0, e]
void lua_settable (lua_State *L, int index);
Выполняет эквивалент t[k] = v, где t — значение по заданному индексу, v — значение на вершине стека, а k — значение непосредственно под вершиной.
Эта функция извлекает и ключ, и значение из стека. Как и в Lua, эта функция может вызвать метаметод для события “newindex” (см. §2.4).
lua_settop
[-?, +?, e]
void lua_settop (lua_State *L, int index);
Принимает любой приемлемый индекс стека или 0 и устанавливает вершину стека в этот индекс. Если новая вершина больше старой, то новые элементы заполняются значением nil. Если index равен 0, то все элементы стека удаляются.
Эта функция может выполнять произвольный код при удалении из стека индекса, помеченного как закрываемый (to-be-closed).
lua_setwarnf
[-0, +0, –]
void lua_setwarnf (lua_State *L, lua_WarnFunction f, void *ud);
Устанавливает функцию предупреждения, используемую Lua для выдачи предупреждений (см. lua_WarnFunction). Параметр ud устанавливает значение ud, передаваемое в функцию предупреждения.
lua_State
typedef struct lua_State lua_State;
Непрозрачная структура, которая указывает на поток и косвенно (через поток) на все состояние интерпретатора Lua. Библиотека Lua полностью реентерабельна: у нее нет глобальных переменных. Вся информация о состоянии доступна через эту структуру.
Указатель на эту структуру должен передаваться в качестве первого аргумента каждой функции в библиотеке, кроме lua_newstate, которая создает состояние Lua с нуля.
lua_status
[-0, +0, –]
int lua_status (lua_State *L);
Возвращает статус потока L.
Статус может быть LUA_OK для нормального потока, кодом ошибки, если поток завершил выполнение lua_resume с ошибкой, или LUA_YIELD, если поток приостановлен.
Вы можете вызывать функции только в потоках со статусом LUA_OK. Вы можете возобновлять потоки со статусом LUA_OK (для запуска новой сопрограммы) или LUA_YIELD (для возобновления сопрограммы).
lua_stringtonumber
[-0, +1, –]
size_t lua_stringtonumber (lua_State *L, const char *s);
Преобразует строку с завершающим нулем s в число, помещает это число в стек и возвращает общий размер строки, то есть ее длину плюс один. Преобразование может дать целое число или число с плавающей запятой в соответствии с лексическими соглашениями Lua (см. §3.1). Строка может иметь начальные и конечные пробелы и знак. Если строка не является допустимым числом, возвращает 0 и ничего не помещает. (Обратите внимание, что результат можно использовать как булево значение, true, если преобразование успешно).
lua_toboolean
[-0, +0, –]
int lua_toboolean (lua_State *L, int index);
Преобразует значение Lua по заданному индексу в булево значение C (0 или 1). Как и все проверки в Lua, lua_toboolean возвращает true для любого значения Lua, отличного от false и nil; в противном случае возвращает false. (Если вы хотите принимать только фактические булевы значения, используйте lua_isboolean для проверки типа значения).
lua_tocfunction
[-0, +0, –]
lua_CFunction lua_tocfunction (lua_State *L, int index);
Преобразует значение по заданному индексу в функцию C. Это значение должно быть функцией C; в противном случае возвращает NULL.
lua_toclose
[-0, +0, v]
void lua_toclose (lua_State *L, int index);
Помечает заданный индекс в стеке как закрываемый слот (to-be-closed slot) (см. §3.3.8). Как и закрываемая переменная в Lua, значение в этом слоте стека будет закрыто, когда оно выйдет из области видимости. Здесь, в контексте функции C, “выйти из области видимости” означает, что выполняющаяся функция возвращается в Lua, или происходит ошибка, или слот удаляется из стека через lua_settop или lua_pop, или происходит вызов lua_closeslot. Слот, помеченный как закрываемый, не должен удаляться из стека никакой другой функцией API, кроме lua_settop или lua_pop, если только он предварительно не деактивирован вызовом lua_closeslot.
Эта функция возбуждает ошибку, если значение в заданном слоте не имеет метаметода __close и не является ложным значением.
Эту функцию не следует вызывать для индекса, который равен или находится ниже активного закрываемого слота.
Обратите внимание, что как в случае ошибок, так и при обычном возврате, к моменту выполнения метаметода __close стек C уже свернут, так что любые автоматические переменные C, объявленные в вызывающей функции (например, буфер), будут вне области видимости.
lua_tointeger
[-0, +0, –]
lua_Integer lua_tointeger (lua_State *L, int index);
Эквивалентно lua_tointegerx с isnum, равным NULL.
lua_tointegerx
[-0, +0, –]
lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);
Преобразует значение Lua по заданному индексу в знаковый целочисленный тип lua_Integer. Значение Lua должно быть целым числом, или числом, или строкой, преобразуемой в целое число (см. §3.4.3); в противном случае lua_tointegerx возвращает 0.
Если isnum не NULL, по его ссылке присваивается булево значение, указывающее, успешно ли выполнена операция.
lua_tolstring
[-0, +0, m]
const char *lua_tolstring (lua_State *L, int index, size_t *len);
Преобразует значение Lua по заданному индексу в строку C. Значение Lua должно быть строкой или числом; в противном случае функция возвращает NULL. Если значение — число, то lua_tolstring также изменяет фактическое значение в стеке на строку. (Это изменение сбивает lua_next, когда lua_tolstring применяется к ключам во время обхода таблицы).
Если len не NULL, функция устанавливает *len в длину строки. Возвращаемая строка C всегда имеет ноль ('\0') после своего последнего символа, но может содержать другие нули в своем теле.
Указатель, возвращаемый lua_tolstring, может быть признан недействительным сборщиком мусора, если соответствующее значение Lua удалено из стека (см. §4.1.3).
Эта функция может вызывать ошибки памяти только при преобразовании числа в строку (поскольку в этом случае она может создать новую строку).
lua_tonumber
[-0, +0, –]
lua_Number lua_tonumber (lua_State *L, int index);
Эквивалентно lua_tonumberx с isnum, равным NULL.
lua_tonumberx
[-0, +0, –]
lua_Number lua_tonumberx (lua_State *L, int index, int *isnum);
Преобразует значение Lua по заданному индексу в тип C lua_Number (см. lua_Number). Значение Lua должно быть числом или строкой, преобразуемой в число (см. §3.4.3); в противном случае lua_tonumberx возвращает 0.
Если isnum не NULL, по его ссылке присваивается булево значение, указывающее, успешно ли выполнена операция.
lua_topointer
[-0, +0, –]
const void *lua_topointer (lua_State *L, int index);
Преобразует значение по заданному индексу в обобщенный указатель C (void*). Значение может быть userdata, таблицей, потоком, строкой или функцией; в противном случае lua_topointer возвращает NULL. Разные объекты будут давать разные указатели. Нет способа преобразовать указатель обратно в исходное значение.
Обычно эта функция используется только для хеширования и отладочной информации.
lua_tostring
[-0, +0, m]
const char *lua_tostring (lua_State *L, int index);
Эквивалентно lua_tolstring с len, равным NULL.
lua_tothread
[-0, +0, –]
lua_State *lua_tothread (lua_State *L, int index);
Преобразует значение по заданному индексу в поток Lua (представленный как lua_State*). Это значение должно быть потоком; в противном случае функция возвращает NULL.
lua_touserdata
[-0, +0, –]
void *lua_touserdata (lua_State *L, int index);
Если значение по заданному индексу является полным userdata, возвращает адрес его блока памяти. Если значение — легкий userdata, возвращает его значение (указатель). В противном случае возвращает NULL.
lua_type
[-0, +0, –]
int lua_type (lua_State *L, int index);
Возвращает тип значения в заданном допустимом индексе или LUA_TNONE для недопустимого, но приемлемого индекса. Типы, возвращаемые lua_type, кодируются следующими константами, определенными в lua.h: LUA_TNIL, LUA_TNUMBER, LUA_TBOOLEAN, LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD и LUA_TLIGHTUSERDATA.
lua_typename
[-0, +0, –]
const char *lua_typename (lua_State *L, int tp);
Возвращает имя типа, закодированного значением tp, которое должно быть одним из значений, возвращаемых lua_type.
lua_Unsigned
typedef ... lua_Unsigned;
Беззнаковая версия lua_Integer.
lua_upvalueindex
[-0, +0, –]
int lua_upvalueindex (int i);
Возвращает псевдоиндекс, представляющий i-е upvalue выполняющейся функции (см. §4.2). i должно быть в диапазоне [1,256].
lua_version
[-0, +0, –]
lua_Number lua_version (lua_State *L);
Возвращает номер версии данного ядра.
lua_WarnFunction
typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont);
Тип функций предупреждения, вызываемых Lua для выдачи предупреждений. Первый параметр — непрозрачный указатель, установленный lua_setwarnf. Второй параметр — сообщение предупреждения. Третий параметр — булево значение, указывающее, будет ли сообщение продолжено сообщением в следующем вызове.
См. warn для получения дополнительной информации о предупреждениях.
lua_warning
[-0, +0, –]
void lua_warning (lua_State *L, const char *msg, int tocont);
Выдает предупреждение с заданным сообщением. Сообщение в вызове с tocont равным true должно быть продолжено в другом вызове этой функции.
См. warn для получения дополнительной информации о предупреждениях.
lua_Writer
typedef int (*lua_Writer) (lua_State *L,
const void* p,
size_t sz,
void* ud);
Тип функции-писателя, используемой lua_dump. Каждый раз, когда lua_dump создает очередную часть чанка, она вызывает писатель, передавая буфер для записи (p), его размер (sz) и параметр ud, переданный в lua_dump.
После того как lua_dump запишет свою последнюю часть, она сигнализирует об этом, вызывая функцию-писатель еще один раз с буфером NULL (и размером 0).
Писатель возвращает код ошибки: 0 означает отсутствие ошибок; любое другое значение означает ошибку и останавливает lua_dump от дальнейших вызовов писателя.
lua_xmove
[-?, +?, –]
void lua_xmove (lua_State *from, lua_State *to, int n);
Обменивает значения между разными потоками одного и того же состояния.
Эта функция извлекает n значений из стека from и помещает их в стек to.
lua_yield
[-?, +?, v]
int lua_yield (lua_State *L, int nresults);
Эта функция эквивалентна lua_yieldk, но не имеет продолжения (см. §4.5). Следовательно, когда поток возобновляется, он продолжает функцию, которая вызвала функцию, вызывающую lua_yield. Во избежание неожиданностей эту функцию следует вызывать только в хвостовом вызове.
lua_yieldk
[-?, +?, v]
int lua_yieldk (lua_State *L,
int nresults,
lua_KContext ctx,
lua_KFunction k);
Выполняет yield сопрограммы (потока).
Когда функция C вызывает lua_yieldk, выполняющаяся сопрограмма приостанавливает свое выполнение, и вызов lua_resume, запустивший эту сопрограмму, возвращается. Параметр nresults — это количество значений из стека, которые будут переданы как результаты в lua_resume.
Когда сопрограмма возобновляется снова, Lua вызывает заданную функцию продолжения k для продолжения выполнения функции C, которая выполнила yield (см. §4.5). Эта функция продолжения получает тот же стек, что и предыдущая функция, с удаленными n результатами и замененными аргументами, переданными в lua_resume. Более того, функция продолжения получает значение ctx, которое было передано в lua_yieldk.
Обычно эта функция не возвращается; когда сопрограмма в конечном итоге возобновляется, она продолжает выполнение функции продолжения. Однако есть один особый случай: когда эта функция вызывается изнутри хука строки или счетчика (см. §4.7). В этом случае lua_yieldk должна вызываться без продолжения (вероятно, в форме lua_yield) и без результатов, а хук должен возвращаться немедленно после вызова. Lua выполнит yield, и, когда сопрограмма снова возобновится, она продолжит нормальное выполнение функции (Lua), которая вызвала хук.
Эта функция может возбудить ошибку, если она вызывается из потока с ожидающим вызовом C без функции продолжения (то, что называется границей C-вызова), или если она вызывается из потока, который не выполняется внутри resume (обычно главный поток).
4.7 – Отладочный интерфейс
Lua не имеет встроенных средств отладки. Вместо этого он предлагает специальный интерфейс посредством функций и хуков. Этот интерфейс позволяет создавать различные виды отладчиков, профайлеров и других инструментов, которым нужна “внутренняя информация” от интерпретатора.
lua_Debug
typedef struct lua_Debug {
int event;
const char *name; /* (n) */
const char *namewhat; /* (n) */
const char *what; /* (S) */
const char *source; /* (S) */
size_t srclen; /* (S) */
int currentline; /* (l) */
int linedefined; /* (S) */
int lastlinedefined; /* (S) */
unsigned char nups; /* (u) количество upvalue */
unsigned char nparams; /* (u) количество параметров */
char isvararg; /* (u) */
unsigned char extraargs; /* (t) количество дополнительных аргументов */
char istailcall; /* (t) */
int ftransfer; /* (r) индекс первого передаваемого значения */
int ntransfer; /* (r) количество передаваемых значений */
char short_src[LUA_IDSIZE]; /* (S) */
/* приватная часть */
другие поля
} lua_Debug;
Структура, используемая для переноса различных фрагментов информации о функции или записи активации. lua_getstack заполняет только приватную часть этой структуры для последующего использования. Чтобы заполнить другие поля lua_Debug полезной информацией, необходимо вызвать lua_getinfo с соответствующим параметром. (В частности, чтобы получить поле, необходимо добавить букву в скобках в комментарии к полю в параметр what функции lua_getinfo.)
Поля lua_Debug имеют следующее значение:
source: источник чанка, создавшего функцию. Еслиsourceначинается с'@', это означает, что функция была определена в файле, имя которого следует за'@'. Еслиsourceначинается с'=', остальная часть его содержимого описывает источник способом, зависящим от пользователя. В противном случае функция была определена в строке, гдеsourceи есть эта строка.srclen: Длина строкиsource.short_src: “печатная” версияsourceдля использования в сообщениях об ошибках.linedefined: номер строки, с которой начинается определение функции.lastlinedefined: номер строки, на которой заканчивается определение функции.what: строка"Lua", если функция Lua,"C", если функция C,"main", если это главная часть чанка.currentline: текущая строка, в которой выполняется данная функция. Когда информация о строке недоступна,currentlineустанавливается в -1.name: подходящее имя для данной функции. Поскольку функции в Lua являются значениями первого класса, у них нет фиксированного имени: некоторые функции могут быть значением нескольких глобальных переменных, в то время как другие могут храниться только в поле таблицы. Функцияlua_getinfoпроверяет, как была вызвана функция, чтобы найти подходящее имя. Если она не может найти имя, тоnameустанавливается вNULL.namewhat: объясняет полеname. Значениеnamewhatможет быть"global","local","upvalue","field",""(пустая строка) плюс некоторые другие варианты, в зависимости от того, как была вызвана функция. (Lua использует пустую строку, когда ни один другой вариант не подходит).istailcall:true, если этот вызов функции был сделан через хвостовой вызов. В этом случае вызыватель этого уровня отсутствует в стеке.extraargs: Количество дополнительных аргументов, добавленных при вызове функций через метаметоды__call. (Каждое метазначение__callдобавляет один дополнительный аргумент — вызываемый объект, но может быть цепочка метазначений__call).nups: количество upvalue функции.nparams: количество параметров функции (всегда 0 для функций C).isvararg:true, если функция вариадическая (всегдаtrueдля функций C).ftransfer: индекс в стеке первого “передаваемого” значения, то есть параметров при вызове или возвращаемых значений при возврате. (Остальные значения находятся в последовательных индексах). Используя этот индекс, вы можете получать и изменять эти значения черезlua_getlocalиlua_setlocal. Это поле имеет значение только во время хука вызова, обозначая первый параметр, или хука возврата, обозначая первое возвращаемое значение. (Для хуков вызова это значение всегда равно 1).ntransfer: Количество передаваемых значений (см. предыдущий пункт). (Для вызовов функций Lua это значение всегда равноnparams).
lua_gethook
[-0, +0, –]
lua_Hook lua_gethook (lua_State *L);
Возвращает текущую функцию хука.
lua_gethookcount
[-0, +0, –]
int lua_gethookcount (lua_State *L);
Возвращает текущий счетчик хука.
lua_gethookmask
[-0, +0, –]
int lua_gethookmask (lua_State *L);
Возвращает текущую маску хука.
lua_getinfo
[-(0|1), +(0|1|2), m]
int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
Получает информацию о конкретной функции или вызове функции.
Чтобы получить информацию о вызове функции, параметр ar должен быть действительной записью активации, которая была заполнена предыдущим вызовом lua_getstack или передана в качестве аргумента хуку (см. lua_Hook).
Чтобы получить информацию о функции, вы помещаете ее в стек и начинаете строку what с символа '>'. (В этом случае lua_getinfo извлекает функцию с вершины стека). Например, чтобы узнать, в какой строке была определена функция f, можно написать следующий код:
lua_Debug ar;
lua_getglobal(L, "f"); /* получить глобальную 'f' */
lua_getinfo(L, ">S", &ar);
printf("%d\n", ar.linedefined);
Каждый символ в строке what выбирает некоторые поля структуры ar для заполнения или значение для помещения в стек. (Эти символы также задокументированы в объявлении структуры lua_Debug, в скобках в комментариях после каждого поля).
'f': помещает в стек функцию, которая выполняется на данном уровне;'l': заполняет полеcurrentline;'n': заполняет поляnameиnamewhat;'r': заполняет поляftransferиntransfer;'S': заполняет поляsource,short_src,linedefined,lastlinedefinedиwhat;'t': заполняет поляistailcallиextraargs;'u': заполняет поляnups,nparamsиisvararg;'L': помещает в стек таблицу, индексами которой являются строки в функции с некоторым ассоциированным кодом, то есть строки, в которых можно поставить точку останова. (Строки без кода включают пустые строки и комментарии). Если эта опция дана вместе с опцией'f', ее таблица помещается после функции. Это единственная опция, которая может вызвать ошибку памяти.
Эта функция возвращает 0, чтобы сигнализировать о недопустимой опции в what; даже в этом случае допустимые опции обрабатываются корректно.
lua_getlocal
[-0, +(0|1), –]
const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
Получает информацию о локальной переменной или временном значении заданной записи активации или заданной функции.
В первом случае параметр ar должен быть действительной записью активации, которая была заполнена предыдущим вызовом lua_getstack или передана в качестве аргумента хуку (см. lua_Hook). Индекс n выбирает, какую локальную переменную инспектировать; подробности об индексах и именах переменных см. в debug.getlocal.
lua_getlocal помещает значение переменной в стек и возвращает ее имя.
Во втором случае ar должен быть NULL, а инспектируемая функция должна находиться на вершине стека. В этом случае видны только параметры функций Lua (поскольку нет информации о том, какие переменные активны), и значения в стек не помещаются.
Возвращает NULL (и ничего не помещает), когда индекс больше количества активных локальных переменных.
lua_getstack
[-0, +0, –]
int lua_getstack (lua_State *L, int level, lua_Debug *ar);
Получает информацию о стеке времени выполнения интерпретатора.
Эта функция заполняет части структуры lua_Debug идентификацией записи активации функции, выполняющейся на заданном уровне. Уровень 0 — это текущая выполняющаяся функция, тогда как уровень n+1 — это функция, которая вызвала уровень n (за исключением хвостовых вызовов, которые не учитываются в стеке). При вызове с уровнем, превышающим глубину стека, lua_getstack возвращает 0; в противном случае возвращает 1.
lua_getupvalue
[-0, +(0|1), –]
const char *lua_getupvalue (lua_State *L, int funcindex, int n);
Получает информацию об n-м upvalue замыкания по индексу funcindex. Помещает значение upvalue в стек и возвращает его имя. Возвращает NULL (и ничего не помещает), когда индекс n больше количества upvalue.
Дополнительную информацию об upvalue см. в debug.getupvalue.
lua_Hook
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
Тип для отладочных функций хука.
Всякий раз, когда вызывается хук, его аргумент ar имеет поле event, установленное в конкретное событие, которое вызвало хук. Lua идентифицирует эти события следующими константами: LUA_HOOKCALL, LUA_HOOKRET, LUA_HOOKTAILCALL, LUA_HOOKLINE и LUA_HOOKCOUNT. Более того, для событий строки также устанавливается поле currentline. Чтобы получить значение любого другого поля в ar, хук должен вызвать lua_getinfo.
Для событий вызова event может быть LUA_HOOKCALL (обычное значение) или LUA_HOOKTAILCALL (для хвостового вызова); в этом случае не будет соответствующего события возврата.
Пока Lua выполняет хук, он отключает другие вызовы хуков. Следовательно, если хук вызывает обратно в Lua для выполнения функции или чанка, это выполнение происходит без каких-либо вызовов хуков.
Функции хуков не могут иметь продолжений, то есть они не могут вызывать lua_yieldk, lua_pcallk или lua_callk с не-null k.
Функции хуков могут выполнять yield при следующих условиях: Только события счетчика и строки могут выполнять yield; чтобы выполнить yield, функция хука должна завершить свое выполнение вызовом lua_yield с nresults, равным нулю (то есть без значений).
lua_sethook
[-0, +0, –]
void lua_sethook (lua_State *L, lua_Hook f, int mask, int count);
Устанавливает отладочную функцию хука.
Аргумент f — функция хука. mask указывает, на каких событиях будет вызываться хук: она формируется побитовым ИЛИ констант LUA_MASKCALL, LUA_MASKRET, LUA_MASKLINE и LUA_MASKCOUNT. Аргумент count имеет значение только тогда, когда маска включает LUA_MASKCOUNT. Для каждого события хук вызывается, как описано ниже:
- Хук вызова: вызывается, когда интерпретатор вызывает функцию. Хук вызывается сразу после того, как Lua входит в новую функцию.
- Хук возврата: вызывается, когда интерпретатор возвращается из функции. Хук вызывается непосредственно перед тем, как Lua покидает функцию.
- Хук строки: вызывается, когда интерпретатор собирается начать выполнение новой строки кода или когда он перепрыгивает назад в коде (даже на ту же строку). Это событие происходит только во время выполнения Lua функции Lua.
- Хук счетчика: вызывается после того, как интерпретатор выполняет каждые
countинструкций. Это событие происходит только во время выполнения Lua функции Lua.
Хуки отключаются установкой mask в ноль.
lua_setlocal
[-(0|1), +0, –]
const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
Устанавливает значение локальной переменной заданной записи активации. Присваивает значение на вершине стека переменной и возвращает ее имя. Также извлекает значение из стека.
Возвращает NULL (и ничего не извлекает), когда индекс больше количества активных локальных переменных.
Параметры ar и n такие же, как в функции lua_getlocal.
lua_setupvalue
[-(0|1), +0, –]
const char *lua_setupvalue (lua_State *L, int funcindex, int n);
Устанавливает значение upvalue замыкания. Присваивает значение на вершине стека upvalue и возвращает его имя. Также извлекает значение из стека.
Возвращает NULL (и ничего не извлекает), когда индекс n больше количества upvalue.
Параметры funcindex и n такие же, как в функции lua_getupvalue.
lua_upvalueid
[-0, +0, –]
void *lua_upvalueid (lua_State *L, int funcindex, int n);
Возвращает уникальный идентификатор для upvalue с номером n из замыкания по индексу funcindex.
Эти уникальные идентификаторы позволяют программе проверять, разделяют ли разные замыкания upvalue. Замыкания Lua, которые разделяют upvalue (то есть обращаются к одной и той же внешней локальной переменной), будут возвращать идентичные идентификаторы для этих индексов upvalue.
Параметры funcindex и n такие же, как в функции lua_getupvalue, но n не может быть больше количества upvalue.
lua_upvaluejoin
[-0, +0, –]
void lua_upvaluejoin (lua_State *L, int funcindex1, int n1,
int funcindex2, int n2);
Делает так, чтобы n1-е upvalue замыкания Lua по индексу funcindex1 ссылалось на n2-е upvalue замыкания Lua по индексу funcindex2.
2.4 - Вспомогательная библиотека Lua
Оглавление
- Введение
- Функции и типы
- luaL_addchar
- luaL_addgsub
- luaL_addlstring
- luaL_addsize
- luaL_addstring
- luaL_addvalue
- luaL_argcheck
- luaL_argerror
- luaL_argexpected
- luaL_Buffer
- luaL_buffaddr
- luaL_buffinit
- luaL_bufflen
- luaL_buffinitsize
- luaL_buffsub
- luaL_callmeta
- luaL_checkany
- luaL_checkinteger
- luaL_checklstring
- luaL_checknumber
- luaL_checkoption
- luaL_checkstack
- luaL_checkstring
- luaL_checktype
- luaL_checkudata
- luaL_checkversion
- luaL_dofile
- luaL_dostring
- luaL_error
- luaL_execresult
- luaL_fileresult
- luaL_getmetafield
- luaL_getmetatable
- luaL_getsubtable
- luaL_gsub
- luaL_len
- luaL_loadbuffer
- luaL_loadbufferx
- luaL_loadfile
- luaL_loadfilex
- luaL_loadstring
- luaL_makeseed
- luaL_newlib
- luaL_newlibtable
- luaL_newmetatable
- luaL_newstate
- luaL_opt
- luaL_optinteger
- luaL_optlstring
- luaL_optnumber
- luaL_optstring
- luaL_prepbuffer
- luaL_prepbuffsize
- luaL_pushfail
- luaL_pushresult
- luaL_pushresultsize
- luaL_ref
- luaL_Reg
- luaL_requiref
- luaL_setfuncs
- luaL_setmetatable
- luaL_alloc
- luaL_Stream
- luaL_testudata
- luaL_tolstring
- luaL_traceback
- luaL_typeerror
- luaL_typename
- luaL_unref
- luaL_where
Введение
Вспомогательная библиотека предоставляет несколько удобных функций для взаимодействия C с Lua. В то время как базовый API предоставляет примитивные функции для всех взаимодействий между C и Lua, вспомогательная библиотека предоставляет функции более высокого уровня для некоторых распространенных задач.
Все функции и типы из вспомогательной библиотеки определены в заголовочном файле lauxlib.h и имеют префикс luaL_.
Все функции вспомогательной библиотеки построены поверх базового API, поэтому они не предоставляют ничего, что нельзя было бы сделать с помощью этого API. Тем не менее, использование вспомогательной библиотеки обеспечивает большую согласованность вашего кода.
Некоторые функции во вспомогательной библиотеке используют внутри себя несколько дополнительных слотов стека. Когда функция вспомогательной библиотеки использует менее пяти слотов, она не проверяет размер стека; она просто предполагает, что слотов достаточно.
Некоторые функции вспомогательной библиотеки используются для проверки аргументов функций C. Поскольку сообщение об ошибке форматируется для аргументов (например, "bad argument #1"), вы не должны использовать эти функции для других значений стека.
Функции, называемые luaL_check*, всегда вызывают ошибку, если проверка не пройдена.
Функции и типы
Здесь мы перечисляем все функции и типы из вспомогательной библиотеки в алфавитном порядке.
luaL_addchar
[-?, +?, m]
void luaL_addchar (luaL_Buffer *B, char c);
Добавляет байт c в буфер B (см. luaL_Buffer).
luaL_addgsub
[-?, +?, m]
const void luaL_addgsub (luaL_Buffer *B, const char *s,
const char *p, const char *r);
Добавляет копию строки s в буфер B (см. luaL_Buffer), заменяя любое вхождение строки p строкой r.
luaL_addlstring
[-?, +?, m]
void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
Добавляет строку, на которую указывает s, длиной l в буфер B (см. luaL_Buffer). Строка может содержать встроенные нули.
luaL_addsize
[-?, +?, –]
void luaL_addsize (luaL_Buffer *B, size_t n);
Добавляет в буфер B строку длиной n, предварительно скопированную в область буфера (см. luaL_prepbuffer).
luaL_addstring
[-?, +?, m]
void luaL_addstring (luaL_Buffer *B, const char *s);
Добавляет строку с завершающим нулем, на которую указывает s, в буфер B (см. luaL_Buffer).
luaL_addvalue
[-?, +?, m]
void luaL_addvalue (luaL_Buffer *B);
Добавляет значение на вершине стека в буфер B (см. luaL_Buffer). Выталкивает значение.
Это единственная функция строковых буферов, которую можно (и нужно) вызывать с дополнительным элементом в стеке, который является значением, добавляемым в буфер.
luaL_argcheck
[-0, +0, v]
void luaL_argcheck (lua_State *L,
int cond,
int arg,
const char *extramsg);
Проверяет, является ли cond истиной. Если нет, вызывает ошибку со стандартным сообщением (см. luaL_argerror).
luaL_argerror
[-0, +0, v]
int luaL_argerror (lua_State *L, int arg, const char *extramsg);
Вызывает ошибку, сообщающую о проблеме с аргументом arg функции C, которая ее вызвала, используя стандартное сообщение, которое включает extramsg в качестве комментария:
bad argument #arg to 'funcname' (extramsg)
Эта функция никогда не возвращается.
luaL_argexpected
[-0, +0, v]
void luaL_argexpected (lua_State *L,
int cond,
int arg,
const char *tname);
Проверяет, является ли cond истиной. Если нет, вызывает ошибку о типе аргумента arg со стандартным сообщением (см. luaL_typeerror).
luaL_Buffer
typedef struct luaL_Buffer luaL_Buffer;
Тип для строкового буфера.
Строковый буфер позволяет коду C строить строки Lua по частям. Шаблон его использования следующий:
- Сначала объявите переменную
bтипаluaL_Buffer. - Затем инициализируйте ее вызовом
luaL_buffinit(L, &b). - Затем добавляйте фрагменты строки в буфер, вызывая любую из функций
luaL_add*. - Завершите вызовом
luaL_pushresult(&b). Этот вызов оставляет итоговую строку на вершине стека.
Если вы заранее знаете максимальный размер результирующей строки, вы можете использовать буфер следующим образом:
- Сначала объявите переменную
bтипаluaL_Buffer. - Затем инициализируйте ее и предварительно выделите пространство размером
szвызовомluaL_buffinitsize(L, &b, sz). - Затем создайте строку в этом пространстве.
- Завершите вызовом
luaL_pushresultsize(&b, sz), гдеsz— общий размер результирующей строки, скопированной в это пространство (который может быть меньше или равен предварительно выделенному размеру).
Во время своей нормальной работы строковый буфер использует переменное количество слотов стека. Поэтому при использовании буфера вы не можете предполагать, что знаете, где находится вершина стека. Вы можете использовать стек между последовательными вызовами операций с буфером, если это использование сбалансировано; то есть, когда вы вызываете операцию с буфером, стек находится на том же уровне, на котором он был сразу после предыдущей операции с буфером. (Единственным исключением из этого правила является luaL_addvalue.) После вызова luaL_pushresult стек возвращается на уровень, на котором он был при инициализации буфера, плюс итоговая строка на его вершине.
luaL_buffaddr
[-0, +0, –]
char *luaL_buffaddr (luaL_Buffer *B);
Возвращает адрес текущего содержимого буфера B (см. luaL_Buffer). Обратите внимание, что любое добавление в буфер может сделать этот адрес недействительным.
luaL_buffinit
[-0, +?, –]
void luaL_buffinit (lua_State *L, luaL_Buffer *B);
Инициализирует буфер B (см. luaL_Buffer). Эта функция не выделяет никакого пространства; буфер должен быть объявлен как переменная.
luaL_bufflen
[-0, +0, –]
size_t luaL_bufflen (luaL_Buffer *B);
Возвращает длину текущего содержимого буфера B (см. luaL_Buffer).
luaL_buffinitsize
[-?, +?, m]
char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz);
Эквивалент последовательности luaL_buffinit, luaL_prepbuffsize.
luaL_buffsub
[-?, +?, –]
void luaL_buffsub (luaL_Buffer *B, int n);
Удаляет n байт из буфера B (см. luaL_Buffer). Буфер должен иметь как минимум столько байт.
luaL_callmeta
[-0, +(0|1), e]
int luaL_callmeta (lua_State *L, int obj, const char *e);
Вызывает метаметод.
Если объект по индексу obj имеет метатаблицу и эта метатаблица имеет поле e, эта функция вызывает это поле, передавая объект в качестве единственного аргумента. В этом случае функция возвращает true и помещает в стек значение, возвращенное вызовом. Если метатаблицы нет или нет метаметода, функция возвращает false, не помещая никакого значения в стек.
luaL_checkany
[-0, +0, v]
void luaL_checkany (lua_State *L, int arg);
Проверяет, есть ли у функции аргумент любого типа (включая nil) в позиции arg.
luaL_checkinteger
[-0, +0, v]
lua_Integer luaL_checkinteger (lua_State *L, int arg);
Проверяет, является ли аргумент функции arg целым числом (или может быть преобразован в целое число), и возвращает это целое число.
luaL_checklstring
[-0, +0, v]
const char *luaL_checklstring (lua_State *L, int arg, size_t *l);
Проверяет, является ли аргумент функции arg строкой, и возвращает эту строку; если l не NULL, заполняет его ссылку длиной строки.
Эта функция использует lua_tolstring для получения результата, поэтому здесь применяются все преобразования и предостережения этой функции.
luaL_checknumber
[-0, +0, v]
lua_Number luaL_checknumber (lua_State *L, int arg);
Проверяет, является ли аргумент функции arg числом, и возвращает это число, преобразованное в lua_Number.
luaL_checkoption
[-0, +0, v]
int luaL_checkoption (lua_State *L,
int arg,
const char *def,
const char *const lst[]);
Проверяет, является ли аргумент функции arg строкой, и ищет эту строку в массиве lst (который должен заканчиваться NULL). Возвращает индекс в массиве, где была найдена строка. Вызывает ошибку, если аргумент не является строкой или если строка не может быть найдена.
Если def не NULL, функция использует def как значение по умолчанию, когда аргумент arg отсутствует или когда этот аргумент равен nil.
Это полезная функция для сопоставления строк с перечислениями C. (Обычное соглашение в библиотеках Lua — использовать строки вместо чисел для выбора опций.)
luaL_checkstack
[-0, +0, v]
void luaL_checkstack (lua_State *L, int sz, const char *msg);
Увеличивает размер стека до top + sz элементов, вызывая ошибку, если стек не может вырасти до этого размера. msg — дополнительный текст для сообщения об ошибке (или NULL для отсутствия дополнительного текста).
luaL_checkstring
[-0, +0, v]
const char *luaL_checkstring (lua_State *L, int arg);
Проверяет, является ли аргумент функции arg строкой, и возвращает эту строку.
Эта функция использует lua_tolstring для получения результата, поэтому здесь применяются все преобразования и предостережения этой функции.
luaL_checktype
[-0, +0, v]
void luaL_checktype (lua_State *L, int arg, int t);
Проверяет, имеет ли аргумент функции arg тип t. См. lua_type для кодировки типов для t.
luaL_checkudata
[-0, +0, v]
void *luaL_checkudata (lua_State *L, int arg, const char *tname);
Проверяет, является ли аргумент функции arg пользовательскими данными типа tname (см. luaL_newmetatable), и возвращает адрес блока памяти пользовательских данных (см. lua_touserdata).
luaL_checkversion
[-0, +0, v]
void luaL_checkversion (lua_State *L);
Проверяет, используют ли код, выполняющий вызов, и вызываемая библиотека Lua одну и ту же версию Lua и одни и те же числовые типы.
luaL_dofile
[-0, +?, m]
int luaL_dofile (lua_State *L, const char *filename);
Загружает и выполняет указанный файл. Определен как следующий макрос:
(luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))
Возвращает 0 (LUA_OK), если ошибок нет, или 1 в случае ошибок. (За исключением ошибок нехватки памяти, которые вызываются.)
luaL_dostring
[-0, +?, –]
int luaL_dostring (lua_State *L, const char *str);
Загружает и выполняет указанную строку. Определен как следующий макрос:
(luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
Возвращает 0 (LUA_OK), если ошибок нет, или 1 в случае ошибок.
luaL_error
[-0, +0, v]
int luaL_error (lua_State *L, const char *fmt, ...);
Вызывает ошибку. Формат сообщения об ошибке задается fmt плюс любые дополнительные аргументы, следуя тем же правилам, что и lua_pushfstring. Она также добавляет в начало сообщения имя файла и номер строки, где произошла ошибка, если эта информация доступна.
Эта функция никогда не возвращается, но идиоматично использовать ее в функциях C как return luaL_error(args).
luaL_execresult
[-0, +3, m]
int luaL_execresult (lua_State *L, int stat);
Эта функция создает возвращаемые значения для функций, связанных с процессами, в стандартной библиотеке (os.execute и io.close).
luaL_fileresult
[-0, +(1|3), m]
int luaL_fileresult (lua_State *L, int stat, const char *fname);
Эта функция создает возвращаемые значения для функций, связанных с файлами, в стандартной библиотеке (io.open, os.rename, file:seek и т.д.).
luaL_getmetafield
[-0, +(0|1), m]
int luaL_getmetafield (lua_State *L, int obj, const char *e);
Помещает в стек поле e из метатаблицы объекта по индексу obj и возвращает тип помещенного значения. Если объект не имеет метатаблицы или если метатаблица не имеет этого поля, ничего не помещает и возвращает LUA_TNIL.
luaL_getmetatable
[-0, +1, m]
int luaL_getmetatable (lua_State *L, const char *tname);
Помещает в стек метатаблицу, связанную с именем tname в реестре (см. luaL_newmetatable), или nil, если с этим именем не связано метатаблицы. Возвращает тип помещенного значения.
luaL_getsubtable
[-0, +1, e]
int luaL_getsubtable (lua_State *L, int idx, const char *fname);
Обеспечивает, что значение t[fname], где t — значение по индексу idx, является таблицей, и помещает эту таблицу в стек. Возвращает true, если находит там существующую таблицу, и false, если создает новую таблицу.
luaL_gsub
[-0, +1, m]
const char *luaL_gsub (lua_State *L,
const char *s,
const char *p,
const char *r);
Создает копию строки s, заменяя любое вхождение строки p строкой r. Помещает результирующую строку в стек и возвращает ее.
luaL_len
[-0, +0, e]
lua_Integer luaL_len (lua_State *L, int index);
Возвращает “длину” значения по указанному индексу в виде числа; это эквивалентно оператору # в Lua (см. §3.4.7). Вызывает ошибку, если результат операции не является целым числом. (Этот случай может произойти только через метаметоды.)
luaL_loadbuffer
[-0, +1, –]
int luaL_loadbuffer (lua_State *L,
const char *buff,
size_t sz,
const char *name);
Эквивалент luaL_loadbufferx с mode, равным NULL.
luaL_loadbufferx
[-0, +1, –]
int luaL_loadbufferx (lua_State *L,
const char *buff,
size_t sz,
const char *name,
const char *mode);
Загружает буфер как чанк Lua. Эта функция использует lua_load для загрузки чанка в буфере, на который указывает buff, размером sz.
Эта функция возвращает те же результаты, что и lua_load. name — имя чанка, используемое для отладочной информации и сообщений об ошибках. Строка mode работает так же, как в функции lua_load. В частности, эта функция поддерживает режим 'B' для фиксированных буферов.
luaL_loadfile
[-0, +1, m]
int luaL_loadfile (lua_State *L, const char *filename);
Эквивалент luaL_loadfilex с mode, равным NULL.
luaL_loadfilex
[-0, +1, m]
int luaL_loadfilex (lua_State *L, const char *filename,
const char *mode);
Загружает файл как чанк Lua. Эта функция использует lua_load для загрузки чанка в файле с именем filename. Если filename равен NULL, то загружает из стандартного ввода. Первая строка в файле игнорируется, если она начинается с #.
Строка mode работает так же, как в функции lua_load.
Эта функция возвращает те же результаты, что и lua_load, или LUA_ERRFILE для ошибок, связанных с файлом.
Как и lua_load, эта функция только загружает чанк; она не выполняет его.
luaL_loadstring
[-0, +1, –]
int luaL_loadstring (lua_State *L, const char *s);
Загружает строку как чанк Lua. Эта функция использует lua_load для загрузки чанка в строке с завершающим нулем s.
Эта функция возвращает те же результаты, что и lua_load.
Также как и lua_load, эта функция только загружает чанк; она не выполняет его.
luaL_makeseed
[-0, +0, –]
unsigned int luaL_makeseed (lua_State *L);
Возвращает значение со слабой попыткой случайности. Параметр L может быть NULL, если состояние Lua недоступно.
luaL_newlib
[-0, +1, m]
void luaL_newlib (lua_State *L, const luaL_Reg l[]);
Создает новую таблицу и регистрирует в ней функции из списка l.
Реализована как следующий макрос:
(luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
Массив l должен быть фактическим массивом, а не указателем на него.
luaL_newlibtable
[-0, +1, m]
void luaL_newlibtable (lua_State *L, const luaL_Reg l[]);
Создает новую таблицу с размером, оптимизированным для хранения всех записей в массиве l (но фактически не сохраняет их). Предназначена для использования в сочетании с luaL_setfuncs (см. luaL_newlib).
Реализована как макрос. Массив l должен быть фактическим массивом, а не указателем на него.
luaL_newmetatable
[-0, +1, m]
int luaL_newmetatable (lua_State *L, const char *tname);
Если в реестре уже есть ключ tname, возвращает 0. В противном случае создает новую таблицу для использования в качестве метатаблицы для пользовательских данных, добавляет в эту новую таблицу пару __name = tname, добавляет в реестр пару [tname] = new table и возвращает 1.
В обоих случаях функция помещает в стек итоговое значение, связанное с tname в реестре.
luaL_newstate
[-0, +0, –]
lua_State *luaL_newstate (void);
Создает новое состояние Lua. Вызывает lua_newstate с luaL_alloc в качестве функции распределения памяти и результатом luaL_makeseed(NULL) в качестве seed, а затем устанавливает функцию предупреждения и функцию паники (см. §4.4), которые выводят сообщения в стандартный вывод ошибок.
Возвращает новое состояние или NULL в случае ошибки выделения памяти.
luaL_opt
[-0, +0, –]
T luaL_opt (L, func, arg, dflt);
Этот макрос определяется следующим образом:
(lua_isnoneornil(L,(arg)) ? (dflt) : func(L,(arg)))
Словами: если аргумент arg равен nil или отсутствует, макрос возвращает значение по умолчанию dflt. В противном случае он возвращает результат вызова func с состоянием L и индексом аргумента arg в качестве аргументов. Обратите внимание, что он вычисляет выражение dflt только при необходимости.
luaL_optinteger
[-0, +0, v]
lua_Integer luaL_optinteger (lua_State *L,
int arg,
lua_Integer d);
Если аргумент функции arg является целым числом (или может быть преобразован в целое число), возвращает это целое число. Если этот аргумент отсутствует или равен nil, возвращает d. В противном случае вызывает ошибку.
luaL_optlstring
[-0, +0, v]
const char *luaL_optlstring (lua_State *L,
int arg,
const char *d,
size_t *l);
Если аргумент функции arg является строкой, возвращает эту строку. Если этот аргумент отсутствует или равен nil, возвращает d. В противном случае вызывает ошибку.
Если l не NULL, заполняет его ссылку длиной результата. Если результат NULL (возможно только при возврате d и d == NULL), его длина считается нулевой.
Эта функция использует lua_tolstring для получения результата, поэтому здесь применяются все преобразования и предостережения этой функции.
luaL_optnumber
[-0, +0, v]
lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number d);
Если аргумент функции arg является числом, возвращает это число как lua_Number. Если этот аргумент отсутствует или равен nil, возвращает d. В противном случае вызывает ошибку.
luaL_optstring
[-0, +0, v]
const char *luaL_optstring (lua_State *L,
int arg,
const char *d);
Если аргумент функции arg является строкой, возвращает эту строку. Если этот аргумент отсутствует или равен nil, возвращает d. В противном случае вызывает ошибку.
luaL_prepbuffer
[-?, +?, m]
char *luaL_prepbuffer (luaL_Buffer *B);
Эквивалент luaL_prepbuffsize с предопределенным размером LUAL_BUFFERSIZE.
luaL_prepbuffsize
[-?, +?, m]
char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz);
Возвращает адрес пространства размером sz, куда вы можете скопировать строку для добавления в буфер B (см. luaL_Buffer). После копирования строки в это пространство вы должны вызвать luaL_addsize с размером строки, чтобы фактически добавить ее в буфер.
luaL_pushfail
[-0, +1, –]
void luaL_pushfail (lua_State *L);
Помещает значение fail в стек (см. §6).
luaL_pushresult
[-?, +1, m]
void luaL_pushresult (luaL_Buffer *B);
Завершает использование буфера B, оставляя итоговую строку на вершине стека.
luaL_pushresultsize
[-?, +1, m]
void luaL_pushresultsize (luaL_Buffer *B, size_t sz);
Эквивалент последовательности luaL_addsize, luaL_pushresult.
luaL_ref
[-1, +0, m]
int luaL_ref (lua_State *L, int t);
Создает и возвращает ссылку в таблице по индексу t для объекта на вершине стека (и выталкивает объект).
Система ссылок использует целочисленные ключи таблицы. Ссылка — это уникальный целочисленный ключ; luaL_ref обеспечивает уникальность возвращаемых ключей. Запись 1 зарезервирована для внутреннего использования. Перед первым использованием luaL_ref целочисленные ключи таблицы должны образовывать правильную последовательность (без пропусков), а значение в записи 1 должно быть false: nil, если последовательность пуста, false в противном случае. Вы не должны вручную устанавливать целочисленные ключи в таблице после первого использования luaL_ref.
Вы можете получить объект, на который ссылается ссылка r, вызвав lua_rawgeti(L, t, r) или lua_geti(L, t, r). Функция luaL_unref освобождает ссылку.
Если объект на вершине стека равен nil, luaL_ref возвращает константу LUA_REFNIL. Гарантируется, что константа LUA_NOREF отличается от любой ссылки, возвращаемой luaL_ref.
luaL_Reg
typedef struct luaL_Reg {
const char *name;
lua_CFunction func;
} luaL_Reg;
Тип для массивов функций, регистрируемых luaL_setfuncs. name — имя функции, func — указатель на функцию. Любой массив luaL_Reg должен заканчиваться сигнальной записью, в которой и name, и func равны NULL.
luaL_requiref
[-0, +1, e]
void luaL_requiref (lua_State *L, const char *modname,
lua_CFunction openf, int glb);
Если package.loaded[modname] не является true, вызывает функцию openf со строкой modname в качестве аргумента и устанавливает результат вызова в package.loaded[modname], как если бы эта функция была вызвана через require.
Если glb равно true, также сохраняет модуль в глобальную переменную modname.
Оставляет копию модуля в стеке.
luaL_setfuncs
[-nup, +0, m]
void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);
Регистрирует все функции в массиве l (см. luaL_Reg) в таблице на вершине стека (ниже необязательных upvalues, см. далее).
Когда nup не равен нулю, все функции создаются с nup upvalues, инициализированными копиями nup значений, предварительно помещенных в стек поверх таблицы библиотеки. Эти значения выталкиваются из стека после регистрации.
Функция со значением NULL представляет заполнитель, который заполняется значением false.
luaL_setmetatable
[-0, +0, –]
void luaL_setmetatable (lua_State *L, const char *tname);
Устанавливает метатаблицу объекта на вершине стека как метатаблицу, связанную с именем tname в реестре (см. luaL_newmetatable).
luaL_alloc
void *luaL_alloc (void *ud, void *ptr, size_t osize, size_t nsize);
Стандартная функция распределения памяти для Lua (см. lua_Alloc), построенная поверх функций C realloc и free.
luaL_Stream
typedef struct luaL_Stream {
FILE *f;
lua_CFunction closef;
} luaL_Stream;
Стандартное представление файловых дескрипторов, используемое стандартной библиотекой ввода-вывода.
Файловый дескриптор реализован как полные пользовательские данные с метатаблицей, называемой LUA_FILEHANDLE (где LUA_FILEHANDLE — это макрос с фактическим именем метатаблицы). Метатаблица создается библиотекой ввода-вывода (см. luaL_newmetatable).
Эти пользовательские данные должны начинаться со структуры luaL_Stream; они могут содержать другие данные после этой начальной структуры. Поле f указывает на соответствующий поток C или равно NULL, чтобы указать на не полностью созданный дескриптор. Поле closef указывает на функцию Lua, которая будет вызвана для закрытия потока при закрытии или сборке дескриптора; эта функция получает файловый дескриптор в качестве единственного аргумента и должна возвращать либо true в случае успеха, либо false плюс сообщение об ошибке в случае ошибки. Как только Lua вызывает это поле, он изменяет значение поля на NULL, чтобы сигнализировать о том, что дескриптор закрыт.
luaL_testudata
[-0, +0, m]
void *luaL_testudata (lua_State *L, int arg, const char *tname);
Эта функция работает как luaL_checkudata, за исключением того, что при неудачной проверке она возвращает NULL вместо вызова ошибки.
luaL_tolstring
[-0, +1, e]
const char *luaL_tolstring (lua_State *L, int idx, size_t *len);
Преобразует любое значение Lua по указанному индексу в строку C в разумном формате. Результирующая строка помещается в стек и также возвращается функцией (см. §4.1.3). Если len не NULL, функция также устанавливает *len в длину строки.
Если значение имеет метатаблицу с полем __tostring, то luaL_tolstring вызывает соответствующий метаметод со значением в качестве аргумента и использует результат вызова в качестве своего результата.
luaL_traceback
[-0, +1, m]
void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
int level);
Создает и помещает в стек трассировку стека L1. Если msg не NULL, он добавляется в начало трассировки. Параметр level указывает, с какого уровня начинать трассировку.
luaL_typeerror
[-0, +0, v]
int luaL_typeerror (lua_State *L, int arg, const char *tname);
Вызывает ошибку типа для аргумента arg функции C, которая ее вызвала, используя стандартное сообщение; tname — это “имя” ожидаемого типа. Эта функция никогда не возвращается.
luaL_typename
[-0, +0, –]
const char *luaL_typename (lua_State *L, int index);
Возвращает имя типа значения по указанному индексу.
luaL_unref
[-0, +0, –]
void luaL_unref (lua_State *L, int t, int ref);
Освобождает ссылку (см. luaL_ref). Целое число ref должно быть либо LUA_NOREF, либо LUA_REFNIL, либо ссылкой, ранее возвращенной luaL_ref и еще не освобожденной. Если ref равен LUA_NOREF или LUA_REFNIL, эта функция ничего не делает. В противном случае запись удаляется из таблицы, чтобы объект, на который ссылались, мог быть собран, а ссылка ref могла быть снова использована luaL_ref.
luaL_where
[-0, +1, m]
void luaL_where (lua_State *L, int lvl);
Помещает в стек строку, идентифицирующую текущую позицию управления на уровне lvl в стеке вызовов. Обычно эта строка имеет следующий формат:
chunkname:currentline:
Уровень 0 — выполняющаяся функция, уровень 1 — функция, вызвавшая выполняющуюся функцию, и т.д.
Эта функция используется для построения префикса для сообщений об ошибках.
2.5 - Руководство по языку Lua: Стандартные библиотеки
Оглавление
- Загрузка библиотек в коде C
- Базовые функции
- Управление сопрограммами
- Модули
- Манипуляции со строками
- Поддержка UTF-8
- Манипуляции с таблицами
- Математические функции
- Средства ввода и вывода
- Средства операционной системы
- Библиотека отладки
6 – Стандартные библиотеки
Стандартные библиотеки Lua предоставляют полезные функции, реализованные на C через C API. Некоторые из этих функций предоставляют основные службы для языка (например, type и getmetatable); другие предоставляют доступ к внешним службам (например, ввод/вывод); а третьи могли бы быть реализованы на самом Lua, но по разным причинам заслуживают реализации на C (например, table.sort).
Все библиотеки реализованы через официальный C API и предоставляются как отдельные модули C. Если не указано иное, эти библиотечные функции не корректируют количество своих аргументов в соответствии с ожидаемыми параметрами. Например, функцию, задокументированную как foo(arg), не следует вызывать без аргумента.
Обозначение fail означает ложное значение, представляющее некую неудачу. (В настоящее время fail эквивалентно nil, но это может измениться в будущих версиях. Рекомендуется всегда проверять успешность этих функций с помощью (not status), а не (status == nil).)
В настоящее время Lua имеет следующие стандартные библиотеки:
- базовая библиотека (§6.2);
- библиотека сопрограмм (§6.3);
- библиотека пакетов (§6.4);
- манипуляции со строками (§6.5);
- базовая поддержка UTF-8 (§6.6);
- манипуляции с таблицами (§6.7);
- математические функции (§6.8) (sin, log и т.д.);
- ввод и вывод (§6.9);
- средства операционной системы (§6.10);
- средства отладки (§6.11).
За исключением базовой библиотеки и библиотеки пакетов, каждая библиотека предоставляет все свои функции как поля глобальной таблицы или как методы своих объектов.
6.1 – Загрузка библиотек в коде C
Главная программа на C должна явно загрузить стандартные библиотеки в состояние, если она хочет, чтобы ее скрипты могли их использовать. Для этого главная программа может вызвать функцию luaL_openlibs. В качестве альтернативы, главная программа может выбрать, какие библиотеки открывать, используя luaL_openselectedlibs. Обе функции объявлены в заголовочном файле lualib.h.
Автономный интерпретатор lua (см. §7) уже открывает все стандартные библиотеки.
luaL_openlibs
[-0, +0, e]
void luaL_openlibs (lua_State *L);
Открывает все стандартные библиотеки Lua в данном состоянии.
luaL_openselectedlibs
[-0, +0, e]
void luaL_openselectedlibs (lua_State *L, int load, int preload);
Открывает (загружает) и предзагружает выбранные стандартные библиотеки в состояние L. (Предзагрузить означает добавить загрузчик библиотеки в таблицу package.preload, чтобы библиотеку можно было затребовать (require) позже в программе. Имейте в виду, что сам require предоставляется библиотекой пакетов. Если программа не загружает эту библиотеку, она не сможет ничего затребовать.)
Целое число load выбирает, какие библиотеки загружать; целое число preload выбирает, какие из незагруженных библиотек предзагружать. Оба являются масками, сформированными побитовым ИЛИ следующих констант:
LUA_GLIBK: базовая библиотека.LUA_LOADLIBK: библиотека пакетов.LUA_COLIBK: библиотека сопрограмм.LUA_STRLIBK: библиотека строк.LUA_UTF8LIBK: библиотека UTF-8.LUA_TABLIBK: библиотека таблиц.LUA_MATHLIBK: математическая библиотека.LUA_IOLIBK: библиотека ввода/вывода.LUA_OSLIBK: библиотека операционной системы.LUA_DBLIBK: библиотека отладки.
6.2 – Базовые функции
Базовая библиотека предоставляет ядро функций для Lua. Если вы не включаете эту библиотеку в свое приложение, вам следует тщательно проверить, нужно ли вам предоставлять реализации для некоторых ее средств.
assert (v [, message])
Вызывает ошибку, если значение ее аргумента v ложно (т.е. nil или false); в противном случае возвращает все свои аргументы. В случае ошибки message является объектом ошибки; при отсутствии по умолчанию используется "assertion failed!"
collectgarbage ([opt [, arg]])
Эта функция является универсальным интерфейсом к сборщику мусора. Она выполняет различные функции в зависимости от своего первого аргумента, opt:
"collect": Выполняет полный цикл сборки мусора. Это опция по умолчанию."stop": Останавливает автоматическое выполнение сборщика мусора. Сборщик будет запускаться только при явном вызове, до вызова для его перезапуска."restart": Перезапускает автоматическое выполнение сборщика мусора."count": Возвращает общий объем памяти, используемый Lua, в Кбайтах. Значение имеет дробную часть, так что умножение его на 1024 дает точное количество байтов, используемых Lua."step": Выполняет шаг сборки мусора. За этой опцией может следовать дополнительный аргумент, целое число с размером шага.Если размер — положительное
n, сборщик действует так, как будто было выделеноnновых байтов. Если размер равен нулю, сборщик выполняет базовый шаг. В инкрементальном режиме базовый шаг соответствует текущему размеру шага. В поколенческом режиме базовый шаг выполняет полную малую сборку или инкрементальный шаг, если сборщик его запланировал.В инкрементальном режиме функция возвращает
true, если шаг завершил цикл сборки. В поколенческом режиме функция возвращаетtrue, если шаг завершил большую сборку."isrunning": Возвращает булево значение, указывающее, запущен ли сборщик (т.е. не остановлен)."incremental": Изменяет режим сборщика на инкрементальный и возвращает предыдущий режим."generational": Изменяет режим сборщика на поколенческий и возвращает предыдущий режим."param": Изменяет и/или извлекает значения параметра сборщика. За этой опцией должны следовать один или два дополнительных аргумента: имя изменяемого или извлекаемого параметра (строка) и необязательное новое значение для этого параметра, целое число в диапазоне[0,100000]. Первый аргумент должен иметь одно из следующих значений:"minormul": Множитель малой сборки."majorminor": Множитель перехода от большой к малой сборке."minormajor": Множитель перехода от малой к большой сборке."pause": Пауза сборщика мусора."stepmul": Множитель шага."stepsize": Размер шага.
Вызов всегда возвращает предыдущее значение параметра. Если вызов не передает новое значение, значение остается неизменным.
Lua хранит эти значения в сжатом формате, поэтому значение, возвращаемое как предыдущее, может не точно совпадать с последним установленным значением.
См. §2.5 для более подробной информации о сборке мусора и некоторых из этих опций.
Эту функцию не следует вызывать из финализатора.
dofile ([filename])
Открывает указанный файл и выполняет его содержимое как чанк Lua, возвращая все значения, возвращенные чанком. При вызове без аргументов dofile выполняет содержимое стандартного ввода (stdin). В случае ошибок dofile передает ошибку своему вызывающему коду. (То есть dofile не работает в защищенном режиме.)
error (message [, level])
Вызывает ошибку (см. §2.3) с message в качестве объекта ошибки. Эта функция никогда не возвращает управление.
Обычно error добавляет некоторую информацию о позиции ошибки в начало сообщения, если сообщение является строкой. Аргумент level указывает, как получить позицию ошибки. При уровне 1 (по умолчанию) позиция ошибки — это место вызова функции error. Уровень 2 указывает на ошибку в месте вызова функции, которая вызвала error; и так далее. Передача уровня 0 предотвращает добавление информации о позиции ошибки в сообщение.
_G
Глобальная переменная (не функция), которая содержит глобальное окружение (см. §2.2). Сама Lua не использует эту переменную; изменение ее значения не влияет ни на какое окружение, и наоборот.
getmetatable (object)
Если object не имеет метатаблицы, возвращает nil. В противном случае, если метатаблица объекта имеет поле __metatable, возвращает связанное с ним значение. В противном случае возвращает метатаблицу данного объекта.
ipairs (t)
Возвращает три значения (функцию-итератор, значение t и 0), так что конструкция
for i,v in ipairs(t) do body end
будет итерироваться по парам ключ-значение (1,t[1]), (2,t[2]), …, до первого отсутствующего индекса.
load (chunk [, chunkname [, mode [, env]]])
Загружает чанк.
Если chunk — строка, то чанк является этой строкой. Если chunk — функция, load вызывает ее повторно для получения частей чанка. Каждый вызов chunk должен возвращать строку, которая конкатенируется с предыдущими результатами. Возврат пустой строки, nil или отсутствие возврата сигнализирует о конце чанка.
Если синтаксических ошибок нет, load возвращает скомпилированный чанк как функцию; в противном случае возвращает fail плюс сообщение об ошибке.
Когда вы загружаете главный чанк, результирующая функция всегда будет иметь ровно одно верхнее значение (upvalue) — переменную _ENV (см. §2.2). Однако, когда вы загружаете бинарный чанк, созданный из функции (см. string.dump), результирующая функция может иметь произвольное количество верхних значений, и нет гарантии, что ее первым верхним значением будет переменная _ENV. (Неглавная функция может даже не иметь верхнего значения _ENV.)
Независимо от этого, если результирующая функция имеет какие-либо верхние значения, ее первое верхнее значение устанавливается в значение env, если этот параметр указан, или в значение глобального окружения. Другие верхние значения инициализируются как nil. Все верхние значения являются новыми, то есть они не разделяются ни с какой другой функцией.
chunkname используется как имя чанка для сообщений об ошибках и отладочной информации (см. §4.7). При отсутствии по умолчанию используется chunk, если chunk — строка, или "=(load)" в противном случае.
Строка mode определяет, может ли чанк быть текстовым или бинарным (то есть предварительно скомпилированным чанком). Это может быть строка "b" (только бинарные чанки), "t" (только текстовые чанки) или "bt" (и бинарные, и текстовые). По умолчанию "bt".
Lua не проверяет целостность бинарных чанков. Злонамеренно созданные бинарные чанки могут привести к краху интерпретатора. Вы можете использовать параметр mode, чтобы предотвратить загрузку бинарных чанков.
loadfile ([filename [, mode [, env]]])
Аналогична load, но получает чанк из файла filename или из стандартного ввода, если имя файла не указано.
next (table [, index])
Позволяет программе обойти все поля таблицы. Ее первый аргумент — таблица, а второй аргумент — индекс в этой таблице. Вызов next возвращает следующий индекс таблицы и связанное с ним значение. При вызове с nil в качестве второго аргумента next возвращает начальный индекс и связанное с ним значение. При вызове с последним индексом или с nil в пустой таблице next возвращает nil. Если второй аргумент отсутствует, он интерпретируется как nil. В частности, вы можете использовать next(t) для проверки, пуста ли таблица.
Порядок перечисления индексов не определен, даже для числовых индексов. (Для обхода таблицы в числовом порядке используйте числовой for.)
Не следует присваивать значение несуществующему полю таблицы во время ее обхода. Однако вы можете изменять существующие поля. В частности, вы можете устанавливать существующие поля в nil.
pairs (t)
Если t имеет метаметод __pairs, вызывает его с t в качестве аргумента и возвращает первые четыре результата вызова.
В противном случае возвращает функцию next, таблицу t и два значения nil, так что конструкция
for k,v in pairs(t) do body end
будет итерироваться по всем парам ключ-значение таблицы t.
См. предостережения о модификации таблицы во время ее обхода в описании функции next.
pcall (f [, arg1, ···])
Вызывает функцию f с заданными аргументами в защищенном режиме. Это означает, что любая ошибка внутри f не распространяется дальше; вместо этого pcall перехватывает ошибку и возвращает код состояния. Ее первый результат — код состояния (булево значение), который равен true, если вызов завершился успешно без ошибок. В таком случае pcall также возвращает все результаты вызова после этого первого результата. В случае любой ошибки pcall возвращает false плюс объект ошибки. Обратите внимание, что ошибки, перехваченные pcall, не вызывают обработчик сообщений.
print (···)
Получает любое количество аргументов и выводит их значения в stdout, преобразуя каждый аргумент в строку по тем же правилам, что и tostring.
Функция print не предназначена для форматированного вывода, а только как быстрый способ показать значение, например, для отладки. Для полного контроля над выводом используйте string.format и io.write.
rawequal (v1, v2)
Проверяет, равен ли v1 v2, без вызова метаметода __eq. Возвращает булево значение.
rawget (table, index)
Получает реальное значение table[index], не используя метазначение __index. table должна быть таблицей; index может быть любым значением.
rawlen (v)
Возвращает длину объекта v, который должен быть таблицей или строкой, без вызова метаметода __len. Возвращает целое число.
rawset (table, index, value)
Устанавливает реальное значение table[index] в value, не используя метазначение __newindex. table должна быть таблицей, index — любым значением, отличным от nil и NaN, а value — любым значением Lua.
Эта функция возвращает table.
select (index, ···)
Если index — число, возвращает все аргументы после аргумента с номером index; отрицательное число индексирует с конца (-1 — последний аргумент). В противном случае index должен быть строкой "#", и select возвращает общее количество полученных дополнительных аргументов.
setmetatable (table, metatable)
Устанавливает метатаблицу для данной таблицы. Если metatable равно nil, удаляет метатаблицу данной таблицы. Если исходная метатаблица имеет поле __metatable, вызывает ошибку.
Эта функция возвращает table.
Чтобы изменить метатаблицу других типов из кода Lua, вы должны использовать библиотеку отладки (§6.11).
tonumber (e [, base])
При вызове без base tonumber пытается преобразовать свой аргумент в число. Если аргумент уже является числом или строкой, преобразуемой в число, tonumber возвращает это число; в противном случае возвращает fail.
Преобразование строк может давать целые числа или числа с плавающей точкой в соответствии с лексическими соглашениями Lua (см. §3.1). Строка может иметь начальные и конечные пробелы и знак.
При вызове с base аргумент e должен быть строкой, интерпретируемой как целое число в этой системе счисления. base может быть любым целым числом от 2 до 36 включительно. В системах счисления больше 10 буква ‘A’ (в верхнем или нижнем регистре) представляет 10, ‘B’ представляет 11 и так далее, ‘Z’ представляет 35. Если строка e не является допустимым числом в заданной системе счисления, функция возвращает fail.
tostring (v)
Получает значение любого типа и преобразует его в строку в удобочитаемом формате.
Если метатаблица v имеет поле __tostring, tostring вызывает соответствующее значение с v в качестве аргумента и использует результат вызова в качестве своего результата. В противном случае, если метатаблица v имеет поле __name со строковым значением, tostring может использовать эту строку в своем конечном результате.
Для полного контроля над тем, как преобразуются числа, используйте string.format.
type (v)
Возвращает тип своего единственного аргумента, закодированный в виде строки. Возможные результаты этой функции: "nil" (строка, а не значение nil), "number", "string", "boolean", "table", "function", "thread" и "userdata".
_VERSION
Глобальная переменная (не функция), которая содержит строку с текущей версией Lua. Текущее значение этой переменной — "Lua 5.5".
warn (msg1, ···)
Выдает предупреждение с сообщением, составленным путем конкатенации всех ее аргументов (которые должны быть строками).
По соглашению, однокомпонентное сообщение, начинающееся с ‘@’, предназначено быть управляющим сообщением, то есть сообщением для самой системы предупреждений. В частности, стандартная функция предупреждения в Lua распознает управляющие сообщения "@off" (для остановки выдачи предупреждений) и "@on" (для (пере)запуска выдачи); неизвестные управляющие сообщения игнорируются.
xpcall (f, msgh [, arg1, ···])
Эта функция аналогична pcall, за исключением того, что она устанавливает новый обработчик сообщений msgh.
6.3 – Управление сопрограммами
Эта библиотека включает операции для управления сопрограммами, которые находятся внутри таблицы coroutine. См. §2.6 для общего описания сопрограмм.
coroutine.close ([co])
Закрывает сопрограмму co, то есть закрывает все ее ожидающие закрытия переменные и переводит сопрограмму в мертвое состояние. По умолчанию co — это выполняющаяся сопрограмма.
Данная сопрограмма должна быть мертвой, приостановленной или выполняющейся. Для выполняющейся сопрограммы эта функция не возвращает управление. Вместо этого возвращается resume, который (пере)запустил сопрограмму.
Для других сопрограмм, в случае ошибки (либо исходной ошибки, остановившей сопрограмму, либо ошибок в методах закрытия), эта функция возвращает false плюс объект ошибки; в противном случае она возвращает true.
coroutine.create (f)
Создает новую сопрограмму с телом f. f должна быть функцией. Возвращает эту новую сопрограмму, объект типа "thread".
coroutine.isyieldable ([co])
Возвращает true, если сопрограмма co может прерваться (yield). По умолчанию co — это выполняющаяся сопрограмма.
Сопрограмма может прерываться, если она не является главным потоком и не находится внутри непрерываемой C-функции.
coroutine.resume (co [, val1, ···])
Запускает или продолжает выполнение сопрограммы co. При первом возобновлении сопрограммы она начинает выполнение своего тела. Значения val1, … передаются в качестве аргументов функции тела. Если сопрограмма прервалась, resume перезапускает ее; значения val1, … передаются как результаты из yield.
Если сопрограмма выполняется без ошибок, resume возвращает true плюс любые значения, переданные в yield (когда сопрограмма прерывается), или любые значения, возвращенные функцией тела (когда сопрограмма завершается). Если произошла ошибка, resume возвращает false плюс сообщение об ошибке.
coroutine.running ()
Возвращает выполняющуюся сопрограмму и булево значение, true, если выполняющаяся сопрограмма является главной.
coroutine.status (co)
Возвращает статус сопрограммы co в виде строки: "running", если сопрограмма выполняется (то есть это та, которая вызвала status); "suspended", если сопрограмма приостановлена в вызове yield или если она еще не начала выполняться; "normal", если сопрограмма активна, но не выполняется (то есть она возобновила другую сопрограмму); и "dead", если сопрограмма завершила свою функцию тела или остановилась с ошибкой.
coroutine.wrap (f)
Создает новую сопрограмму с телом f; f должна быть функцией. Возвращает функцию, которая возобновляет сопрограмму при каждом вызове. Любые аргументы, переданные этой функции, ведут себя как дополнительные аргументы для resume. Функция возвращает те же значения, что и resume, за исключением первого булева. В случае ошибки функция закрывает сопрограмму и распространяет ошибку.
coroutine.yield (···)
Приостанавливает выполнение вызывающей сопрограммы. Любые аргументы для yield передаются как дополнительные результаты в resume.
6.4 – Модули
Библиотека пакетов предоставляет базовые средства для загрузки модулей в Lua. Она экспортирует одну функцию непосредственно в глобальное окружение: require. Все остальное экспортируется в таблице package.
require (modname)
Загружает данный модуль. Функция начинает с проверки таблицы package.loaded, чтобы определить, загружен ли уже modname. Если да, то require возвращает значение, хранящееся в package.loaded[modname]. (Отсутствие второго результата в этом случае сигнализирует, что этому вызову не пришлось загружать модуль.) В противном случае она пытается найти загрузчик для модуля.
Чтобы найти загрузчик, require руководствуется таблицей package.searchers. Каждый элемент в этой таблице является функцией поиска, которая ищет модуль определенным способом. Изменяя эту таблицу, мы можем изменить способ поиска модуля функцией require. Следующее объяснение основано на конфигурации по умолчанию для package.searchers.
Сначала require запрашивает package.preload[modname]. Если там есть значение, это значение (которое должно быть функцией) является загрузчиком. В противном случае require ищет Lua-загрузчик, используя путь, хранящийся в package.path. Если это также не удается, она ищет C-загрузчик, используя путь, хранящийся в package.cpath. Если и это не удается, она пробует универсальный загрузчик (см. package.searchers).
Как только загрузчик найден, require вызывает загрузчик с двумя аргументами: modname и дополнительным значением, данными загрузчика, также возвращенными функцией поиска. Данные загрузчика могут быть любым значением, полезным для модуля; для стандартных функций поиска они указывают, где был найден загрузчик. (Например, если загрузчик был получен из файла, это дополнительное значение — путь к файлу.) Если загрузчик возвращает любое значение, отличное от nil, require присваивает возвращенное значение package.loaded[modname]. Если загрузчик не возвращает значение, отличное от nil, и не присвоил никакого значения package.loaded[modname], то require присваивает true этой записи. В любом случае require возвращает конечное значение package.loaded[modname]. Помимо этого значения, require также возвращает вторым результатом данные загрузчика, возвращенные функцией поиска, которые указывают, как require нашла модуль.
Если возникает какая-либо ошибка при загрузке или выполнении модуля, или если не удается найти ни одного загрузчика для модуля, require вызывает ошибку.
package.config
Строка, описывающая некоторые конфигурации времени компиляции для пакетов. Эта строка представляет собой последовательность строк:
- Первая строка — это строка-разделитель каталогов. По умолчанию
'\'для Windows и'/'для всех других систем. - Вторая строка — это символ, разделяющий шаблоны в пути. По умолчанию
';'. - Третья строка — это строка, обозначающая точки подстановки в шаблоне. По умолчанию
'?'. - Четвертая строка — это строка, которая в пути в Windows заменяется на каталог исполняемого файла. По умолчанию
'!'. - Пятая строка — это метка для игнорирования всего текста после нее при построении имени функции
luaopen_. По умолчанию'-'.
package.cpath
Строка с путем, используемым require для поиска C-загрузчика.
Lua инициализирует C-путь package.cpath так же, как и Lua-путь package.path, используя переменную окружения LUA_CPATH_5_5, или переменную окружения LUA_CPATH, или путь по умолчанию, определенный в luaconf.h.
package.loaded
Таблица, используемая require для контроля того, какие модули уже загружены. Когда вы запрашиваете модуль modname и package.loaded[modname] не равно false, require просто возвращает значение, хранящееся там.
Эта переменная является лишь ссылкой на реальную таблицу; присваивания этой переменной не изменяют таблицу, используемую require. Реальная таблица хранится в реестре C (см. §4.3), индексируемая ключом LUA_LOADED_TABLE (строкой).
package.loadlib (libname, funcname)
Динамически связывает главную программу с C-библиотекой libname.
Если funcname равно "*", то она только связывается с библиотекой, делая символы, экспортируемые библиотекой, доступными для других динамически связанных библиотек. В противном случае она ищет функцию funcname внутри библиотеки и возвращает эту функцию как C-функцию. Таким образом, funcname должна соответствовать прототипу lua_CFunction (см. lua_CFunction).
Это функция низкого уровня. Она полностью обходит систему пакетов и модулей. В отличие от require, она не выполняет поиск по путям и не добавляет автоматически расширения. libname должно быть полным именем файла C-библиотеки, включая при необходимости путь и расширение. funcname должно быть точным именем, экспортируемым C-библиотекой (которое может зависеть от используемого C-компилятора и компоновщика).
Эта функциональность не поддерживается стандартом ISO C. Поэтому loadlib доступна только на некоторых платформах: Linux, Windows, Mac OS X, Solaris, BSD, а также других Unix-системах, поддерживающих стандарт dlfcn.
Эта функция по своей сути небезопасна, так как позволяет Lua вызывать любую функцию в любой читаемой динамической библиотеке в системе. (Lua вызывает любую функцию, предполагая, что функция имеет правильный прототип и соблюдает правильный протокол (см. lua_CFunction). Поэтому вызов произвольной функции в произвольной динамической библиотеке чаще всего приводит к нарушению доступа.)
package.path
Строка с путем, используемым require для поиска Lua-загрузчика.
При запуске Lua инициализирует эту переменную значением переменной окружения LUA_PATH_5_5 или переменной окружения LUA_PATH, или путем по умолчанию, определенным в luaconf.h, если эти переменные окружения не определены. ";;" в значении переменной окружения заменяется путем по умолчанию.
package.preload
Таблица для хранения загрузчиков для конкретных модулей (см. require).
Эта переменная является лишь ссылкой на реальную таблицу; присваивания этой переменной не изменяют таблицу, используемую require. Реальная таблица хранится в реестре C (см. §4.3), индексируемая ключом LUA_PRELOAD_TABLE (строкой).
package.searchers
Таблица, используемая require для управления поиском модулей.
Каждая запись в этой таблице является функцией поиска. При поиске модуля require вызывает каждую из этих функций поиска в порядке возрастания, передавая имя модуля (аргумент, переданный в require) в качестве единственного аргумента. Если функция поиска находит модуль, она возвращает другую функцию — загрузчик модуля, плюс дополнительное значение — данные загрузчика, которые будут переданы этому загрузчику и возвращены вторым результатом из require. Если она не может найти модуль, она возвращает строку с объяснением причины (или nil, если ей нечего сказать).
Lua инициализирует эту таблицу четырьмя функциями поиска.
Первая функция поиска просто ищет загрузчик в таблице package.preload.
Вторая функция поиска ищет загрузчик как Lua-библиотеку, используя путь, хранящийся в package.path. Поиск выполняется, как описано в функции package.searchpath.
Третья функция поиска ищет загрузчик как C-библиотеку, используя путь, заданный переменной package.cpath. Поиск также выполняется, как описано в функции package.searchpath. Например, если C-путь — это строка
"./?.so;./?.dll;/usr/local/?/init.so"
функция поиска для модуля foo попытается открыть файлы ./foo.so, ./foo.dll и /usr/local/foo/init.so в этом порядке. Найдя C-библиотеку, эта функция поиска сначала использует средство динамической загрузки для связывания приложения с библиотекой. Затем она пытается найти C-функцию внутри библиотеки, которая будет использоваться в качестве загрузчика. Имя этой C-функции — это строка "luaopen_", конкатенированная с копией имени модуля, где каждая точка заменена на подчеркивание. Более того, если имя модуля содержит дефис, его суффикс после (и включая) первого дефиса удаляется. Например, если имя модуля a.b.c-v2.1, имя функции будет luaopen_a_b_c.
Четвертая функция поиска пробует универсальный загрузчик. Она ищет в C-пути библиотеку для корневого имени заданного модуля. Например, при запросе a.b.c она будет искать C-библиотеку для a. Если она найдена, она ищет в ней функцию открытия для подмодуля; в нашем примере это будет luaopen_a_b_c. С помощью этого средства пакет может упаковать несколько C-подмодулей в одну библиотеку, при этом каждый подмодуль сохраняет свою оригинальную функцию открытия.
Все функции поиска, кроме первой (предзагрузки), возвращают в качестве дополнительного значения путь к файлу, где был найден модуль, как возвращено package.searchpath. Первая функция поиска всегда возвращает строку ":preload:".
Функции поиска не должны вызывать ошибок и не должны иметь побочных эффектов в Lua. (Они могут иметь побочные эффекты в C, например, связывая приложение с библиотекой.)
package.searchpath (name, path [, sep [, rep]])
Ищет заданное name в заданном path.
Путь — это строка, содержащая последовательность шаблонов, разделенных точкой с запятой. Для каждого шаблона функция заменяет каждый вопросительный знак (если есть) в шаблоне копией name, в которой все вхождения sep (по умолчанию точка) заменены на rep (по умолчанию системный разделитель каталогов), а затем пытается открыть полученное имя файла.
Например, если путь — строка
"./?.lua;./?.lc;/usr/local/?/init.lua"
поиск имени foo.a попытается открыть файлы ./foo/a.lua, ./foo/a.lc и /usr/local/foo/a/init.lua в этом порядке.
Возвращает результирующее имя первого файла, который удается открыть в режиме чтения (после закрытия файла), или fail плюс сообщение об ошибке, если ни один не подошел. (Это сообщение об ошибке перечисляет все имена файлов, которые пытались открыть.)
6.5 – Манипуляции со строками
Эта библиотека предоставляет общие функции для работы со строками, такие как поиск и извлечение подстрок, а также сопоставление с образцом. При индексации строки в Lua первый символ находится в позиции 1 (а не 0, как в C). Индексы могут быть отрицательными и интерпретируются как индексация с конца строки. Таким образом, последний символ находится в позиции -1, и так далее.
Библиотека строк предоставляет все свои функции внутри таблицы string. Она также устанавливает метатаблицу для строк, где поле __index указывает на таблицу string. Поэтому вы можете использовать строковые функции в объектно-ориентированном стиле. Например, string.byte(s,i) можно записать как s:byte(i).
Библиотека строк предполагает однобайтовые кодировки символов.
string.byte (s [, i [, j]])
Возвращает внутренние числовые коды символов s[i], s[i+1], …, s[j]. Значение по умолчанию для i — 1; значение по умолчанию для j — i. Эти индексы корректируются по тем же правилам, что и для функции string.sub.
Числовые коды не обязательно переносимы между платформами.
string.char (···)
Получает ноль или более целых чисел. Возвращает строку длиной, равной количеству аргументов, в которой каждый символ имеет внутренний числовой код, равный соответствующему аргументу.
Числовые коды не обязательно переносимы между платформами.
string.dump (function [, strip])
Возвращает строку, содержащую бинарное представление (бинарный чанк) заданной функции, так что последующая load этой строки вернет копию функции (но с новыми верхними значениями). Если strip — истинное значение, бинарное представление может не включать всю отладочную информацию о функции для экономии места.
У функций с верхними значениями сохраняется только их количество. При (пере)загрузке эти верхние значения получают новые экземпляры. (Подробности о том, как эти верхние значения инициализируются, см. в описании функции load. Вы можете использовать библиотеку отладки для сериализации и перезагрузки верхних значений функции способом, адекватным вашим потребностям.)
string.find (s, pattern [, init [, plain]])
Ищет первое совпадение с pattern (см. §6.5.1) в строке s. Если находит совпадение, find возвращает индексы s, где это вхождение начинается и заканчивается; в противном случае возвращает fail. Третий, необязательный числовой аргумент init указывает, с какой позиции начинать поиск; его значение по умолчанию 1, и оно может быть отрицательным. Значение true в качестве четвертого, необязательного аргумента plain отключает средства сопоставления с образцом, так что функция выполняет простой “поиск подстроки”, при этом ни один символ в pattern не считается магическим.
Если в образце есть захваты, то при успешном совпадении захваченные значения также возвращаются после двух индексов.
string.format (formatstring, ···)
Возвращает отформатированную версию своего переменного числа аргументов в соответствии с описанием, данным в первом аргументе, который должен быть строкой. Строка формата следует тем же правилам, что и функция ISO C sprintf. Допустимые спецификаторы преобразования: A, a, c, d, E, e, f, G, g, i, o, p, s, u, X, x и '%', а также не-C спецификатор q. Допустимые флаги: '-', '+', '#', '0' и ' ' (пробел). Как ширина, так и точность, если указаны, ограничены двумя цифрами.
Спецификатор q форматирует булевы значения, nil, числа и строки таким образом, что результат является допустимой константой в исходном коде Lua. Булевы значения и nil записываются очевидным образом (true, false, nil). Числа с плавающей точкой записываются в шестнадцатеричном виде для сохранения полной точности. Строка записывается в двойных кавычках с использованием escape-последовательностей, где это необходимо, чтобы гарантировать, что она может быть безопасно прочитана обратно интерпретатором Lua. Например, вызов
string.format('%q', 'a string with "quotes" and \n new line')
может произвести строку:
"a string with \"quotes\" and \
new line"
Этот спецификатор не поддерживает модификаторы (флаги, ширину, точность).
Спецификаторы преобразования A, a, E, e, f, G и g ожидают число в качестве аргумента. Спецификаторы c, d, i, o, u, X и x ожидают целое число. Когда Lua скомпилирован с компилятором C89, спецификаторы A и a (шестнадцатеричные числа с плавающей точкой) не поддерживают модификаторы.
Спецификатор s ожидает строку; если его аргумент не является строкой, он преобразуется в нее по тем же правилам, что и tostring. Если спецификатор имеет какой-либо модификатор, соответствующий строковый аргумент не должен содержать встроенных нулей.
Спецификатор p форматирует указатель, возвращенный lua_topointer. Это дает уникальный строковый идентификатор для таблиц, пользовательских данных, потоков, строк и функций. Для других значений (числа, nil, булевы значения) этот спецификатор дает строку, представляющую указатель NULL.
string.gmatch (s, pattern [, init])
Возвращает функцию-итератор, которая при каждом вызове возвращает следующие захваты из pattern (см. §6.5.1) по строке s. Если pattern не указывает захватов, то при каждом вызове выдается все совпадение целиком. Третий, необязательный числовой аргумент init указывает, с какой позиции начинать поиск; его значение по умолчанию 1, и оно может быть отрицательным.
В качестве примера, следующий цикл будет итерироваться по всем словам из строки s, печатая по одному в строке:
s = "hello world from Lua"
for w in string.gmatch(s, "%a+") do
print(w)
end
Следующий пример собирает все пары key=value из заданной строки в таблицу:
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
end
Для этой функции символ '^' в начале образца не работает как якорь, так как это предотвратило бы итерацию.
string.gsub (s, pattern, repl [, n])
Возвращает копию s, в которой все (или первые n, если указано) вхождения pattern (см. §6.5.1) были заменены строкой замены, указанной в repl, которая может быть строкой, таблицей или функцией. gsub также возвращает вторым значением общее количество произошедших совпадений. Имя gsub происходит от Global SUBstitution.
Если repl — строка, то ее значение используется для замены. Символ % работает как escape-символ: любая последовательность в repl вида %d, где d от 1 до 9, обозначает значение d-й захваченной подстроки; последовательность %0 обозначает все совпадение целиком; последовательность %% обозначает одиночный %.
Если repl — таблица, то к таблице выполняется запрос для каждого совпадения, используя первый захват в качестве ключа.
Если repl — функция, то эта функция вызывается каждый раз при совпадении, при этом все захваченные подстроки передаются в качестве аргументов по порядку.
В любом случае, если образец не указывает захватов, он ведет себя так, как будто весь образец находится внутри захвата.
Если значение, возвращенное запросом к таблице или вызовом функции, является строкой или числом, оно используется в качестве строки замены; в противном случае, если оно false или nil, замены не происходит (то есть исходное совпадение сохраняется в строке).
Вот несколько примеров:
x = string.gsub("hello world", "(%w+)", "%1 %1")
-- x="hello hello world world"
x = string.gsub("hello world", "%w+", "%0 %0", 1)
-- x="hello hello world"
x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
-- x="world hello Lua from"
x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
-- x="home = /home/roberto, user = roberto"
x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
return load(s)()
end)
-- x="4+5 = 9"
local t = {name="lua", version="5.5"}
x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
-- x="lua-5.5.tar.gz"
string.len (s)
Получает строку и возвращает ее длину. Пустая строка "" имеет длину 0. Встроенные нули считаются, поэтому "a\000bc\000" имеет длину 5.
string.lower (s)
Получает строку и возвращает копию этой строки, в которой все заглавные буквы заменены на строчные. Все остальные символы остаются без изменений. Определение того, что является заглавной буквой, зависит от текущей локали.
string.match (s, pattern [, init])
Ищет первое совпадение с образцом (см. §6.5.1) в строке s. Если находит, match возвращает захваты из образца; в противном случае возвращает fail. Если образец не указывает захватов, возвращается все совпадение целиком. Третий, необязательный числовой аргумент init указывает, с какой позиции начинать поиск; его значение по умолчанию 1, и оно может быть отрицательным.
string.pack (fmt, v1, v2, ···)
Возвращает бинарную строку, содержащую значения v1, v2 и т.д., сериализованные в бинарной форме (упакованные) в соответствии со строкой формата fmt (см. §6.5.2).
string.packsize (fmt)
Возвращает длину строки, получаемой в результате string.pack с заданным форматом. Строка формата не может иметь опции переменной длины 's' или 'z' (см. §6.5.2).
string.rep (s, n [, sep])
Возвращает строку, которая является конкатенацией n копий строки s, разделенных строкой sep. Значение по умолчанию для sep — пустая строка (то есть без разделителя). Возвращает пустую строку, если n не положительно.
(Обратите внимание, что очень легко исчерпать память вашей машины одним вызовом этой функции.)
string.reverse (s)
Возвращает строку, которая является перевернутой строкой s.
string.sub (s, i [, j])
Возвращает подстроку s, которая начинается с i и продолжается до j; i и j могут быть отрицательными. Если j отсутствует, предполагается, что оно равно -1 (что соответствует длине строки). В частности, вызов string.sub(s,1,j) возвращает префикс s длиной j, а string.sub(s,-i) (для положительного i) возвращает суффикс s длиной i.
Если после преобразования отрицательных индексов i меньше 1, оно корректируется до 1. Если j больше длины строки, оно корректируется до этой длины. Если после этих коррекций i больше j, функция возвращает пустую строку.
string.unpack (fmt, s [, pos])
Возвращает значения, упакованные в строке s (см. string.pack) в соответствии со строкой формата fmt (см. §6.5.2). Необязательный параметр pos указывает, с какой позиции начинать чтение в s (по умолчанию 1). После прочитанных значений эта функция также возвращает индекс первого непрочитанного байта в s.
string.upper (s)
Получает строку и возвращает копию этой строки, в которой все строчные буквы заменены на заглавные. Все остальные символы остаются без изменений. Определение того, что является строчной буквой, зависит от текущей локали.
6.5.1 – Образцы (Patterns)
Образцы в Lua описываются обычными строками, которые интерпретируются как образцы функциями сопоставления с образцом string.find, string.gmatch, string.gsub и string.match. В этом разделе описывается синтаксис и значение (то есть что они сопоставляют) этих строк.
Класс символов:
Класс символов используется для представления набора символов. Следующие комбинации допустимы при описании класса символов:
x: (гдеxне является одним из магических символов^$()%.[]*+-?) представляет сам символx..: (точка) представляет все символы.%a: представляет все буквы.%c: представляет все управляющие символы.%d: представляет все цифры.%g: представляет все печатные символы, кроме пробела.%l: представляет все строчные буквы.%p: представляет все знаки пунктуации.%s: представляет все пробельные символы.%u: представляет все заглавные буквы.%w: представляет все буквенно-цифровые символы.%x: представляет все шестнадцатеричные цифры.%x: (гдеx— любой небуквенно-цифровой символ) представляет сам символx. Это стандартный способ экранирования магических символов. Любой небуквенно-цифровой символ (включая все знаки пунктуации, даже немагические) может быть предварен'%', чтобы представить самого себя в образце.[set]: представляет класс, который является объединением всех символов вset. Диапазон символов может быть указан путем разделения конечных символов диапазона в порядке возрастания с помощью'-'. Все классы%x, описанные выше, также могут использоваться как компоненты вset. Все остальные символы вsetпредставляют сами себя. Например,[%w_](или[_%w]) представляет все буквенно-цифровые символы плюс подчеркивание,[0-7]представляет восьмеричные цифры, а[0-7%l%-]представляет восьмеричные цифры плюс строчные буквы плюс символ'-'.Вы можете поместить закрывающую квадратную скобку в набор, расположив ее как первый символ в наборе. Вы можете поместить дефис в набор, расположив его как первый или последний символ в наборе. (Вы также можете использовать экранирование для обоих случаев.)
Взаимодействие между диапазонами и классами не определено. Поэтому образцы типа
[%a-z]или[a-%%]не имеют смысла.[^set]: представляет дополнение кset, гдеsetинтерпретируется как выше.
Для всех классов, представленных одиночными буквами (%a, %c и т.д.), соответствующая заглавная буква представляет дополнение класса. Например, %S представляет все непробельные символы.
Определения буквы, пробела и других групп символов зависят от текущей локали. В частности, класс [a-z] может быть не эквивалентен %l.
Элемент образца:
Элементом образца может быть
- одиночный класс символов, который соответствует любому одиночному символу в классе;
- одиночный класс символов, за которым следует
'*', что соответствует последовательностям из нуля или более символов в классе. Эти элементы повторения всегда будут соответствовать самой длинной возможной последовательности; - одиночный класс символов, за которым следует
'+', что соответствует последовательностям из одного или более символов в классе. Эти элементы повторения всегда будут соответствовать самой длинной возможной последовательности; - одиночный класс символов, за которым следует
'-', что также соответствует последовательностям из нуля или более символов в классе. В отличие от'*', эти элементы повторения всегда будут соответствовать самой короткой возможной последовательности; - одиночный класс символов, за которым следует
'?', что соответствует нулю или одному вхождению символа в классе. Всегда соответствует одному вхождению, если это возможно; %n, дляnот 1 до 9; такой элемент соответствует подстроке, равнойn-й захваченной строке (см. ниже);%bxy, гдеxиy— два различных символа; такой элемент соответствует строкам, которые начинаются сx, заканчиваются наyи гдеxиyсбалансированы. Это означает, что если читать строку слева направо, считая+1дляxи-1дляy, конечныйy— это первыйy, где счетчик достигает 0. Например, элемент%b()соответствует выражениям со сбалансированными круглыми скобками.%f[set], образец границы; такой элемент соответствует пустой строке в любой позиции, такой что следующий символ принадлежитset, а предыдущий символ не принадлежитset. Наборsetинтерпретируется, как описано ранее. Начало и конец строки обрабатываются так, как если бы они были символом'\0'.
Образец:
Образец — это последовательность элементов образца. Символ '^' в начале образца привязывает совпадение к началу строки. Символ '$' в конце образца привязывает совпадение к концу строки. В других позициях '^' и '$' не имеют специального значения и представляют сами себя.
Захваты:
Образец может содержать подобразцы, заключенные в круглые скобки; они описывают захваты. Когда совпадение успешно, подстроки строки, соответствующие захватам, сохраняются (захватываются) для будущего использования. Захваты нумеруются в соответствии с их левыми скобками. Например, в образце "(a*(.)%w(%s*))" часть строки, соответствующая "a*(.)%w(%s*)", сохраняется как первый захват и, следовательно, имеет номер 1; символ, соответствующий ".", захватывается с номером 2, а часть, соответствующая "%s*", имеет номер 3.
В качестве особого случая, захват () захватывает текущую позицию в строке (число). Например, если применить образец "()aa()" к строке "flaaap", будет два захвата: 3 и 5.
Множественные совпадения:
Функция string.gsub и итератор string.gmatch ищут множественные вхождения заданного образца в строке. Для этих функций новое совпадение считается допустимым, только если оно заканчивается хотя бы на один байт позже конца предыдущего совпадения. Другими словами, автомат образцов никогда не принимает пустую строку в качестве совпадения сразу после другого совпадения. В качестве примера рассмотрим результаты следующего кода:
> string.gsub("abc", "()a*()", print);
--> 1 2
--> 3 3
--> 4 4
Второй и третий результаты получаются, когда Lua сопоставляет пустую строку после 'b' и еще одну после 'c'. Lua не сопоставляет пустую строку после 'a', потому что она закончилась бы в той же позиции, что и предыдущее совпадение.
6.5.2 – Строки формата для Pack и Unpack
Первым аргументом для string.pack, string.packsize и string.unpack является строка формата, которая описывает структуру создаваемой или читаемой структуры.
Строка формата — это последовательность опций преобразования. Опции преобразования следующие:
<: устанавливает little-endian (порядок байтов от младшего к старшему)>: устанавливает big-endian (порядок байтов от старшего к младшему)=: устанавливает native-endian (родной порядок байтов)![n]: устанавливает максимальное выравнивание вn(по умолчанию родное выравнивание)b: знаковый байт (char)B: беззнаковый байт (unsigned char)h: знаковыйshort(родного размера)H: беззнаковыйshort(родного размера)l: знаковыйlong(родного размера)L: беззнаковыйlong(родного размера)j:lua_IntegerJ:lua_UnsignedT:size_t(родного размера)i[n]: знаковыйintразмеромnбайт (по умолчанию родной размер)I[n]: беззнаковыйintразмеромnбайт (по умолчанию родной размер)f:float(родного размера)d:double(родного размера)n:lua_Numbercn: строка фиксированного размера длинойnбайтz: строка, завершающаяся нулемs[n]: строка, предваренная своей длиной, закодированной как беззнаковое целое размеромnбайт (по умолчаниюsize_t)x: один байт заполненияXop: пустой элемент, который выравнивает в соответствии с опциейop(которая в остальном игнорируется)' ': (пробел) игнорируется
(Запись "[n]" означает необязательное целое число.) За исключением заполнения, пробелов и конфигураций (опции "xX <=>!"), каждая опция соответствует аргументу в string.pack или результату в string.unpack.
Для опций "!n", "sn", "in" и "In" n может быть любым целым числом от 1 до 16. Все целочисленные опции проверяют переполнение; string.pack проверяет, помещается ли данное значение в заданный размер; string.unpack проверяет, помещается ли прочитанное значение в целое число Lua. Для беззнаковых опций целые числа Lua также рассматриваются как беззнаковые.
Любая строка формата начинается так, как если бы перед ней стояло "!1=", то есть с максимальным выравниванием 1 (без выравнивания) и родным порядком байтов.
Родной порядок байтов предполагает, что вся система имеет либо big-endian, либо little-endian порядок. Функции упаковки не будут корректно эмулировать поведение форматов со смешанным порядком байтов.
Выравнивание работает следующим образом: Для каждой опции формат дополняется до тех пор, пока данные не начнутся со смещением, кратным минимуму между размером опции и максимальным выравниванием; этот минимум должен быть степенью двойки. Опции "c" и "z" не выравниваются; опция "s" следует выравниванию своего начального целого.
Все заполнение заполняется нулями в string.pack и игнорируется в string.unpack.
6.6 – Поддержка UTF-8
Эта библиотека предоставляет базовую поддержку кодировки UTF-8. Она предоставляет все свои функции внутри таблицы utf8. Эта библиотека не предоставляет никакой поддержки Unicode, кроме обработки кодировки. Любая операция, требующая знания смысла символа, например, классификация символов, выходит за рамки ее возможностей.
Если не указано иное, все функции, ожидающие позицию в байтах в качестве параметра, предполагают, что данная позиция является либо началом байтовой последовательности, либо длиной строки плюс один. Как и в библиотеке строк, отрицательные индексы отсчитываются от конца строки.
Функции, создающие байтовые последовательности, принимают все значения вплоть до 0x7FFFFFFF, как определено в оригинальной спецификации UTF-8; это подразумевает байтовые последовательности длиной до шести байт.
Функции, интерпретирующие байтовые последовательности, принимают только допустимые последовательности (правильно сформированные и не избыточные). По умолчанию они принимают только байтовые последовательности, дающие допустимые кодовые точки Unicode, отвергая значения больше 10FFFF и суррогаты. Булев аргумент lax, если доступен, отменяет эти проверки, так что принимаются все значения вплоть до 0x7FFFFFFF. (Неправильно сформированные и избыточные последовательности по-прежнему отвергаются.)
utf8.char (···)
Получает ноль или более целых чисел, преобразует каждое в соответствующую ему байтовую последовательность UTF-8 и возвращает строку с конкатенацией всех этих последовательностей.
utf8.charpattern
Образец (строка, а не функция) "[\0-\x7F\xC2-\xFD][\x80-\xBF]*" (см. §6.5.1), который соответствует ровно одной байтовой последовательности UTF-8, при условии, что строка является допустимой строкой UTF-8.
utf8.codes (s [, lax])
Возвращает значения таким образом, что конструкция
for p, c in utf8.codes(s) do body end
будет итерироваться по всем символам UTF-8 в строке s, где p — позиция (в байтах), а c — кодовая точка каждого символа. Вызывает ошибку, если встречает недопустимую байтовую последовательность.
utf8.codepoint (s [, i [, j [, lax]]])
Возвращает кодовые точки (как целые числа) из всех символов в s, которые начинаются между байтовыми позициями i и j (обе включительно). Значение по умолчанию для i — 1, а для j — i. Вызывает ошибку, если встречает недопустимую байтовую последовательность.
utf8.len (s [, i [, j [, lax]]])
Возвращает количество символов UTF-8 в строке s, которые начинаются между позициями i и j (обе включительно). Значение по умолчанию для i — 1, а для j — -1. Если находит недопустимую байтовую последовательность, возвращает fail плюс позицию первого недопустимого байта.
utf8.offset (s, n [, i])
Возвращает позицию n-го символа s (начиная с байтовой позиции i) в виде двух целых чисел: индекс (в байтах), где начинается его кодировка, и индекс (в байтах), где она заканчивается.
Если указанный символ находится сразу после конца s, функция ведет себя так, как если бы там был '\0'. Если указанный символ не находится ни в строке, ни сразу после ее конца, функция возвращает fail.
Отрицательное n получает символы до позиции i. По умолчанию i равно 1, когда n неотрицательно, и #s + 1 в противном случае, так что utf8.offset(s,-n) получает смещение n-го символа с конца строки.
В качестве особого случая, когда n равно 0, функция возвращает начало и конец кодировки символа, который содержит i-й байт s.
Эта функция предполагает, что s является допустимой строкой UTF-8.
6.7 – Манипуляции с таблицами
Эта библиотека предоставляет общие функции для манипуляции таблицами. Она предоставляет все свои функции внутри таблицы table.
Помните, что всякий раз, когда операция требует длины таблицы, применяются все предостережения относительно оператора длины (см. §3.4.7). Все функции игнорируют нечисловые ключи в таблицах, переданных в качестве аргументов.
table.concat (list [, sep [, i [, j]]])
Для списка, где все элементы являются строками или числами, возвращает строку list[i]..sep..list[i+1] ... sep..list[j]. Значение по умолчанию для sep — пустая строка, для i — 1, для j — #list. Если i больше j, возвращает пустую строку.
table.create (nseq [, nrec])
Создает новую пустую таблицу, предварительно выделяя память. Это предварительное выделение может помочь производительности и сэкономить память, если вы заранее знаете, сколько элементов будет в таблице.
Параметр nseq — это подсказка о том, сколько элементов будет в таблице в виде последовательности. Необязательный параметр nrec — это подсказка о том, сколько других элементов будет в таблице; по умолчанию ноль.
table.insert (list, [pos,] value)
Вставляет элемент value в позицию pos в списке list, сдвигая вверх элементы list[pos], list[pos+1], ..., list[#list]. Значение по умолчанию для pos — #list+1, так что вызов table.insert(t,x) вставляет x в конец списка t.
table.move (a1, f, e, t [,a2])
Перемещает элементы из таблицы a1 в таблицу a2, выполняя эквивалент следующего множественного присваивания: a2[t],... = a1[f],...,a1[e]. По умолчанию a2 равна a1. Диапазон назначения может перекрываться с диапазоном источника. Количество перемещаемых элементов должно помещаться в целое число Lua. Если f больше e, ничего не перемещается.
Возвращает таблицу назначения a2.
table.pack (···)
Возвращает новую таблицу со всеми аргументами, сохраненными под ключами 1, 2 и т.д., и с полем "n", содержащим общее количество аргументов. Обратите внимание, что результирующая таблица может не быть последовательностью, если некоторые аргументы равны nil.
table.remove (list [, pos])
Удаляет из списка list элемент в позиции pos, возвращая значение удаленного элемента. Когда pos — целое число между 1 и #list, она сдвигает вниз элементы list[pos+1], list[pos+2], ..., list[#list] и стирает элемент list[#list]; Индекс pos также может быть 0, когда #list равно 0, или #list + 1.
Значение по умолчанию для pos — #list, так что вызов table.remove(l) удаляет последний элемент списка l.
table.sort (list [, comp])
Сортирует элементы списка в заданном порядке, на месте, от list[1] до list[#list]. Если указана comp, она должна быть функцией, которая получает два элемента списка и возвращает true, если первый элемент должен стоять перед вторым в конечном порядке, так что после сортировки i <= j влечет not comp(list[j],list[i]). Если comp не указана, используется стандартный оператор Lua <.
Функция comp должна определять непротиворечивый порядок; более формально, функция должна определять строгий слабый порядок. (Слабый порядок похож на полный порядок, но он может приравнивать разные элементы для целей сравнения.)
Алгоритм сортировки не является стабильным: Различные элементы, считающиеся равными при заданном порядке, могут изменить свое относительное положение в результате сортировки.
table.unpack (list [, i [, j]])
Возвращает элементы из данного списка. Эта функция эквивалентна
return list[i], list[i+1], ..., list[j]
По умолчанию i равно 1, а j равно #list.
6.8 – Математические функции
Эта библиотека предоставляет базовые математические функции. Она предоставляет все свои функции и константы внутри таблицы math. Функции с аннотацией “integer/float” дают целочисленные результаты для целочисленных аргументов и результаты с плавающей точкой для нецелочисленных аргументов. Функции округления math.ceil, math.floor и math.modf возвращают целое число, если результат помещается в диапазон целых чисел, или число с плавающей точкой в противном случае.
math.abs (x)
Возвращает максимальное значение между x и -x. (integer/float)
math.acos (x)
Возвращает арккосинус x (в радианах).
math.asin (x)
Возвращает арксинус x (в радианах).
math.atan (y [, x])
Возвращает арктангенс y/x (в радианах), используя знаки обоих аргументов для определения квадранта результата. Также корректно обрабатывает случай, когда x равен нулю.
Значение по умолчанию для x — 1, так что вызов math.atan(y) возвращает арктангенс y.
math.ceil (x)
Возвращает наименьшее целое значение, большее или равное x.
math.cos (x)
Возвращает косинус x (предполагается, что x в радианах).
math.deg (x)
Преобразует угол x из радиан в градусы.
math.exp (x)
Возвращает значение ex (где e — основание натуральных логарифмов).
math.floor (x)
Возвращает наибольшее целое значение, меньшее или равное x.
math.fmod (x, y)
Возвращает остаток от деления x на y, который округляет частное в сторону нуля. (integer/float)
math.frexp (x)
Возвращает два числа m и e такие, что x = m * 2^e, где e — целое число. Когда x равен нулю, NaN, +inf или -inf, m равен x; в противном случае абсолютное значение m находится в диапазоне [0.5, 1).
math.huge
Значение с плавающей точкой HUGE_VAL, значение, большее любого другого числового значения.
math.ldexp (m, e)
Возвращает m * 2^e, где e — целое число.
math.log (x [, base])
Возвращает логарифм x по заданному основанию base. По умолчанию base равно e (так что функция возвращает натуральный логарифм x).
math.max (x, ···)
Возвращает аргумент с максимальным значением в соответствии с оператором Lua <.
math.maxinteger
Целое число с максимальным значением для целого числа.
math.min (x, ···)
Возвращает аргумент с минимальным значением в соответствии с оператором Lua <.
math.mininteger
Целое число с минимальным значением для целого числа.
math.modf (x)
Возвращает целую часть x и дробную часть x. Ее второй результат всегда является числом с плавающей точкой.
math.pi
Значение π.
math.rad (x)
Преобразует угол x из градусов в радианы.
math.random ([m [, n]])
При вызове без аргументов возвращает псевдослучайное число с плавающей точкой с равномерным распределением в диапазоне [0, 1). При вызове с двумя целыми числами m и n, math.random возвращает псевдослучайное целое число с равномерным распределением в диапазоне [m, n]. Вызов math.random(n) для положительного n эквивалентен math.random(1,n). Вызов math.random(0) производит целое число, в котором все биты (псевдо)случайны.
Эта функция использует алгоритм xoshiro256** для получения псевдослучайных 64-битных целых чисел, которые являются результатами вызовов с аргументом 0. Другие результаты (диапазоны и числа с плавающей точкой) несмещенно извлекаются из этих целых чисел.
Lua инициализирует свой генератор псевдослучайных чисел эквивалентом вызова math.randomseed без аргументов, так что math.random должен генерировать разные последовательности результатов при каждом запуске программы.
math.randomseed ([x [, y]])
При вызове хотя бы с одним аргументом целочисленные параметры x и y объединяются в зерно (seed), которое используется для реинициализации генератора псевдослучайных чисел; одинаковые зерна производят одинаковые последовательности чисел. По умолчанию y равно нулю.
При вызове без аргументов Lua генерирует зерно со слабой попыткой случайности.
Эта функция возвращает два компонента зерна, которые были фактически использованы, так что их повторная установка повторяет последовательность.
Чтобы обеспечить требуемый уровень случайности начального состояния (или, наоборот, иметь детерминированную последовательность, например, при отладке программы), следует вызывать math.randomseed с явными аргументами.
math.sin (x)
Возвращает синус x (предполагается, что x в радианах).
math.sqrt (x)
Возвращает квадратный корень из x. (Вы также можете использовать выражение x^0.5 для вычисления этого значения.)
math.tan (x)
Возвращает тангенс x (предполагается, что x в радианах).
math.tointeger (x)
Если значение x может быть преобразовано в целое число, возвращает это целое число. В противном случае возвращает fail.
math.type (x)
Возвращает "integer", если x — целое число, "float", если это число с плавающей точкой, или fail, если x не является числом.
math.ult (m, n)
Возвращает булево значение, true, если и только если целое число m меньше целого числа n при их сравнении как беззнаковых целых чисел.
6.9 – Средства ввода и вывода
Библиотека ввода/вывода предоставляет два разных стиля для манипуляции файлами. Первый использует неявные файловые дескрипторы; то есть существуют операции для установки файла ввода по умолчанию и файла вывода по умолчанию, и все операции ввода/вывода выполняются с этими файлами по умолчанию. Второй стиль использует явные файловые дескрипторы.
При использовании неявных файловых дескрипторов все операции предоставляются таблицей io. При использовании явных файловых дескрипторов операция io.open возвращает файловый дескриптор, а затем все операции предоставляются как методы файлового дескриптора.
Метатаблица для файловых дескрипторов предоставляет метаметоды __gc и __close, которые пытаются закрыть файл при вызове.
Таблица io также предоставляет три предопределенных файловых дескриптора с их обычными значениями из C: io.stdin, io.stdout и io.stderr. Библиотека ввода/вывода никогда не закрывает эти файлы.
Если не указано иное, все функции ввода/вывода возвращают fail при неудаче плюс сообщение об ошибке в качестве второго результата и системно-зависимый код ошибки в качестве третьего результата, и некоторое значение, отличное от false, при успехе. На не-POSIX системах вычисление сообщения об ошибке и кода ошибки в случае ошибок может быть не потокобезопасным, поскольку они полагаются на глобальную переменную C errno.
io.close ([file])
Эквивалент file:close(). Без файла закрывает файл вывода по умолчанию.
io.flush ()
Эквивалент io.output():flush().
io.input ([file])
При вызове с именем файла открывает указанный файл (в текстовом режиме) и устанавливает его дескриптор как файл ввода по умолчанию. При вызове с файловым дескриптором просто устанавливает этот файловый дескриптор как файл ввода по умолчанию. При вызове без аргументов возвращает текущий файл ввода по умолчанию.
В случае ошибок эта функция вызывает ошибку вместо возврата кода ошибки.
io.lines ([filename, ···])
Открывает указанный файл в режиме чтения и возвращает функцию-итератор, которая работает как file:lines(...) для открытого файла. Когда функция-итератор не может прочитать ни одного значения, она автоматически закрывает файл. Помимо функции-итератора, io.lines возвращает три других значения: два значения nil в качестве заполнителей и созданный файловый дескриптор. Таким образом, при использовании в общем цикле for файл закрывается, даже если цикл прерывается ошибкой или break.
Вызов io.lines() (без имени файла) эквивалентен io.input():lines("l"); то есть он итерируется по строкам файла ввода по умолчанию. В этом случае итератор не закрывает файл по окончании цикла.
В случае ошибок при открытии файла эта функция вызывает ошибку вместо возврата кода ошибки.
io.open (filename [, mode])
Эта функция открывает файл в режиме, указанном в строке mode. В случае успеха возвращает новый файловый дескриптор.
Строка режима может быть любой из следующих:
"r": режим чтения (по умолчанию);"w": режим записи;"a": режим добавления;"r+": режим обновления, все предыдущие данные сохраняются;"w+": режим обновления, все предыдущие данные стираются;"a+": режим добавления с обновлением, предыдущие данные сохраняются, запись разрешена только в конец файла.
Строка режима может также иметь 'b' в конце, что необходимо в некоторых системах для открытия файла в бинарном режиме.
io.output ([file])
Аналогично io.input, но работает с файлом вывода по умолчанию.
io.popen (prog [, mode])
Эта функция является системно-зависимой и доступна не на всех платформах.
Запускает программу prog в отдельном процессе и возвращает файловый дескриптор, который можно использовать для чтения данных из этой программы (если mode равен "r", по умолчанию) или для записи данных в эту программу (если mode равен "w").
io.read (···)
Эквивалент io.input():read(...).
io.tmpfile ()
В случае успеха возвращает дескриптор для временного файла. Этот файл открывается в режиме обновления и автоматически удаляется по завершении программы.
io.type (obj)
Проверяет, является ли obj допустимым файловым дескриптором. Возвращает строку "file", если obj — открытый файловый дескриптор, "closed file", если obj — закрытый файловый дескриптор, или fail, если obj не является файловым дескриптором.
io.write (···)
Эквивалент io.output():write(...).
file:close ()
Закрывает file. Обратите внимание, что файлы автоматически закрываются, когда их дескрипторы собираются сборщиком мусора, но это происходит через непредсказуемый промежуток времени.
При закрытии файлового дескриптора, созданного с помощью io.popen, file:close возвращает те же значения, что и os.execute.
file:flush ()
Сохраняет все записанные данные в файл.
file:lines (···)
Возвращает функцию-итератор, которая при каждом вызове читает файл в соответствии с заданными форматами. Если формат не указан, по умолчанию используется "l". В качестве примера, конструкция
for c in file:lines(1) do body end
будет итерироваться по всем символам файла, начиная с текущей позиции. В отличие от io.lines, эта функция не закрывает файл по окончании цикла.
file:read (···)
Читает файл file в соответствии с заданными форматами, которые указывают, что читать. Для каждого формата функция возвращает строку или число с прочитанными символами, или fail, если не может прочитать данные с указанным форматом. (В этом последнем случае функция не читает последующие форматы.) При вызове без аргументов используется формат по умолчанию, который читает следующую строку (см. ниже).
Доступные форматы:
"n": читает число и возвращает его как число с плавающей точкой или целое число, следуя лексическим соглашениям Lua. (Число может иметь начальные пробелы и знак.) Этот формат всегда читает самую длинную входную последовательность, которая является допустимым префиксом для числа; если этот префикс не образует допустимого числа (например, пустая строка,"0x"или"3.4e-") или он слишком длинный (более 200 символов), он отбрасывается, и формат возвращаетfail."a": читает весь файл, начиная с текущей позиции. В конце файла возвращает пустую строку; этот формат никогда не завершается неудачей."l": читает следующую строку, пропуская конец строки, возвращаетfailв конце файла. Это формат по умолчанию."L": читает следующую строку, сохраняя символ конца строки (если он есть), возвращаетfailв конце файла.- число: читает строку длиной до этого количества байтов, возвращает
failв конце файла. Если число равно нулю, ничего не читает и возвращает пустую строку илиfailв конце файла.
Форматы "l" и "L" следует использовать только для текстовых файлов.
file:seek ([whence [, offset]])
Устанавливает и получает позицию в файле, измеряемую от начала файла, в позицию, заданную как offset плюс база, указанная строкой whence, следующим образом:
"set": база — позиция 0 (начало файла);"cur": база — текущая позиция;"end": база — конец файла;
В случае успеха seek возвращает конечную позицию в файле, измеренную в байтах от начала файла. Если seek терпит неудачу, он возвращает fail плюс строку с описанием ошибки.
Значение по умолчанию для whence — "cur", а для offset — 0. Поэтому вызов file:seek() возвращает текущую позицию в файле, не изменяя ее; вызов file:seek("set") устанавливает позицию в начало файла (и возвращает 0); а вызов file:seek("end") устанавливает позицию в конец файла и возвращает его размер.
file:setvbuf (mode [, size])
Устанавливает режим буферизации для файла. Доступны три режима:
"no": без буферизации."full": полная буферизация."line": построчная буферизация.
Для последних двух случаев size является подсказкой для размера буфера в байтах. По умолчанию используется подходящий размер.
Конкретное поведение каждого режима непереносимо; для получения дополнительной информации проверьте базовую функцию ISO C setvbuf на вашей платформе.
file:write (···)
Записывает значение каждого из своих аргументов в файл. Аргументы должны быть строками или числами.
В случае успеха эта функция возвращает file. В противном случае возвращает четыре значения: fail, сообщение об ошибке, код ошибки и количество байтов, которое удалось записать.
6.10 – Средства операционной системы
Эта библиотека реализована через таблицу os.
os.clock ()
Возвращает приблизительное количество секунд процессорного времени, использованного программой, как возвращается базовой функцией ISO C clock.
os.date ([format [, time]])
Возвращает строку или таблицу, содержащую дату и время, отформатированные в соответствии с заданной строкой format.
Если аргумент time присутствует, это время, которое должно быть отформатировано (см. описание этого значения в функции os.time). В противном случае date форматирует текущее время.
Если format начинается с '!', то дата форматируется во Всемирном координированном времени (UTC). После этого необязательного символа, если format — строка "*t", то date возвращает таблицу со следующими полями: year, month (1–12), day (1–31), hour (0–23), min (0–59), sec (0–61, из-за високосных секунд), wday (день недели, 1–7, воскресенье — 1), yday (день года, 1–366) и isdst (флаг летнего времени, булево значение). Это последнее поле может отсутствовать, если информация недоступна.
Если format не "*t", то date возвращает дату как строку, отформатированную по тем же правилам, что и функция ISO C strftime.
Если format отсутствует, по умолчанию используется "%c", что дает удобочитаемое представление даты и времени с использованием текущей локали.
На не-POSIX системах эта функция может быть не потокобезопасной из-за зависимости от функций C gmtime и localtime.
os.difftime (t2, t1)
Возвращает разницу в секундах между временем t1 и временем t2 (где времена являются значениями, возвращенными os.time). В POSIX, Windows и некоторых других системах это значение точно равно t2-t1.
os.execute ([command])
Эта функция эквивалентна функции ISO C system. Она передает command для выполнения оболочке операционной системы. Ее первый результат — true, если команда завершилась успешно, или fail в противном случае. После этого первого результата функция возвращает строку и число следующим образом:
"exit": команда завершилась нормально; следующее число — это статус выхода команды."signal": команда была завершена сигналом; следующее число — это сигнал, завершивший команду.
При вызове без команды os.execute возвращает булево значение, которое равно true, если оболочка доступна.
os.exit ([code [, close]])
Вызывает функцию ISO C exit для завершения главной программы. Если code равно true, возвращаемый статус — EXIT_SUCCESS; если code равно false, возвращаемый статус — EXIT_FAILURE; если code — число, возвращаемый статус — это число. Значение по умолчанию для code — true.
Если необязательный второй аргумент close равен true, функция закрывает состояние Lua перед выходом (см. lua_close).
os.getenv (varname)
Возвращает значение переменной окружения процесса varname или fail, если переменная не определена.
os.remove (filename)
Удаляет файл (или пустой каталог в POSIX-системах) с заданным именем. Если эта функция терпит неудачу, она возвращает fail плюс строку с описанием ошибки и код ошибки. В противном случае возвращает true.
os.rename (oldname, newname)
Переименовывает файл или каталог с именем oldname в newname. Если эта функция терпит неудачу, она возвращает fail плюс строку с описанием ошибки и код ошибки. В противном случае возвращает true.
os.setlocale (locale [, category])
Устанавливает текущую локаль программы. locale — это системно-зависимая строка, указывающая локаль; category — необязательная строка, описывающая, какую категорию изменить: "all", "collate", "ctype", "monetary", "numeric" или "time"; категория по умолчанию — "all". Функция возвращает имя новой локали или fail, если запрос не может быть выполнен.
Если locale — пустая строка, текущая локаль устанавливается в определенную реализацией родную локаль. Если locale — строка "C", текущая локаль устанавливается в стандартную локаль C.
При вызове с nil в качестве первого аргумента эта функция только возвращает имя текущей локали для заданной категории.
Эта функция может быть не потокобезопасной из-за зависимости от функции C setlocale.
os.time ([table])
Возвращает текущее местное время при вызове без аргументов или время, представляющее местные дату и время, заданные данной таблицей. Эта таблица должна иметь поля year, month и day и может иметь поля hour (по умолчанию 12), min (по умолчанию 0), sec (по умолчанию 0) и isdst (по умолчанию nil). Другие поля игнорируются. Описание этих полей см. в функции os.date.
При вызове функции значения в этих полях не обязаны находиться внутри своих допустимых диапазонов. Например, если sec равно -10, это означает 10 секунд до времени, указанного другими полями; если hour равно 1000, это означает 1000 часов после времени, указанного другими полями.
Возвращаемое значение — это число, значение которого зависит от вашей системы. В POSIX, Windows и некоторых других системах это число отсчитывает количество секунд с некоторого заданного начального момента времени (“эпохи”). В других системах значение не определено, и число, возвращаемое time, может использоваться только в качестве аргумента для os.date и os.difftime.
При вызове с таблицей os.time также нормализует все поля, задокументированные в функции os.date, так что они представляют то же самое время, что и до вызова, но со значениями внутри допустимых диапазонов.
os.tmpname ()
Возвращает строку с именем файла, которое можно использовать для временного файла. Файл должен быть явно открыт перед использованием и явно удален, когда больше не нужен.
В POSIX-системах эта функция также создает файл с этим именем, чтобы избежать рисков безопасности. (Кто-то другой может создать файл с неправильными разрешениями за время между получением имени и созданием файла.) Вам все равно нужно открыть файл для его использования и удалить его (даже если вы его не используете).
По возможности лучше использовать io.tmpfile, которая автоматически удаляет файл по завершении программы.
6.11 – Библиотека отладки
Эта библиотека предоставляет функциональность отладочного интерфейса (§4.7) программам Lua. Следует проявлять осторожность при использовании этой библиотеки. Некоторые из ее функций нарушают базовые предположения о коде Lua (например, что к локальным переменным функции нельзя получить доступ извне; что метатаблицы пользовательских данных не могут быть изменены кодом Lua; что программы Lua не падают) и, следовательно, могут скомпрометировать в остальном безопасный код. Более того, некоторые функции в этой библиотеке могут быть медленными.
Все функции в этой библиотеке предоставляются внутри таблицы debug. Все функции, работающие с потоком, имеют необязательный первый аргумент — поток, с которым нужно работать. По умолчанию всегда используется текущий поток.
debug.debug ()
Входит в интерактивный режим с пользователем, выполняя каждую строку, которую вводит пользователь. Используя простые команды и другие средства отладки, пользователь может проверять глобальные и локальные переменные, изменять их значения, вычислять выражения и т.д. Строка, содержащая только слово cont, завершает эту функцию, так что вызывающий код продолжает свое выполнение.
Обратите внимание, что команды для debug.debug лексически не вложены ни в какую функцию и поэтому не имеют прямого доступа к локальным переменным.
debug.gethook ([thread])
Возвращает текущие настройки перехватчика (hook) для потока в виде трех значений: текущая функция перехватчика, текущая маска перехватчика и текущий счетчик перехватчика, как установлено функцией debug.sethook.
Возвращает fail, если активного перехватчика нет.
debug.getinfo ([thread,] f [, what])
Возвращает таблицу с информацией о функции. Вы можете передать функцию напрямую или передать число в качестве значения f, что означает функцию, выполняющуюся на уровне f стека вызовов данного потока: уровень 0 — текущая функция (сама getinfo); уровень 1 — функция, вызвавшая getinfo (за исключением хвостовых вызовов, которые не учитываются в стеке); и так далее. Если f — число, превышающее количество активных функций, getinfo возвращает fail.
Возвращаемая таблица может содержать все поля, возвращаемые lua_getinfo, при этом строка what описывает, какие поля следует заполнить. По умолчанию для what запрашивается вся доступная информация, кроме таблицы допустимых строк. Опция 'f' добавляет поле с именем func с самой функцией. Опция 'L' добавляет поле с именем activelines с таблицей допустимых строк, при условии, что функция является Lua-функцией. Если у функции нет отладочной информации, таблица пуста.
Например, выражение debug.getinfo(1,"n").name возвращает имя для текущей функции, если подходящее имя может быть найдено, а выражение debug.getinfo(print) возвращает таблицу со всей доступной информацией о функции print.
debug.getlocal ([thread,] f, local)
Эта функция возвращает имя и значение локальной переменной с индексом local функции на уровне f стека. Эта функция получает доступ не только к явным локальным переменным, но также к параметрам и временным значениям.
Первый параметр или локальная переменная имеет индекс 1, и так далее, в порядке их объявления в коде, при этом учитываются только переменные, активные в текущей области видимости функции. Константы времени компиляции могут не появляться в этом списке, если они были оптимизированы компилятором. Отрицательные индексы относятся к аргументам vararg; -1 — это первый аргумент vararg. Эти отрицательные индексы доступны только тогда, когда таблица vararg была оптимизирована; в противном случае аргументы vararg доступны в таблице vararg.
Функция возвращает fail, если нет переменной с заданным индексом, и вызывает ошибку при вызове с уровнем вне диапазона. (Вы можете вызвать debug.getinfo, чтобы проверить, допустим ли уровень.)
Имена переменных, начинающиеся с '(' (открывающая скобка), представляют переменные без известных имен (внутренние переменные, такие как переменные управления циклом, и переменные из чанков, сохраненных без отладочной информации).
Параметр f также может быть функцией. В этом случае getlocal возвращает только имена параметров функции.
debug.getmetatable (value)
Возвращает метатаблицу данного значения или nil, если у него нет метатаблицы.
debug.getregistry ()
Возвращает таблицу реестра (см. §4.3).
debug.getupvalue (f, up)
Эта функция возвращает имя и значение верхнего значения (upvalue) с индексом up функции f. Функция возвращает fail, если нет верхнего значения с заданным индексом.
(Для Lua-функций верхние значения — это внешние локальные переменные, которые использует функция и которые, следовательно, включены в ее замыкание.)
Для C-функций эта функция использует пустую строку "" в качестве имени для всех верхних значений.
Имя переменной '?' (вопросительный знак) представляет переменные без известных имен (переменные из чанков, сохраненных без отладочной информации).
debug.getuservalue (u, n)
Возвращает n-е пользовательское значение, связанное с пользовательскими данными u, плюс булево значение, false, если пользовательские данные не имеют этого значения.
debug.sethook ([thread,] hook, mask [, count])
Устанавливает заданную функцию в качестве отладочного перехватчика (hook). Строка mask и число count описывают, когда будет вызываться перехватчик. Строка mask может иметь любую комбинацию следующих символов с заданным значением:
'c': перехватчик вызывается каждый раз, когда Lua вызывает функцию;'r': перехватчик вызывается каждый раз, когда Lua возвращается из функции;'l': перехватчик вызывается каждый раз, когда Lua переходит на новую строку кода.
Более того, при count, отличном от нуля, перехватчик вызывается также после каждых count инструкций.
При вызове без аргументов debug.sethook отключает перехватчик.
При вызове перехватчика его первым параметром является строка, описывающая событие, вызвавшее его срабатывание: "call", "tail call", "return", "line" и "count". Для событий "line" перехватчик также получает номер новой строки в качестве второго параметра. Внутри перехватчика вы можете вызвать getinfo с уровнем 2, чтобы получить больше информации о выполняющейся функции. (Уровень 0 — это функция getinfo, а уровень 1 — функция перехватчика.)
debug.setlocal ([thread,] level, local, value)
Эта функция присваивает значение value локальной переменной с индексом local функции на уровне level стека. Функция возвращает fail, если нет локальной переменной с заданным индексом, и вызывает ошибку при вызове с уровнем вне диапазона. (Вы можете вызвать getinfo, чтобы проверить, допустим ли уровень.) В противном случае возвращает имя локальной переменной.
См. debug.getlocal для получения дополнительной информации об индексах и именах переменных.
debug.setmetatable (value, table)
Устанавливает метатаблицу для данного значения в заданную таблицу (которая может быть nil). Возвращает value.
debug.setupvalue (f, up, value)
Эта функция присваивает значение value верхнему значению (upvalue) с индексом up функции f. Функция возвращает fail, если нет верхнего значения с заданным индексом. В противном случае возвращает имя верхнего значения.
См. debug.getupvalue для получения дополнительной информации о верхних значениях.
debug.setuservalue (udata, value, n)
Устанавливает данное значение в качестве n-го пользовательского значения, связанного с данными udata. udata должны быть полными пользовательскими данными (full userdata).
Возвращает udata или fail, если пользовательские данные не имеют этого значения.
debug.traceback ([thread,] [message [, level]])
Если message присутствует, но не является ни строкой, ни nil, эта функция возвращает message без дальнейшей обработки. В противном случае она возвращает строку с трассировкой стека вызовов. Необязательная строка message добавляется в начало трассировки. Необязательный номер level указывает, с какого уровня начинать трассировку (по умолчанию 1, функция, вызывающая traceback).
debug.upvalueid (f, n)
Возвращает уникальный идентификатор (как легкие пользовательские данные — light userdata) для верхнего значения с номером n из данной функции.
Эти уникальные идентификаторы позволяют программе проверять, разделяют ли разные замыкания верхние значения. Замыкания Lua, которые разделяют верхнее значение (то есть обращаются к одной и той же внешней локальной переменной), вернут идентичные идентификаторы для этих индексов верхних значений.
debug.upvaluejoin (f1, n1, f2, n2)
Делает так, что n1-е верхнее значение Lua-замыкания f1 ссылается на n2-е верхнее значение Lua-замыкания f2.
2.6 - 7 – Lua как самостоятельное приложение
Оглавление
7 – Lua как самостоятельное приложение
Хотя Lua был разработан как язык расширения для встраивания в хост-программу на C, он также часто используется как самостоятельный язык. Интерпретатор для Lua как самостоятельного языка, называемый просто lua, поставляется со стандартным дистрибутивом. Автономный интерпретатор включает все стандартные библиотеки. Его использование:
lua [options] [script [args]]
Опции следующие:
-e stat: выполнить строкуstat;-i: войти в интерактивный режим после выполнения скрипта;-l mod: выполнитьrequire "mod"и присвоить результат глобальной переменнойmod;-l g=mod: выполнитьrequire "mod"и присвоить результат глобальной переменнойg;-v: вывести информацию о версии;-E: игнорировать переменные окружения;-W: включить предупреждения;--: прекратить обработку опций;-: выполнить стандартный ввод (stdin) как файл и прекратить обработку опций.
После обработки своих опций lua запускает указанный скрипт. При вызове без аргументов lua ведет себя как lua -v -i, если стандартный ввод (stdin) является терминалом, и как lua - в противном случае.
При вызове без опции -E интерпретатор проверяет переменную окружения LUA_INIT_5_5 (или LUA_INIT, если версионированное имя не определено) перед выполнением любого аргумента. Если содержимое переменной имеет формат @filename, то lua выполняет этот файл. В противном случае lua выполняет саму строку.
При вызове с опцией -E Lua не проверяет никакие переменные окружения. В частности, значения package.path и package.cpath устанавливаются с путями по умолчанию, определенными в luaconf.h. Чтобы сигнализировать библиотекам, что эта опция включена, автономный интерпретатор устанавливает поле "LUA_NOENV" в реестре в истинное значение. Другие библиотеки могут проверять это поле с той же целью.
Опции -e, -l и -W обрабатываются в порядке их появления. Например, вызов вида
$ lua -e 'a=1' -llib1 script.lua
сначала установит a в 1, затем выполнит require для библиотеки lib1 и, наконец, запустит файл script.lua без аргументов. (Здесь $ — приглашение командной оболочки. Ваше приглашение может отличаться).
Перед выполнением любого кода lua собирает все аргументы командной строки в глобальную таблицу arg. Имя скрипта помещается в индекс 0, первый аргумент после имени скрипта — в индекс 1, и так далее. Любые аргументы перед именем скрипта (то есть имя интерпретатора плюс его опции) помещаются в отрицательные индексы. Например, в вызове
$ lua -la b.lua t1 t2
таблица выглядит так:
arg = { [-2] = "lua", [-1] = "-la",
[0] = "b.lua",
[1] = "t1", [2] = "t2" }
Если в вызове нет скрипта, имя интерпретатора помещается в индекс 0, за ним следуют остальные аргументы. Например, вызов
$ lua -e "print(arg[1])"
выведет "-e". Если есть скрипт, скрипт вызывается с аргументами arg[1], ···, arg[#arg]. Как и все чанки в Lua, скрипт компилируется как вариадическая функция.
В интерактивном режиме Lua многократно выводит приглашение и ожидает строку. После чтения строки Lua сначала пытается интерпретировать строку как выражение. Если это удается, он выводит его значение. В противном случае он интерпретирует строку как чанк. Если вы вводите незавершенный чанк, интерпретатор ожидает его завершения, выдавая другое приглашение.
Обратите внимание, что, поскольку каждая полная строка читается как новый чанк, локальные переменные не переживают строки. Чтобы избежать путаницы, интерпретатор выдает предупреждение, если строка начинается с зарезервированного слова local:
> x = 20 -- глобальная 'x'
> local x = 10; print(x)
--> warning: locals do not survive across lines in interactive mode
--> 10
> print(x) -- снова глобальная 'x'
--> 20
> do -- незавершенный чанк
>> local x = 10; print(x) -- '>>' приглашение для завершения строки
>> print(x)
>> end -- чанк завершен
--> 10
--> 10
Если глобальная переменная _PROMPT содержит строку, то ее значение используется в качестве приглашения. Аналогично, если глобальная переменная _PROMPT2 содержит строку, ее значение используется в качестве вторичного приглашения (выдаваемого во время незавершенных инструкций).
В случае незащищенных ошибок в скрипте интерпретатор сообщает об ошибке в стандартный поток ошибок. Если объект ошибки не является строкой, но имеет метаметод __tostring, интерпретатор вызывает этот метаметод для создания итогового сообщения. В противном случае интерпретатор преобразует объект ошибки в строку и добавляет к нему трассировку стека. Когда предупреждения включены, они просто выводятся в стандартный вывод ошибок.
При нормальном завершении интерпретатор закрывает свое главное состояние Lua (см. lua_close). Скрипт может избежать этого шага, вызвав os.exit для завершения.
Чтобы позволить использовать Lua в качестве интерпретатора скриптов в системах Unix, Lua пропускает первую строку файла чанка, если она начинается с #. Поэтому Lua-скрипты можно сделать исполняемыми программами, используя chmod +x и форму #!, как в
#!/usr/local/bin/lua
Конечно, расположение интерпретатора Lua на вашей машине может отличаться. Если lua находится в вашем PATH, то
#!/usr/bin/env lua
является более переносимым решением.
8 – Несовместимости с предыдущей версией
Здесь мы перечисляем несовместимости, с которыми вы можете столкнуться при переходе программы с Lua 5.4 на Lua 5.5.
Вы можете избежать некоторых несовместимостей, скомпилировав Lua с соответствующими опциями (см. файл luaconf.h). Однако все эти опции совместимости будут удалены в будущем. Чаще всего проблемы совместимости возникают именно при удалении этих опций. Поэтому, когда у вас есть возможность, старайтесь тестировать свой код с версией Lua, скомпилированной со всеми отключенными опциями совместимости. Это облегчит переходы на более новые версии Lua.
Версии Lua всегда могут изменять C API способами, которые не подразумевают изменений в исходном коде программы, например, числовые значения констант или реализацию функций в виде макросов. Поэтому никогда не следует предполагать, что двоичные файлы совместимы между разными версиями Lua. Всегда перекомпилируйте клиентов Lua API при использовании новой версии.
Аналогично, версии Lua всегда могут изменять внутреннее представление предварительно скомпилированных чанков; предкомпилированные чанки несовместимы между разными версиями Lua.
Стандартные пути в официальном дистрибутиве могут меняться между версиями.
8.1 – Несовместимости в языке
- Слово
globalявляется зарезервированным словом. Не используйте его как обычное имя. - Управляющая переменная в циклах
forдоступна только для чтения. Если вам нужно ее изменить, объявите локальную переменную с тем же именем в теле цикла. - Цепочка метаметодов
__callможет содержать не более 15 объектов. - При ошибке
nilв качестве объекта ошибки заменяется строковым сообщением.
8.2 – Несовместимости в библиотеках
- Параметры сборки мусора не устанавливаются опциями
"incremental"и"generational"; вместо этого для этой цели есть новая опция"param". Более того, были внесены некоторые изменения в сами параметры.
8.3 – Несовместимости в API
- В
lua_callи связанных функциях максимальное значение для количества требуемых результатов (nresults) составляет 250. Если вам действительно нужно большее значение, используйтеLUA_MULTRET, а затем настройте размер стека. Ранее этот предел не был указан. lua_newstateимеет третий параметр — начальное значение для хеширования строк.- Функция
lua_resetthreadустарела; она эквивалентнаlua_closethreadсfrom, равнымNULL. - Функция
lua_setcstacklimitустарела. Вызовы к ней можно просто удалить. - Функция
lua_dumpизменила способ сохранения стека при вызовах функции-писателя. (Это не было указано в предыдущих версиях). Кроме того, она вызывает функцию-писатель один дополнительный раз, чтобы сигнализировать о конце дампа. - Параметры сборки мусора не устанавливаются опциями
LUA_GCINCиLUA_GCGEN; вместо этого для этой цели есть новая опцияLUA_GCPARAM. Более того, были внесены некоторые изменения в сами параметры. - Функция
lua_pushvfstringтеперь сообщает об ошибках, а не возбуждает их.
9 – Полный синтаксис Lua
Здесь представлен полный синтаксис Lua в расширенной БНФ. Как обычно в расширенной БНФ, {A} означает 0 или более A, а [A] означает необязательное A. (Приоритеты операторов см. в §3.4.8; описание терминалов Name, Numeral и LiteralString см. в §3.1).
chunk ::= block
block ::= {stat} [retstat]
stat ::= ‘;’ |
varlist ‘=’ explist |
functioncall |
label |
break |
goto Name |
do block end |
while exp do block end |
repeat block until exp |
if exp then block {elseif exp then block} [else block] end |
for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end |
for namelist in explist do block end |
function funcname funcbody |
local function Name funcbody |
global function Name funcbody |
local attnamelist [‘=’ explist] |
global attnamelist |
global [attrib] ‘*’
attnamelist ::= [attrib] Name [attrib] {‘,’ Name [attrib]}
attrib ::= ‘<’ Name ‘>’
retstat ::= return [explist] [‘;’]
label ::= ‘::’ Name ‘::’
funcname ::= Name {‘.’ Name} [‘:’ Name]
varlist ::= var {‘,’ var}
var ::= Name | prefixexp ‘[’ exp ‘]’ | prefixexp ‘.’ Name
namelist ::= Name {‘,’ Name}
explist ::= exp {‘,’ exp}
exp ::= nil | false | true | Numeral | LiteralString | ‘...’ | functiondef |
prefixexp | tableconstructor | exp binop exp | unop exp
prefixexp ::= var | functioncall | ‘(’ exp ‘)’
functioncall ::= prefixexp args | prefixexp ‘:’ Name args
args ::= ‘(’ [explist] ‘)’ | tableconstructor | LiteralString
functiondef ::= function funcbody
funcbody ::= ‘(’ [parlist] ‘)’ block end
parlist ::= namelist [‘,’ varargparam] | varargparam
varargparam ::= ‘...’ [Name]
tableconstructor ::= ‘{’ [fieldlist] ‘}’
fieldlist ::= field {fieldsep field} [fieldsep]
field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp
fieldsep ::= ‘,’ | ‘;’
binop ::= ‘+’ | ‘-’ | ‘*’ | ‘/’ | ‘//’ | ‘^’ | ‘%’ |
‘&’ | ‘~’ | ‘|’ | ‘>>’ | ‘<<’ | ‘..’ |
‘<’ | ‘<=’ | ‘>’ | ‘>=’ | ‘==’ | ‘~=’ |
and | or
unop ::= ‘-’ | not | ‘#’ | ‘~’
3 - Authelia
Структура Authelia
Базовая схема взаимодействия Authelia с сервисами
---
config:
theme: redux
---
flowchart LR
A["Пользователь"] -- Запрос --> B["Reverse Proxy Nginx/Traefik"]
B -- Проверка аутентификации --> C["Authelia"]
C -- Данные пользователей --> D["Хранилище: PostgreSQL/MySQL"]
C -- 2FA/SMS --> E["Провайдер: Twilio/Email"]
C -- Разрешить/Запретить --> B
B -- Доступ разрешен --> F["Защищенный сервис"]
B:::Aqua
C:::Rose
F:::Peach
classDef Aqua stroke-width:1px, stroke-dasharray:none, stroke:#46EDC8, fill:#DEFFF8, color:#378E7A
classDef Rose stroke-width:2px, stroke-dasharray:none, stroke:#FF5978, fill:#FFDFE5, color:#8E2236
classDef Peach stroke-width:1px, stroke-dasharray:none, stroke:#FBB35A, fill:#FFEFDB, color:#8F632D
style D fill:#FFD600
style E fill:#C8E6C9Детализированная архитектура Authelia
graph TD
subgraph Authelia
A[Frontend] -->|API| B[Backend]
B --> C[Аутентификация]
B --> D[Авторизация]
B --> E[2FA]
C -->|LDAP/OIDC| F[Identity Provider]
D -->|ACL| G[Политики доступа]
E -->|TOTP/SMS| H[Провайдеры 2FA]
end
I[Reverse Proxy] -->|Запросы| B
B -->|Сессии| J[Redis]
F -->|Пользователи| K[PostgreSQL]3.1 - Конфигурация Authelia
config.template.yml который располагается в каждой секции сайта.Файл конфигурации Authelia
Конфигурация оформляется в виде файла config.template.yml который располагается в каждой секции сайта.
docker run authelia/authelia:latest authelia config validate --config /config/configuration.yml
Смотреть файл конфигурации
# yamllint disable rule:comments-indentation
---
###############################################################################
## Authelia Configuration ##
###############################################################################
##
## Notes:
##
## - the default location of this file is assumed to be configuration.yml unless otherwise noted
## - when using docker the container expects this by default to be at /config/configuration.yml
## - the default location where this file is loaded from can be overridden with the X_AUTHELIA_CONFIG environment var
## - the comments in this configuration file are helpful but users should consult the official documentation on the
## website at https://www.authelia.com/ or https://www.authelia.com/configuration/prologue/introduction/
## - this configuration file template is not automatically updated
##
## Certificates directory specifies where Authelia will load trusted certificates (public portion) from in addition to
## the system certificates store.
## They should be in base64 format, and have one of the following extensions: *.cer, *.crt, *.pem.
# certificates_directory: '/config/certificates/'
## The theme to display: light, dark, grey, auto.
# theme: 'light'
## Set the default 2FA method for new users and for when a user has a preferred method configured that has been
## disabled. This setting must be a method that is enabled.
## Options are totp, webauthn, mobile_push.
# default_2fa_method: ''
##
## Server Configuration
##
# server:
## The address for the Main server to listen on in the address common syntax.
## Formats:
## - [<scheme>://]<hostname>[:<port>][/<path>]
## - [<scheme>://][hostname]:<port>[/<path>]
## Square brackets indicate optional portions of the format. Scheme must be 'tcp', 'tcp4', 'tcp6', 'unix', or 'fd'.
## The default scheme is 'unix' if the address is an absolute path otherwise it's 'tcp'. The default port is '9091'.
## If the path is specified this configures the router to handle both the `/` path and the configured path.
# address: 'tcp://:9091/'
## Set the path on disk to Authelia assets.
## Useful to allow overriding of specific static assets.
# asset_path: '/config/assets/'
## Disables writing the health check vars to /app/.healthcheck.env which makes healthcheck.sh return exit code 0.
## This is disabled by default if either /app/.healthcheck.env or /app/healthcheck.sh do not exist.
# disable_healthcheck: false
## Authelia by default doesn't accept TLS communication on the server port. This section overrides this behaviour.
# tls:
## The path to the DER base64/PEM format private key.
# key: ''
## The path to the DER base64/PEM format public certificate.
# certificate: ''
## The list of certificates for client authentication.
# client_certificates: []
## Server headers configuration/customization.
# headers:
## The CSP Template. Read the docs.
# csp_template: ''
## Server Buffers configuration.
# buffers:
## Buffers usually should be configured to be the same value.
## Explanation at https://www.authelia.com/c/server#buffer-sizes
## Read buffer size adjusts the server's max incoming request size in bytes.
## Write buffer size does the same for outgoing responses.
## Read buffer.
# read: 4096
## Write buffer.
# write: 4096
## Server Timeouts configuration.
# timeouts:
## Read timeout in the duration common syntax.
# read: '6 seconds'
## Write timeout in the duration common syntax.
# write: '6 seconds'
## Idle timeout in the duration common syntax.
# idle: '30 seconds'
## Server Endpoints configuration.
## This section is considered advanced and it SHOULD NOT be configured unless you've read the relevant documentation.
# endpoints:
## Enables the pprof endpoint.
# enable_pprof: false
## Enables the expvars endpoint.
# enable_expvars: false
## Configure the authz endpoints.
# authz:
# forward-auth:
# implementation: 'ForwardAuth'
# authn_strategies: []
# ext-authz:
# implementation: 'ExtAuthz'
# authn_strategies: []
# auth-request:
# implementation: 'AuthRequest'
# authn_strategies: []
# legacy:
# implementation: 'Legacy'
# authn_strategies: []
##
## Log Configuration
##
# log:
## Level of verbosity for logs: info, debug, trace.
# level: 'debug'
## Format the logs are written as: json, text.
# format: 'json'
## File path where the logs will be written. If not set logs are written to stdout.
# file_path: '/config/authelia.log'
## Whether to also log to stdout when a log_file_path is defined.
# keep_stdout: false
##
## Telemetry Configuration
##
# telemetry:
##
## Metrics Configuration
##
# metrics:
## Enable Metrics.
# enabled: false
## The address for the Metrics server to listen on in the address common syntax.
## Formats:
## - [<scheme>://]<hostname>[:<port>][/<path>]
## - [<scheme>://][hostname]:<port>[/<path>]
## Square brackets indicate optional portions of the format. Scheme must be 'tcp', 'tcp4', 'tcp6', 'unix', or 'fd'.
## The default scheme is 'unix' if the address is an absolute path otherwise it's 'tcp'. The default port is '9959'.
## If the path is not specified it defaults to `/metrics`.
# address: 'tcp://:9959/metrics'
## Metrics Server Buffers configuration.
# buffers:
## Read buffer.
# read: 4096
## Write buffer.
# write: 4096
## Metrics Server Timeouts configuration.
# timeouts:
## Read timeout in the duration common syntax.
# read: '6 seconds'
## Write timeout in the duration common syntax.
# write: '6 seconds'
## Idle timeout in the duration common syntax.
# idle: '30 seconds'
##
## TOTP Configuration
##
## Parameters used for TOTP generation.
# totp:
## Disable TOTP.
# disable: false
## The issuer name displayed in the Authenticator application of your choice.
# issuer: 'authelia.com'
## The TOTP algorithm to use.
## It is CRITICAL you read the documentation before changing this option:
## https://www.authelia.com/c/totp#algorithm
# algorithm: 'SHA1'
## The number of digits a user has to input. Must either be 6 or 8.
## Changing this option only affects newly generated TOTP configurations.
## It is CRITICAL you read the documentation before changing this option:
## https://www.authelia.com/c/totp#digits
# digits: 6
## The period in seconds a Time-based One-Time Password is valid for.
## Changing this option only affects newly generated TOTP configurations.
# period: 30
## The skew controls number of Time-based One-Time Passwords either side of the current one that are valid.
## Warning: before changing skew read the docs link below.
# skew: 1
## See: https://www.authelia.com/c/totp#input-validation to read
## the documentation.
## The size of the generated shared secrets. Default is 32 and is sufficient in most use cases, minimum is 20.
# secret_size: 32
## The allowed algorithms for a user to pick from.
# allowed_algorithms:
# - 'SHA1'
## The allowed digits for a user to pick from.
# allowed_digits:
# - 6
## The allowed periods for a user to pick from.
# allowed_periods:
# - 30
## Disable the reuse security policy which prevents replays of one-time password code values.
# disable_reuse_security_policy: false
##
## WebAuthn Configuration
##
## Parameters used for WebAuthn.
# webauthn:
## Disable WebAuthn.
# disable: false
## Enables logins via a Passkey.
# enable_passkey_login: false
## The display name the browser should show the user for when using WebAuthn to login/register.
# display_name: 'Authelia'
## Conveyance preference controls if we collect the attestation statement including the AAGUID from the device.
## Options are none, indirect, direct.
# attestation_conveyance_preference: 'indirect'
## The interaction timeout for WebAuthn dialogues in the duration common syntax.
# timeout: '60 seconds'
## Authenticator Filtering.
# filtering:
## Prohibits registering Authenticators that claim they can export their credentials in some way.
# prohibit_backup_eligibility: false
## Permitted AAGUID's. If configured specifically only allows the listed AAGUID's.
# permitted_aaguids: []
## Prohibited AAGUID's. If configured prohibits the use of specific AAGUID's.
# prohibited_aaguids: []
## Selection Criteria controls the preferences for registration.
# selection_criteria:
## The attachment preference. Either 'cross-platform' for dedicated authenticators, or 'platform' for embedded
## authenticators.
# attachment: 'cross-platform'
## The discoverability preference. Options are 'discouraged', 'preferred', and 'required'.
# discoverability: 'discouraged'
## User verification controls if the user must make a gesture or action to confirm they are present.
## Options are required, preferred, discouraged.
# user_verification: 'preferred'
## Metadata Service validation via MDS3.
# metadata:
## Enable the metadata fetch behaviour.
# enabled: false
## Enable Validation of the Trust Anchor. This generally should be enabled if you're using the metadata. It
## ensures the attestation certificate presented by the authenticator is valid against the MDS3 certificate that
## issued the attestation certificate.
# validate_trust_anchor: true
## Enable Validation of the Entry. This ensures that the MDS3 actually contains the metadata entry. If not enabled
## attestation certificates which are not formally registered will be skipped. This may potentially exclude some
## virtual authenticators.
# validate_entry: true
## Enabling this allows attestation certificates with a zero AAGUID to pass validation. This is important if you do
## use non-conformant authenticators like Apple ID.
# validate_entry_permit_zero_aaguid: false
## Enable Validation of the Authenticator Status.
# validate_status: true
## List of statuses which are considered permitted when validating an authenticator's metadata. Generally it is
## recommended that this is not configured as any other status the authenticator's metadata has will result in an
## error. This option is ineffectual if validate_status is false.
# validate_status_permitted: ~
## List of statuses that should be prohibited when validating an authenticator's metadata. Generally it is
## recommended that this is not configured as there are safe defaults. This option is ineffectual if validate_status
## is false, or validate_status_permitted has values.
# validate_status_prohibited: ~
##
## Duo Push API Configuration
##
## Parameters used to contact the Duo API. Those are generated when you protect an application of type
## "Partner Auth API" in the management panel.
# duo_api:
# disable: false
# hostname: 'api-123456789.example.com'
# integration_key: 'ABCDEF'
## Secret can also be set using a secret: https://www.authelia.com/c/secrets
# secret_key: '1234567890abcdefghifjkl'
# enable_self_enrollment: false
##
## Identity Validation Configuration
##
## This configuration tunes the identity validation flows.
identity_validation:
## Reset Password flow. Adjusts how the reset password flow operates.
reset_password:
## Maximum allowed time before the JWT is generated and when the user uses it in the duration common syntax.
# jwt_lifespan: '5 minutes'
## The algorithm used for the Reset Password JWT.
# jwt_algorithm: 'HS256'
## The secret key used to sign and verify the JWT.
jwt_secret: 'a_very_important_secret'
## Elevated Session flows. Adjusts the flow which require elevated sessions for example managing credentials, adding,
## removing, etc.
# elevated_session:
## Maximum allowed lifetime after the One-Time Code is generated that it is considered valid.
# code_lifespan: '5 minutes'
## Maximum allowed lifetime after the user uses the One-Time Code and the user must perform the validation again in
## the duration common syntax.
# elevation_lifespan: '10 minutes'
## Number of characters the one-time password contains.
# characters: 8
## In addition to the One-Time Code requires the user performs a second factor authentication.
# require_second_factor: false
## Skips the elevation requirement and entry of the One-Time Code if the user has performed second factor
## authentication.
# skip_second_factor: false
##
## NTP Configuration
##
## This is used to validate the servers time is accurate enough to validate TOTP.
# ntp:
## The address of the NTP server to connect to in the address common syntax.
## Format: [<scheme>://]<hostname>[:<port>].
## Square brackets indicate optional portions of the format. Scheme must be 'udp', 'udp4', or 'udp6'.
## The default scheme is 'udp'. The default port is '123'.
# address: 'udp://time.cloudflare.com:123'
## NTP version.
# version: 4
## Maximum allowed time offset between the host and the NTP server in the duration common syntax.
# max_desync: '3 seconds'
## Disables the NTP check on startup entirely. This means Authelia will not contact a remote service at all if you
## set this to true, and can operate in a truly offline mode.
# disable_startup_check: false
## The default of false will prevent startup only if we can contact the NTP server and the time is out of sync with
## the NTP server more than the configured max_desync. If you set this to true, an error will be logged but startup
## will continue regardless of results.
# disable_failure: false
##
## Definitions
##
## The definitions are used in other areas as reference points to reduce duplication.
##
# definitions:
## The user attribute definitions.
# user_attributes:
## The name of the definition.
# definition_name:
## The common expression language expression for this definition.
# expression: ''
## The network definitions.
# network:
## The name of the definition followed by the list of CIDR network addresses in this definition.
# internal:
# - '10.10.0.0/16'
# - '172.16.0.0/12'
# - '192.168.2.0/24'
# VPN:
# - '10.9.0.0/16'
##
## Authentication Backend Provider Configuration
##
## Used for verifying user passwords and retrieve information such as email address and groups users belong to.
##
## The available providers are: `file`, `ldap`. You must use only one of these providers.
# authentication_backend:
## Password Change Options.
# password_change:
## Disable both the HTML element and the API for password change functionality.
# disable: false
## Password Reset Options.
# password_reset:
## Disable both the HTML element and the API for reset password functionality.
# disable: false
## External reset password url that redirects the user to an external reset portal. This disables the internal reset
## functionality.
# custom_url: ''
## The amount of time to wait before we refresh data from the authentication backend in the duration common syntax.
## To disable this feature set it to 'disable', this will slightly reduce security because for Authelia, users will
## always belong to groups they belonged to at the time of login even if they have been removed from them in LDAP.
## To force update on every request you can set this to '0' or 'always', this will increase processor demand.
## See the below documentation for more information.
## Refresh Interval docs: https://www.authelia.com/c/1fa#refresh-interval
# refresh_interval: '5 minutes'
##
## LDAP (Authentication Provider)
##
## This is the recommended Authentication Provider in production
## because it allows Authelia to offload the stateful operations
## onto the LDAP service.
# ldap:
## The address of the directory server to connect to in the address common syntax.
## Format: [<scheme>://]<hostname>[:<port>].
## Square brackets indicate optional portions of the format. Scheme must be 'ldap', 'ldaps', or 'ldapi`.
## The default scheme is 'ldapi' if the address is an absolute path otherwise it's 'ldaps'.
## The default port is '636', unless the scheme is 'ldap' in which case it's '389'.
# address: 'ldaps://127.0.0.1:636'
## The LDAP implementation, this affects elements like the attribute utilised for resetting a password.
## Acceptable options are as follows:
## - 'activedirectory' - for Microsoft Active Directory.
## - 'freeipa' - for FreeIPA.
## - 'lldap' - for lldap.
## - 'custom' - for custom specifications of attributes and filters.
## This currently defaults to 'custom' to maintain existing behaviour.
##
## Depending on the option here certain other values in this section have a default value, notably all of the
## attribute mappings have a default value that this config overrides, you can read more about these default values
## at https://www.authelia.com/c/ldap#defaults
# implementation: 'custom'
## The dial timeout for LDAP in the duration common syntax.
# timeout: '20 seconds'
## Use StartTLS with the LDAP connection.
# start_tls: false
## TLS configuration.
# tls:
## The server subject name to check the servers certificate against during the validation process.
## This option is not required if the certificate has a SAN which matches the address options hostname.
# server_name: 'ldap.example.com'
## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the
## certificate or the certificate of the authority signing the certificate to the certificates directory which is
## defined by the `certificates_directory` option at the top of the configuration.
## It's important to note the public key should be added to the directory, not the private key.
## This option is strongly discouraged but may be useful in some self-signed situations where validation is not
## important to the administrator.
# skip_verify: false
## Minimum TLS version for the connection.
# minimum_version: 'TLS1.2'
## Maximum TLS version for the connection.
# maximum_version: 'TLS1.3'
## The certificate chain used with the private_key if the server requests TLS Client Authentication
## i.e. Mutual TLS.
# certificate_chain: |
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
## The private key used with the certificate_chain if the server requests TLS Client Authentication
## i.e. Mutual TLS.
# private_key: |
# -----BEGIN PRIVATE KEY-----
# ...
# -----END PRIVATE KEY-----
## Connection Pooling configuration.
# pooling:
## Enable Pooling.
# enable: false
## Pool count.
# count: 5
## Retries to obtain a connection during the timeout.
# retries: 2
## Timeout before the attempt to obtain a connection fails.
# timeout: '10 seconds'
## The distinguished name of the container searched for objects in the directory information tree.
## See also: additional_users_dn, additional_groups_dn.
# base_dn: 'dc=example,dc=com'
## The additional_users_dn is prefixed to base_dn and delimited by a comma when searching for users.
## i.e. with this set to OU=Users and base_dn set to DC=a,DC=com; OU=Users,DC=a,DC=com is searched for users.
# additional_users_dn: 'ou=users'
## The users filter used in search queries to find the user profile based on input filled in login form.
## Various placeholders are available in the user filter which you can read about in the documentation which can
## be found at: https://www.authelia.com/c/ldap#users-filter-replacements
##
## Recommended settings are as follows:
## - Microsoft Active Directory: (&({username_attribute}={input})(objectCategory=person)(objectClass=user))
## - OpenLDAP:
## - (&({username_attribute}={input})(objectClass=person))
## - (&({username_attribute}={input})(objectClass=inetOrgPerson))
##
## To allow sign in both with username and email, one can use a filter like
## (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person))
# users_filter: '(&({username_attribute}={input})(objectClass=person))'
## The additional_groups_dn is prefixed to base_dn and delimited by a comma when searching for groups.
## i.e. with this set to OU=Groups and base_dn set to DC=a,DC=com; OU=Groups,DC=a,DC=com is searched for groups.
# additional_groups_dn: 'ou=groups'
## The groups filter used in search queries to find the groups based on relevant authenticated user.
## Various placeholders are available in the groups filter which you can read about in the documentation which can
## be found at: https://www.authelia.com/c/ldap#groups-filter-replacements
##
## If your groups use the `groupOfUniqueNames` structure use this instead:
## (&(uniqueMember={dn})(objectClass=groupOfUniqueNames))
# groups_filter: '(&(member={dn})(objectClass=groupOfNames))'
## The group search mode to use. Options are 'filter' or 'memberof'. It's essential to read the docs if you wish to
## use 'memberof'. Also 'filter' is the best choice for most use cases.
# group_search_mode: 'filter'
## Follow referrals returned by the server.
## This is especially useful for environments where read-only servers exist. Only implemented for write operations.
# permit_referrals: false
## The username and password of the admin user.
# user: 'cn=admin,dc=example,dc=com'
## Password can also be set using a secret: https://www.authelia.com/c/secrets
# password: 'password'
## The attributes for users and objects from the directory server.
# attributes:
## The distinguished name attribute if your directory server supports it. Users should read the docs before
## configuring. Only used for the 'memberof' group search mode.
# distinguished_name: ''
## The attribute holding the username of the user. This attribute is used to populate the username in the session
## information. For your information, Microsoft Active Directory usually uses 'sAMAccountName' and OpenLDAP
## usually uses 'uid'. Beware that this attribute holds the unique identifiers for the users binding the user and
## the configuration stored in database; therefore only single value attributes are allowed and the value must
## never be changed once attributed to a user otherwise it would break the configuration for that user.
## Technically non-unique attributes like 'mail' can also be used but we don't recommend using them, we instead
## advise to use a filter to perform alternative lookups and the attributes mentioned above
## (sAMAccountName and uid) to follow https://datatracker.ietf.org/doc/html/rfc2307.
# username: 'uid'
## The attribute holding the display name of the user. This will be used to greet an authenticated user.
# display_name: 'displayName'
## The attribute holding the mail address of the user. If multiple email addresses are defined for a user, only
## the first one returned by the directory server is used.
# mail: 'mail'
## The attribute which provides distinguished names of groups an object is a member of.
## Only used for the 'memberof' group search mode.
# member_of: 'memberOf'
## The attribute holding the name of the group.
# group_name: 'cn'
##
## File (Authentication Provider)
##
## With this backend, the users database is stored in a file which is updated when users reset their passwords.
## Therefore, this backend is meant to be used in a dev environment and not in production since it prevents Authelia
## to be scaled to more than one instance. The options under 'password' have sane defaults, and as it has security
## implications it is highly recommended you leave the default values. Before considering changing these settings
## please read the docs page below:
## https://www.authelia.com/r/passwords#tuning
##
## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
##
# file:
# path: '/config/users_database.yml'
# watch: false
# search:
# email: false
# case_insensitive: false
# password:
# algorithm: 'argon2'
# argon2:
# variant: 'argon2id'
# iterations: 3
# memory: 65536
# parallelism: 4
# key_length: 32
# salt_length: 16
# scrypt:
# variant: 'scrypt'
# iterations: 16
# block_size: 8
# parallelism: 1
# key_length: 32
# salt_length: 16
# pbkdf2:
# variant: 'sha512'
# iterations: 310000
# salt_length: 16
# sha2crypt:
# variant: 'sha512'
# iterations: 50000
# salt_length: 16
# bcrypt:
# variant: 'standard'
# cost: 12
##
## Password Policy Configuration.
##
# password_policy:
## The standard policy allows you to tune individual settings manually.
# standard:
# enabled: false
## Require a minimum length for passwords.
# min_length: 8
## Require a maximum length for passwords.
# max_length: 0
## Require uppercase characters.
# require_uppercase: true
## Require lowercase characters.
# require_lowercase: true
## Require numeric characters.
# require_number: true
## Require special characters.
# require_special: true
## zxcvbn is a well known and used password strength algorithm. It does not have tunable settings.
# zxcvbn:
# enabled: false
## Configures the minimum score allowed.
# min_score: 3
##
## Privacy Policy Configuration
##
## Parameters used for displaying the privacy policy link and drawer.
# privacy_policy:
## Enables the display of the privacy policy using the policy_url.
# enabled: false
## Enables the display of the privacy policy drawer which requires users accept the privacy policy
## on a per-browser basis.
# require_user_acceptance: false
## The URL of the privacy policy document. Must be an absolute URL and must have the 'https://' scheme.
## If the privacy policy enabled option is true, this MUST be provided.
# policy_url: ''
##
## Access Control Configuration
##
## Access control is a list of rules defining the authorizations applied for one resource to users or group of users.
##
## If 'access_control' is not defined, ACL rules are disabled and the 'deny' rule is applied, i.e., access is denied
## to everyone. Otherwise restrictions follow the rules defined.
##
## Note: One can use the wildcard * to match any subdomain.
## It must stand at the beginning of the pattern. (example: *.example.com)
##
## Note: You must put patterns containing wildcards between simple quotes for the YAML to be syntactically correct.
##
## Definition: A 'rule' is an object with the following keys: 'domain', 'subject', 'policy' and 'resources'.
##
## - 'domain' defines which domain or set of domains the rule applies to.
##
## - 'subject' defines the subject to apply authorizations to. This parameter is optional and matching any user if not
## provided. If provided, the parameter represents either a user or a group. It should be of the form
## 'user:<username>' or 'group:<groupname>'.
##
## - 'policy' is the policy to apply to resources. It must be either 'bypass', 'one_factor', 'two_factor' or 'deny'.
##
## - 'resources' is a list of regular expressions that matches a set of resources to apply the policy to. This parameter
## is optional and matches any resource if not provided.
##
## Note: the order of the rules is important. The first policy matching (domain, resource, subject) applies.
# access_control:
## Default policy can either be 'bypass', 'one_factor', 'two_factor' or 'deny'. It is the policy applied to any
## resource if there is no policy to be applied to the user.
# default_policy: 'deny'
# rules:
## Rules applied to everyone
# - domain: 'public.example.com'
# policy: 'bypass'
## Domain Regex examples. Generally we recommend just using a standard domain.
# - domain_regex: '^(?P<User>\w+)\.example\.com$'
# policy: 'one_factor'
# - domain_regex: '^(?P<Group>\w+)\.example\.com$'
# policy: 'one_factor'
# - domain_regex:
# - '^appgroup-.*\.example\.com$'
# - '^appgroup2-.*\.example\.com$'
# policy: 'one_factor'
# - domain_regex: '^.*\.example\.com$'
# policy: 'two_factor'
# - domain: 'secure.example.com'
# policy: 'one_factor'
## Network based rule, if not provided any network matches.
# networks:
# - 'internal'
# - 'VPN'
# - '192.168.1.0/24'
# - '10.0.0.1'
# - domain:
# - 'secure.example.com'
# - 'private.example.com'
# policy: 'two_factor'
# - domain: 'singlefactor.example.com'
# policy: 'one_factor'
## Rules applied to 'admins' group
# - domain: 'mx2.mail.example.com'
# subject: 'group:admins'
# policy: 'deny'
# - domain: '*.example.com'
# subject:
# - 'group:admins'
# - 'group:moderators'
# policy: 'two_factor'
## Rules applied to 'dev' group
# - domain: 'dev.example.com'
# resources:
# - '^/groups/dev/.*$'
# subject: 'group:dev'
# policy: 'two_factor'
## Rules applied to user 'john'
# - domain: 'dev.example.com'
# resources:
# - '^/users/john/.*$'
# subject: 'user:john'
# policy: 'two_factor'
## Rules applied to user 'harry'
# - domain: 'dev.example.com'
# resources:
# - '^/users/harry/.*$'
# subject: 'user:harry'
# policy: 'two_factor'
## Rules applied to user 'bob'
# - domain: '*.mail.example.com'
# subject: 'user:bob'
# policy: 'two_factor'
# - domain: 'dev.example.com'
# resources:
# - '^/users/bob/.*$'
# subject: 'user:bob'
# policy: 'two_factor'
##
## Session Provider Configuration
##
## The session cookies identify the user once logged in.
## The available providers are: `memory`, `redis`. Memory is the provider unless redis is defined.
session:
## The secret to encrypt the session data. This is only used with Redis / Redis Sentinel.
## Secret can also be set using a secret: https://www.authelia.com/c/secrets
secret: 'insecure_session_secret'
## Cookies configures the list of allowed cookie domains for sessions to be created on.
## Undefined values will default to the values below.
# cookies:
# -
## The name of the session cookie.
# name: 'authelia_session'
## The domain to protect.
## Note: the Authelia portal must also be in that domain.
# domain: 'example.com'
## Required. The fully qualified URI of the portal to redirect users to on proxies that support redirections.
## Rules:
## - MUST use the secure scheme 'https://'
## - The above 'domain' option MUST either:
## - Match the host portion of this URI.
## - Match the suffix of the host portion when prefixed with '.'.
# authelia_url: 'https://auth.example.com'
## Optional. The fully qualified URI used as the redirection location if the portal is accessed directly. Not
## configuring this option disables the automatic redirection behaviour.
##
## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication
## unless they were redirected to Authelia by the proxy.
##
## Rules:
## - MUST use the secure scheme 'https://'
## - MUST not match the 'authelia_url' option.
## - The above 'domain' option MUST either:
## - Match the host portion of this URI.
## - Match the suffix of the host portion when prefixed with '.'.
# default_redirection_url: 'https://www.example.com'
## Sets the Cookie SameSite value. Possible options are none, lax, or strict.
## Please read https://www.authelia.com/c/session#same_site
# same_site: 'lax'
## The value for inactivity, expiration, and remember_me are in seconds or the duration common syntax.
## All three of these values affect the cookie/session validity period. Longer periods are considered less secure
## because a stolen cookie will last longer giving attackers more time to spy or attack.
## The inactivity time before the session is reset. If expiration is set to 1h, and this is set to 5m, if the user
## does not select the remember me option their session will get destroyed after 1h, or after 5m since the last
## time Authelia detected user activity.
# inactivity: '5 minutes'
## The time before the session cookie expires and the session is destroyed if remember me IS NOT selected by the
## user.
# expiration: '1 hour'
## The time before the cookie expires and the session is destroyed if remember me IS selected by the user. Setting
## this value to -1 disables remember me for this session cookie domain. If allowed and the user uses the remember
## me checkbox this overrides the expiration option and disables the inactivity option.
# remember_me: '1 month'
## Cookie Session Domain default 'name' value.
# name: 'authelia_session'
## Cookie Session Domain default 'same_site' value.
# same_site: 'lax'
## Cookie Session Domain default 'inactivity' value.
# inactivity: '5m'
## Cookie Session Domain default 'expiration' value.
# expiration: '1h'
## Cookie Session Domain default 'remember_me' value.
# remember_me: '1M'
##
## Redis Provider
##
## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
##
# redis:
# host: '127.0.0.1'
# port: 6379
## Use a unix socket instead
# host: '/var/run/redis/redis.sock'
## The connection timeout in the duration common syntax.
# timeout: '5 seconds'
## The maximum number of retries on a failed command. Set it to 0 to disable retries.
# max_retries: 3
## Username used for redis authentication. This is optional and a new feature in redis 6.0.
# username: 'authelia'
## Password can also be set using a secret: https://www.authelia.com/c/secrets
# password: 'authelia'
## This is the Redis DB Index https://redis.io/commands/select (sometimes referred to as database number, DB, etc).
# database_index: 0
## The maximum number of concurrent active connections to Redis.
# maximum_active_connections: 8
## The target number of idle connections to have open ready for work. Useful when opening connections is slow.
# minimum_idle_connections: 0
## The Redis TLS configuration. If defined will require a TLS connection to the Redis instance(s).
# tls:
## The server subject name to check the servers certificate against during the validation process.
## This option is not required if the certificate has a SAN which matches the host option.
# server_name: 'myredis.example.com'
## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the
## certificate or the certificate of the authority signing the certificate to the certificates directory which is
## defined by the `certificates_directory` option at the top of the configuration.
## It's important to note the public key should be added to the directory, not the private key.
## This option is strongly discouraged but may be useful in some self-signed situations where validation is not
## important to the administrator.
# skip_verify: false
## Minimum TLS version for the connection.
# minimum_version: 'TLS1.2'
## Maximum TLS version for the connection.
# maximum_version: 'TLS1.3'
## The certificate chain used with the private_key if the server requests TLS Client Authentication
## i.e. Mutual TLS.
# certificate_chain: |
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
## The private key used with the certificate_chain if the server requests TLS Client Authentication
## i.e. Mutual TLS.
# private_key: |
# -----BEGIN PRIVATE KEY-----
# ...
# -----END PRIVATE KEY-----
## The Redis HA configuration options.
## This provides specific options to Redis Sentinel, sentinel_name must be defined (Master Name).
# high_availability:
## Sentinel Name / Master Name.
# sentinel_name: 'mysentinel'
## Specific username for Redis Sentinel. The node username and password is configured above.
# sentinel_username: 'sentinel_specific_user'
## Specific password for Redis Sentinel. The node username and password is configured above.
# sentinel_password: 'sentinel_specific_pass'
## The additional nodes to pre-seed the redis provider with (for sentinel).
## If the host in the above section is defined, it will be combined with this list to connect to sentinel.
## For high availability to be used you must have either defined; the host above or at least one node below.
# nodes:
# - host: 'sentinel-node1'
# port: 6379
# - host: 'sentinel-node2'
# port: 6379
## Choose the host with the lowest latency.
# route_by_latency: false
## Choose the host randomly.
# route_randomly: false
##
## Regulation Configuration
##
## This mechanism prevents attackers from brute forcing the first factor. It bans the user if too many attempts are made
## in a short period of time.
# regulation:
## Regulation Mode.
# modes:
# - 'user'
## The number of failed login attempts before user is banned. Set it to 0 to disable regulation.
# max_retries: 3
## The time range during which the user can attempt login before being banned in the duration common syntax. The user
## is banned if the authentication failed 'max_retries' times in a 'find_time' seconds window.
# find_time: '2 minutes'
## The length of time before a banned user can login again in the duration common syntax.
# ban_time: '5 minutes'
##
## Storage Provider Configuration
##
## The available providers are: `local`, `mysql`, `postgres`. You must use one and only one of these providers.
# storage:
## The encryption key that is used to encrypt sensitive information in the database. Must be a string with a minimum
## length of 20. Please see the docs if you configure this with an undesirable key and need to change it, you MUST use
## the CLI to change this in the database if you want to change it from a previously configured value.
# encryption_key: 'you_must_generate_a_random_string_of_more_than_twenty_chars_and_configure_this'
##
## Local (Storage Provider)
##
## This stores the data in a SQLite3 Database.
## This is only recommended for lightweight non-stateful installations.
##
## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
##
# local:
## Path to the SQLite3 Database.
# path: '/config/db.sqlite3'
##
## MySQL / MariaDB (Storage Provider)
##
# mysql:
## The address of the MySQL server to connect to in the address common syntax.
## Format: [<scheme>://]<hostname>[:<port>].
## Square brackets indicate optional portions of the format. Scheme must be 'tcp', 'tcp4', 'tcp6', or 'unix`.
## The default scheme is 'unix' if the address is an absolute path otherwise it's 'tcp'. The default port is '3306'.
# address: 'tcp://127.0.0.1:3306'
## The database name to use.
# database: 'authelia'
## The username used for SQL authentication.
# username: 'authelia'
## The password used for SQL authentication.
## Can also be set using a secret: https://www.authelia.com/c/secrets
# password: 'mypassword'
## The connection timeout in the duration common syntax.
# timeout: '5 seconds'
## MySQL TLS settings. Configuring this requires TLS.
# tls:
## The server subject name to check the servers certificate against during the validation process.
## This option is not required if the certificate has a SAN which matches the address options hostname.
# server_name: 'mysql.example.com'
## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the
## certificate or the certificate of the authority signing the certificate to the certificates directory which is
## defined by the `certificates_directory` option at the top of the configuration.
## It's important to note the public key should be added to the directory, not the private key.
## This option is strongly discouraged but may be useful in some self-signed situations where validation is not
## important to the administrator.
# skip_verify: false
## Minimum TLS version for the connection.
# minimum_version: 'TLS1.2'
## Maximum TLS version for the connection.
# maximum_version: 'TLS1.3'
## The certificate chain used with the private_key if the server requests TLS Client Authentication
## i.e. Mutual TLS.
# certificate_chain: |
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
## The private key used with the certificate_chain if the server requests TLS Client Authentication
## i.e. Mutual TLS.
# private_key: |
# -----BEGIN PRIVATE KEY-----
# ...
# -----END PRIVATE KEY-----
##
## PostgreSQL (Storage Provider)
##
# postgres:
## The address of the PostgreSQL server to connect to in the address common syntax.
## Format: [<scheme>://]<hostname>[:<port>].
## Square brackets indicate optional portions of the format. Scheme must be 'tcp', 'tcp4', 'tcp6', or 'unix`.
## The default scheme is 'unix' if the address is an absolute path otherwise it's 'tcp'. The default port is '5432'.
# address: 'tcp://127.0.0.1:5432'
## List of additional server instance configurations to fallback to when the primary instance is not available.
# servers:
# -
## The Address of this individual instance.
# address: 'tcp://127.0.0.1:5432'
## The TLS configuration for this individual instance.
# tls:
# server_name: 'postgres.example.com'
# skip_verify: false
# minimum_version: 'TLS1.2'
# maximum_version: 'TLS1.3'
# certificate_chain: |
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
# private_key: |
# -----BEGIN PRIVATE KEY-----
# ...
# -----END PRIVATE KEY-----
## The database name to use.
# database: 'authelia'
## The schema name to use.
# schema: 'public'
## The username used for SQL authentication.
# username: 'authelia'
## The password used for SQL authentication.
## Can also be set using a secret: https://www.authelia.com/c/secrets
# password: 'mypassword'
## The connection timeout in the duration common syntax.
# timeout: '5 seconds'
## PostgreSQL TLS settings. Configuring this requires TLS.
# tls:
## The server subject name to check the servers certificate against during the validation process.
## This option is not required if the certificate has a SAN which matches the address options hostname.
# server_name: 'postgres.example.com'
## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the
## certificate or the certificate of the authority signing the certificate to the certificates directory which is
## defined by the `certificates_directory` option at the top of the configuration.
## It's important to note the public key should be added to the directory, not the private key.
## This option is strongly discouraged but may be useful in some self-signed situations where validation is not
## important to the administrator.
# skip_verify: false
## Minimum TLS version for the connection.
# minimum_version: 'TLS1.2'
## Maximum TLS version for the connection.
# maximum_version: 'TLS1.3'
## The certificate chain used with the private_key if the server requests TLS Client Authentication
## i.e. Mutual TLS.
# certificate_chain: |
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
## The private key used with the certificate_chain if the server requests TLS Client Authentication
## i.e. Mutual TLS.
# private_key: |
# -----BEGIN PRIVATE KEY-----
# ...
# -----END PRIVATE KEY-----
##
## Notification Provider
##
## Notifications are sent to users when they require a password reset, a WebAuthn registration or a TOTP registration.
## The available providers are: filesystem, smtp. You must use only one of these providers.
# notifier:
## You can disable the notifier startup check by setting this to true.
# disable_startup_check: false
##
## File System (Notification Provider)
##
## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
##
# filesystem:
# filename: '/config/notification.txt'
##
## SMTP (Notification Provider)
##
## Use a SMTP server for sending notifications. Authelia uses the PLAIN or LOGIN methods to authenticate.
## [Security] By default Authelia will:
## - force all SMTP connections over TLS including unauthenticated connections
## - use the disable_require_tls boolean value to disable this requirement
## (only works for unauthenticated connections)
## - validate the SMTP server x509 certificate during the TLS handshake against the hosts trusted certificates
## (configure in tls section)
# smtp:
## The address of the SMTP server to connect to in the address common syntax.
# address: 'smtp://127.0.0.1:25'
## The connection timeout in the duration common syntax.
# timeout: '5 seconds'
## The username used for SMTP authentication.
# username: 'test'
## The password used for SMTP authentication.
## Can also be set using a secret: https://www.authelia.com/c/secrets
# password: 'password'
## The sender is used to is used for the MAIL FROM command and the FROM header.
## If this is not defined and the username is an email, we use the username as this value. This can either be just
## an email address or the RFC5322 'Name <email address>' format.
# sender: 'Authelia <admin@example.com>'
## HELO/EHLO Identifier. Some SMTP Servers may reject the default of localhost.
# identifier: 'localhost'
## Subject configuration of the emails sent. {title} is replaced by the text from the notifier.
# subject: '[Authelia] {title}'
## This address is used during the startup check to verify the email configuration is correct.
## It's not important what it is except if your email server only allows local delivery.
# startup_check_address: 'test@authelia.com'
## By default we require some form of TLS. This disables this check though is not advised.
# disable_require_tls: false
## Disables sending HTML formatted emails.
# disable_html_emails: false
# tls:
## The server subject name to check the servers certificate against during the validation process.
## This option is not required if the certificate has a SAN which matches the address options hostname.
# server_name: 'smtp.example.com'
## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the
## certificate or the certificate of the authority signing the certificate to the certificates directory which is
## defined by the `certificates_directory` option at the top of the configuration.
## It's important to note the public key should be added to the directory, not the private key.
## This option is strongly discouraged but may be useful in some self-signed situations where validation is not
## important to the administrator.
# skip_verify: false
## Minimum TLS version for the connection.
# minimum_version: 'TLS1.2'
## Maximum TLS version for the connection.
# maximum_version: 'TLS1.3'
## The certificate chain used with the private_key if the server requests TLS Client Authentication
## i.e. Mutual TLS.
# certificate_chain: |
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
## The private key used with the certificate_chain if the server requests TLS Client Authentication
## i.e. Mutual TLS.
# private_key: |
# -----BEGIN PRIVATE KEY-----
# ...
# -----END PRIVATE KEY-----
##
## Identity Providers
##
# identity_providers:
##
## OpenID Connect (Identity Provider)
##
## It's recommended you read the documentation before configuration of this section.
## See: https://www.authelia.com/c/oidc/provider
# oidc:
## The hmac_secret is used to sign OAuth2 tokens (authorization code, access tokens and refresh tokens).
## HMAC Secret can also be set using a secret: https://www.authelia.com/c/secrets
# hmac_secret: 'this_is_a_secret_abc123abc123abc'
## The JWK's issuer option configures multiple JSON Web Keys. It's required that at least one of the JWK's
## configured has the RS256 algorithm. For RSA keys (RS or PS) the minimum is a 2048 bit key.
# jwks:
# -
## Key ID embedded into the JWT header for key matching. Must be an alphanumeric string with 7 or less characters.
## This value is automatically generated if not provided. It's recommended to not configure this.
# key_id: 'example'
## The key algorithm used with this key.
# algorithm: 'RS256'
## The key use expected with this key. Currently only 'sig' is supported.
# use: 'sig'
## Required Private Key in PEM DER form.
# key: |
# -----BEGIN PRIVATE KEY-----
# ...
# -----END PRIVATE KEY-----
## Optional matching certificate chain in PEM DER form that matches the key. All certificates within the chain
## must be valid and current, and from top to bottom each certificate must be signed by the subsequent one.
# certificate_chain: |
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
## Enables additional debug messages.
# enable_client_debug_messages: false
## SECURITY NOTICE: It's not recommended changing this option and values below 8 are strongly discouraged.
# minimum_parameter_entropy: 8
## SECURITY NOTICE: It's not recommended changing this option, and highly discouraged to have it set to 'never'
## for security reasons.
# enforce_pkce: 'public_clients_only'
## SECURITY NOTICE: It's not recommended changing this option. We encourage you to read the documentation and fully
## understanding it before enabling this option.
# enable_jwt_access_token_stateless_introspection: false
## The signing algorithm used for signing the discovery and metadata responses. An issuer JWK with a matching
## algorithm must be available when configured. Most clients completely ignore this and it has a performance cost.
# discovery_signed_response_alg: 'none'
## The signing key id used for signing the discovery and metadata responses. An issuer JWK with a matching key id
## must be available when configured. Most clients completely ignore this and it has a performance cost.
# discovery_signed_response_key_id: ''
## Authorization Policies which can be utilized by clients. The 'policy_name' is an arbitrary value that you pick
## which is utilized as the value for the 'authorization_policy' on the client.
# authorization_policies:
# policy_name:
# default_policy: 'two_factor'
# rules:
# - policy: 'one_factor'
# subject: 'group:services'
# networks:
# - '192.168.1.0/24'
## The lifespans configure the expiration for these token types in the duration common syntax. In addition to this
## syntax the lifespans can be customized per-client.
# lifespans:
## Configures the default/fallback lifespan for given token types. This behaviour applies to all clients and all
## grant types but you can override this behaviour using the custom lifespans.
# access_token: '1 hour'
# authorize_code: '1 minute'
# id_token: '1 hour'
# refresh_token: '90 minutes'
## Cross-Origin Resource Sharing (CORS) settings.
# cors:
## List of endpoints in addition to the metadata endpoints to permit cross-origin requests on.
# endpoints:
# - 'authorization'
# - 'pushed-authorization-request'
# - 'token'
# - 'revocation'
# - 'introspection'
# - 'userinfo'
## List of allowed origins.
## Any origin with https is permitted unless this option is configured or the
## allowed_origins_from_client_redirect_uris option is enabled.
# allowed_origins:
# - 'https://example.com'
## Automatically adds the origin portion of all redirect URI's on all clients to the list of allowed_origins,
## provided they have the scheme http or https and do not have the hostname of localhost.
# allowed_origins_from_client_redirect_uris: false
## Clients is a list of registered clients and their configuration.
## It's recommended you read the documentation before configuration of a registered client.
## See: https://www.authelia.com/c/oidc/registered-clients
# clients:
# -
## The Client ID is the OAuth 2.0 and OpenID Connect 1.0 Client ID which is used to link an application to a
## configuration.
# client_id: 'myapp'
## The description to show to users when they end up on the consent screen. Defaults to the ID above.
# client_name: 'My Application'
## The client secret is a shared secret between Authelia and the consumer of this client.
# yamllint disable-line rule:line-length
# client_secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'.
## Sector Identifiers are occasionally used to generate pairwise subject identifiers. In most cases this is not
## necessary. It is critical to read the documentation for more information.
# sector_identifier_uri: 'https://example.com/sector.json'
## Sets the client to public. This should typically not be set, please see the documentation for usage.
# public: false
## Redirect URI's specifies a list of valid case-sensitive callbacks for this client.
# redirect_uris:
# - 'https://oidc.example.com:8080/oauth2/callback'
## Request URI's specifies a list of valid case-sensitive TLS-secured URIs for this client for use as
## URIs to fetch Request Objects.
# request_uris:
# - 'https://oidc.example.com:8080/oidc/request-object.jwk'
## Audience this client is allowed to request.
# audience: []
## Scopes this client is allowed to request.
# scopes:
# - 'openid'
# - 'groups'
# - 'email'
# - 'profile'
## Grant Types configures which grants this client can obtain.
## It's not recommended to define this unless you know what you're doing.
# grant_types:
# - 'authorization_code'
## Response Types configures which responses this client can be sent.
## It's not recommended to define this unless you know what you're doing.
# response_types:
# - 'code'
## Response Modes configures which response modes this client supports.
# response_modes:
# - 'form_post'
# - 'query'
## The policy to require for this client; one_factor or two_factor. Can also be the key names for the
## authorization policies section.
# authorization_policy: 'two_factor'
## The custom lifespan name to use for this client. This must be configured independent of the client before
## utilization. Custom lifespans are reusable similar to authorization policies.
# lifespan: ''
## The consent mode controls how consent is obtained.
# consent_mode: 'auto'
## This value controls the duration a consent on this client remains remembered when the consent mode is
## configured as 'auto' or 'pre-configured' in the duration common syntax.
# pre_configured_consent_duration: '1 week'
## Requires the use of Pushed Authorization Requests for this client when set to true.
# require_pushed_authorization_requests: false
## Enforces the use of PKCE for this client when set to true.
# require_pkce: false
## Enforces the use of PKCE for this client when configured, and enforces the specified challenge method.
## Options are 'plain' and 'S256'.
# pkce_challenge_method: 'S256'
## The signing algorithm used for signing the authorization responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#authorization_signed_response_alg
# authorization_signed_response_alg: 'none'
## The signing key id used for signing the authorization responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#authorization_signed_response_key_id
# authorization_signed_response_key_id: ''
## The content encryption algorithm used for encrypting the authorization responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#authorization_encrypted_response_alg
# authorization_encrypted_response_alg: 'none'
## The encryption algorithm used for encrypting the authorization responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#authorization_encrypted_response_enc
# authorization_encrypted_response_enc: 'A128CBC-HS256'
## The content encryption key id used for encrypting the authorization responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#authorization_encrypted_response_key_id
# authorization_encrypted_response_key_id: ''
## The signing algorithm used for signing the ID Tokens in Access Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#id_token_signed_response_alg
# id_token_signed_response_alg: 'RS256'
## The signing key id used for signing the ID Tokens in Access Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#id_token_signed_response_key_id
# id_token_signed_response_key_id: ''
## The content encryption algorithm used for encrypting the ID Tokens in Access Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#id_token_encrypted_response_alg
# id_token_encrypted_response_alg: 'none'
## The encryption algorithm used for encrypting the ID Tokens in Access Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#id_token_encrypted_response_enc
# id_token_encrypted_response_enc: 'A128CBC-HS256'
## The content encryption key id used for encrypting the ID Tokens in Access Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#authorization_encrypted_response_key_id
# id_token_encrypted_response_key_id: ''
## The signing algorithm used for signing the Access Tokens in Access Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#access_token_signed_response_alg
# access_token_signed_response_alg: 'none'
## The signing key id used for signing the Access Tokens in Access Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#access_token_signed_response_key_id
# access_token_signed_response_key_id: ''
## The content encryption algorithm used for encrypting the Access Tokens in Access Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#access_token_encrypted_response_alg
# access_token_encrypted_response_alg: 'none'
## The encryption algorithm used for encrypting the Access Tokens in Access Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#access_token_encrypted_response_enc
# access_token_encrypted_response_enc: 'A128CBC-HS256'
## The content encryption key id used for encrypting the Access Tokens in Access Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#access_token_encrypted_response_key_id
# access_token_encrypted_response_key_id: ''
## The signing algorithm used for signing the User Info Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#userinfo_signed_response_alg
# userinfo_signed_response_alg: 'none'
## The signing key id used for signing the User Info Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#userinfo_signed_response_key_id
# userinfo_signed_response_key_id: ''
## The content encryption algorithm used for encrypting the User Info Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#userinfo_encrypted_response_alg
# userinfo_encrypted_response_alg: 'none'
## The encryption algorithm used for encrypting the User Info Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#userinfo_encrypted_response_enc
# userinfo_encrypted_response_enc: 'A128CBC-HS256'
## The content encryption key id used for encrypting the User Info Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#userinfo_encrypted_response_key_id
# userinfo_encrypted_response_key_id: ''
## The signing algorithm used for signing the Introspection Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#introspection_signed_response_alg
# introspection_signed_response_alg: 'none'
## The signing key id used for Introspection responses. An issuer JWK with a matching key id must be available
## when configured.
# introspection_signed_response_key_id: ''
## The content encryption algorithm used for encrypting the Introspection Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#introspection_encrypted_response_alg
# introspection_encrypted_response_alg: 'none'
## The encryption algorithm used for encrypting the Introspection Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#introspection_encrypted_response_enc
# introspection_encrypted_response_enc: 'A128CBC-HS256'
## The content encryption key id used for encrypting the Introspection Request responses.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#introspection_encrypted_response_key_id
# introspection_encrypted_response_key_id: ''
## The signature algorithm which must be used for request objects.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#request_object_signing_alg
# request_object_signing_alg: 'RS256'
## The content encryption algorithm which must be used for request objects.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#request_object_encryption_alg
# request_object_encryption_alg: ''
## The encryption algorithm which must be used for request objects.
## Please read the documentation before adjusting this option.
## See: https://www.authelia.com/c/oidc/registered-clients#request_object_encryption_enc
# request_object_encryption_enc: ''
## The permitted client authentication method for the Token Endpoint for this client.
## For confidential client types this value defaults to 'client_secret_basic' and for the public client types it
## defaults to 'none' per the specifications.
# token_endpoint_auth_method: 'client_secret_basic'
## The permitted client authentication signing algorithm for the Token Endpoint for this client when using
## the 'client_secret_jwt' or 'private_key_jwt' token_endpoint_auth_method.
# token_endpoint_auth_signing_alg: 'RS256'
## The permitted client authentication method for the Revocation Endpoint for this client.
## For confidential client types this value defaults to 'client_secret_basic' and for the public client types it
## defaults to 'none' per the specifications.
# revocation_endpoint_auth_method: 'client_secret_basic'
## The permitted client authentication signing algorithm for the Revocation Endpoint for this client when using
## the 'client_secret_jwt' or 'private_key_jwt' revocation_endpoint_auth_method.
# revocation_endpoint_auth_signing_alg: 'RS256'
## The permitted client authentication method for the Introspection Endpoint for this client.
## For confidential client types this value defaults to 'client_secret_basic' and for the public client types it
## defaults to 'none' per the specifications.
# introspection_endpoint_auth_method: 'client_secret_basic'
## The permitted client authentication signing algorithm for the Introspection Endpoint for this client when
## using the 'client_secret_jwt' or 'private_key_jwt' introspection_endpoint_auth_method.
# introspection_endpoint_auth_signing_alg: 'RS256'
## The permitted client authentication method for the Pushed Authorization Request Endpoint for this client.
## For confidential client types this value defaults to 'client_secret_basic' and for the public client types it
## defaults to 'none' per the specifications.
# pushed_authorization_request_endpoint_auth_method: 'client_secret_basic'
## The permitted client authentication signing algorithm for the Pushed Authorization Request Endpoint for this
## client when using the 'client_secret_jwt' or 'private_key_jwt'
## pushed_authorization_request_endpoint_auth_method.
# pushed_authorization_request_endpoint_auth_signing_alg: 'RS256'
## Trusted public keys configuration for request object signing for things such as 'private_key_jwt'.
## URL of the HTTPS endpoint which serves the keys. Please note the 'jwks_uri' and the 'jwks' option below
## are mutually exclusive.
# jwks_uri: 'https://app.example.com/jwks.json'
## Trusted public keys configuration for request object signing for things such as 'private_key_jwt'.
## List of JWKs known and registered with this client. It's recommended to use the 'jwks_uri' option if
## available due to key rotation. Please note the 'jwks' and the 'jwks_uri' option above are mutually exclusive.
# jwks:
# -
## Key ID used to match the JWT's to an individual identifier. This option is required if configured.
# key_id: 'example'
## The key algorithm expected with this key.
# algorithm: 'RS256'
## The key use expected with this key. Currently only 'sig' is supported.
# use: 'sig'
## Required Public Key in PEM DER form.
# key: |
# -----BEGIN RSA PUBLIC KEY-----
# ...
# -----END RSA PUBLIC KEY-----
## The matching certificate chain in PEM DER form that matches the key if available.
# certificate_chain: |
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
...
Синтаксис
Ключи
policies: # словарь ключа
arbitrary_name: # значение ключа для последующего использования в блоке usage_example
enable: true
usage_example:
- name: 'example'
policy: 'arbitrary_name' # использование ключа policy
Время
| Unit | Short Unit | Human Readable Long Unit |
|---|---|---|
| Years | y | year, years |
| Months | M | month, months |
| Weeks | w | week, weeks |
| Days | d | day, days |
| Hours | h | hour, hours |
| Minutes | m | minute, minutes |
| Seconds | s | second, seconds |
| Milliseconds | ms | millisecond, milliseconds |
В настройках указываются значения в коротком или длинном формате
| Desired Value | Configuration Examples (Short) | Configuration Examples (Long) |
|---|---|---|
| 1 hour and 30 minutes | 90m or 1h30m or 5400 or 5400s | 1 hour and 30 minutes |
| 1 day | 1d or 24h or 86400 or 86400s | 1 day |
| 10 hours | 10h or 600m or 9h60m or 36000 | 10 hours |
Адрес
Строковая переменная
Параметры
| Parameter | Listeners | Connectors | Purpose |
|---|---|---|---|
| umask | Да | Нет | Устанавливает umask перед созданием сокета и восстанавливает его после создания. Значение должно быть восьмеричным числом с 3 или 4 цифрами. |
| path | Да | Нет | Устанавливает переменную path для настройки подпути, специально для unix-сокета, но технически работает и для TCP. Обратите внимание, что это должна быть только буквенно-цифровая часть без префикса в виде прямой косой черты. |
Формат
Квадратные скобки обозначают необязательные разделы, а угловые скобки - обязательные разделы.
Hostname
Имя хоста
Следующий формат представляет собой формат имени хоста. В большинстве случаев он подходит как для слушателя, так и для коннектора. В этом формате, согласно обозначениям, схема и порт являются необязательными. Если они не указаны, то используются по умолчанию.
[<scheme>://]<hostname>[:<port>][/<path>]
Файл дескриптор
fd://<file descriptor number>
fd://<file descriptor number>?umask=0022
fd://<file descriptor number>?path=auth
fd://<file descriptor number>?umask=0022&path=auth
Unix domain socket
unix://<path>
unix://<path>?umask=0022
unix://<path>?path=auth
unix://<path>?umask=0022&path=auth
В большинстве случаев он подходит как для слушателя, так и для коннектора.
Формат Unix Domain Socket также принимает строку запроса.
Примеры
0.0.0.0
tcp://0.0.0.0
tcp://0.0.0.0/subpath
tcp://0.0.0.0:9091
tcp://0.0.0.0:9091/subpath
tcp://:9091
tcp://:9091/subpath
0.0.0.0:9091
udp://0.0.0.0:123
udp://:123
unix:///var/lib/authelia.sock
Scheme
Вся схема не является обязательной, но если в строке присутствует разделитель узла схемы ://, то схема должна присутствовать.
| Scheme | Listeners | Connectors | Default Port | Notes |
|---|---|---|---|---|
| tcp | Yes | Yes | N/A | Standard TCP Socket which allows IPv4 and/or IPv6 addresses |
| tcp4 | Yes | Yes | N/A | Standard TCP Socket which allows only IPv4 addresses |
| tcp6 | Yes | Yes | N/A | Standard TCP Socket which allows only IPv6 addresses |
| udp | Yes | Yes | N/A | Standard UDP Socket which allows IPv4 and/or IPv6 addresses |
| udp4 | Yes | Yes | N/A | Standard UDP Socket which allows only IPv4 addresses |
| udp6 | Yes | Yes | N/A | Standard UDP Socket which allows only IPv6 addresses |
| unix | Yes | Yes | N/A | Standard Unix Domain Socket which allows only absolute paths |
| ldap | No | Yes | 389 | Remote LDAP connection via a TCP socket using StartTLS if available |
| ldaps | No | Yes | 636 | Remote LDAP connection via a TLS socket |
| ldapi | No | Yes | N/A | LDAP connection via Unix Domain Socket |
| smtp | No | Yes | 25 | Remote SMTP connection via a TCP socket using StartTLS if available |
| submission | No | Yes | 587 | Remote SMTP Submission connection via a TCP socket using StartTLS if available |
| submissions | No | Yes | 465 | Remote SMTP Submission connection via a TLS socket |
hostname
Имя хоста требуется, если схема является одной из схем tcp или udp и не указан порт. Это может быть любой локально адресуемый IP или имя хоста, которое разрешается в локально адресуемый IP.
При указании IPv6 он должен быть заключен в квадратные скобки. Например, для IPv6-адреса ::1 со схемой tcp и портом 80 правильным адресом будет tcp://[::1]:80.
Регулярные выражения
domain_regex: '^(admin|secure)\.example\.com$'
Network
Мы поддерживаем сетевой синтаксис, который разворачивает строки в сетевой диапазон. Формат строк использует стандартную нотацию CIDR и предполагает наличие одного хоста (адаптированного как /32 для IPv4 и /128 для IPv6), если суффикс CIDR отсутствует.
| Example | CIDR | Range |
|---|---|---|
| 192.168.0.1 | 192.168.0.1/32 | 192.168.0.1 |
| 192.168.1.0/24 | 192.168.1.0/24 | 192.168.1.0 - 192.168.1.255 |
| 192.168.2.1/24 | 192.168.2.0/24 | 192.168.2.0 - 192.168.2.255 |
| 2001:db8:3333:4444:5555:6666:7777:8888 | 2001:db8:3333:4444:5555:6666:7777:8888/128 | 2001:db8:3333:4444:5555:6666:7777:8888 |
| 2001:db8:3333:4400::/56 | 2001:db8:3333:4400::/56 | 2001:0db8:3333:4400:0000:0000:0000:0000 - 2001:0db8:3333:44ff:ffff:ffff:ffff:ffff |
| 2001:db8:3333:4444:5555:6666:7777:8888/56 | 2001:db8:3333:4400::/56 | 2001:0db8:3333:4400:0000:0000:0000:0000 - 2001:0db8:3333:44ff:ffff:ffff:ffff:ffff |
Структуры
Ниже представлены общие структуры данных, используемые в конфигурации, к которым предъявляются особые требования, используемые в различных областях.
TLS
В различных разделах конфигурации используется единый раздел конфигурации под названием tls, в котором настраиваются параметры TLS-сокета и TLS-проверки. В этом разделе описаны общие части этой структуры. По умолчанию Authelia использует системный сертификат доверия для проверки сертификата TLS, но вы можете дополнить его с помощью глобальной опции certificates_directory, а также полностью отключить проверку сертификата TLS с помощью опции skip_verify.
tls:
server_name: 'example.com'
skip_verify: false
minimum_version: 'TLS1.2'
maximum_version: 'TLS1.3'
certificate_chain: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
private_key: |
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
server_name
Ключ server_name переопределяет имя, проверяемое по сертификату в процессе проверки. Полезно, если вам требуется IP-адрес узла внутренней службы, но вы хотите проверить конкретное имя сервера сертификатов.
skip_verify
Ключ skip_verify полностью исключает проверку сертификата внутреннего сервиса. Это не рекомендуется, вместо этого следует настроить параметр server_name и глобальный параметр certificates directory.
minimum_version - maximum_version
Устанавливает минимальную версию TLS, которую Authelia будет использовать при выполнении сопряжений TLS. Возможные значения: TLS1.3, TLS1.2, TLS1.1, TLS1.0, SSL3.0.
certificate_chain
Цепочка/набор сертификатов, которые будут использоваться вместе с private_key для выполнения взаимной TLS-аутентификации с сервером.
Значение должно представлять собой один или несколько сертификатов, закодированных в формате PEM с кодировкой DER base64 (RFC4648). Если предоставлено более одного сертификата, то каждый сертификат должен быть подписан следующим сертификатом, если он предоставлен, в порядке сверху вниз.
private_key
Закрытый ключ, который будет использоваться с цепочкой_сертификатов для взаимной аутентификации TLS. Материал открытого ключа, связанного с закрытым ключем, должен совпадать с закрытым ключом первого сертификата в цепочке_сертификатов.
Значение должно представлять собой один закрытый ключ, закодированный в формате PEM DER base64 (RFC4648), и должно быть закодировано в соответствии со спецификациями PKCS#8, PKCS#1 или SECG1.
Server Buffers
Различные разделы конфигурации используют единый раздел конфигурации под названием buffers, который настраивает буферы HTTP-сервера. В частности, секции сервера и телеметрии метрик. В этом разделе описаны общие части этой структуры.
buffers:
read: 4096
write: 4096
read
Настройка максимального размера запроса. Значение по умолчанию 4096 обычно достаточно для большинства случаев использования.
write
Настройка максимального размера ответа. Значение по умолчанию 4096 обычно достаточно для большинства случаев использования.
Server Timeouts
В различных разделах конфигурации используется единый раздел конфигурации под названием timeouts, в котором настраиваются таймауты HTTP-сервера. В частности, в секциях телеметрии сервера и метрик.
timeouts:
read: '6s'
write: '6s'
idle: '30s'
read write
Настройка таймаута чтения и записи сервера.
idle
Настройка таймаута простоя сервера.
3.2 - Методы Authelia
Методы
Authelia имеет несколько способов настройки. Порядок приоритета следующий:
- Секреты
- Переменные окружения
- Файлы (в порядке их указания)
3.2.1 - Секреты Authelia
Для настройки Authelia требуется несколько секретов и паролей. Даже если они могут быть заданы в конфигурационном файле или стандартных переменных окружения, рекомендуется использовать этот метод настройки, описанный ниже.
Filters
Помимо описанных ниже методов, файлы конфигурации можно передавать через фильтры шаблонов. Эти фильтры можно использовать для вставки или изменения содержимого файла. В частности, функция fileContent может быть использована для получения содержимого файла, а nindent - для добавления новой строки и отступа содержимого этого файла.
authentication_backend:
ldap:
address: 'ldap://{{ env "SERVICES_SERVER" }}'
tls:
private_key: |
{{- fileContent "./test_resources/example_filter_rsa_private_key" | nindent 8 }}
{{ и }} ограничители шаблона
вставляем содержимое файла в ключ private_key с отступом 8 пробелов
Layers
Важно
Хотя этот метод является третьим уровнем многоуровневой модели конфигурации, как описано во введении, этот уровень особенный, так как Authelia не запустится, если вы определите секрет, как и любой другой метод конфигурации.Security
Этот метод немного улучшает безопасность других методов, поскольку позволяет легко разделить конфигурацию логически безопасным способом.
Environment variables
Секретное значение может быть загружено Authelia, если ключ конфигурации заканчивается одним из следующих слов: key, secret, password, token или certificate_chain.
Если вы возьмете ожидаемую переменную окружения для конфигурационного параметра с суффиксом _FILE в конце. Значение этих переменных окружения должно быть путем к файлу, который может быть прочитан процессом Authelia, если это не так, Authelia не сможет загрузиться. Authelia автоматически удалит новые строки в конце содержимого файлов.
Например, пароль LDAP может быть определен в конфигурации по пути authentication_backend.ldap.password, поэтому в качестве альтернативы этот пароль может быть задан с помощью переменной окружения под названием
AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE
Список переменных
| Configuration Key | Environment Variable |
|---|---|
| authentication_backend.ldap.password | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE |
| authentication_backend.ldap.tls.certificate_chain | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_CERTIFICATE_CHAIN_FILE |
| authentication_backend.ldap.tls.private_key | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_PRIVATE_KEY_FILE |
| duo_api.integration_key | AUTHELIA_DUO_API_INTEGRATION_KEY_FILE |
| duo_api.secret_key | AUTHELIA_DUO_API_SECRET_KEY_FILE |
| identity_providers.oidc.hmac_secret | AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET_FILE |
| identity_validation.reset_password.jwt_secret | AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE |
| notifier.smtp.password | AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE |
| notifier.smtp.tls.certificate_chain | AUTHELIA_NOTIFIER_SMTP_TLS_CERTIFICATE_CHAIN_FILE |
| notifier.smtp.tls.private_key | AUTHELIA_NOTIFIER_SMTP_TLS_PRIVATE_KEY_FILE |
| session.redis.high_availability.sentinel_password | AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_SENTINEL_PASSWORD_FILE |
| session.redis.password | AUTHELIA_SESSION_REDIS_PASSWORD_FILE |
| session.redis.tls.certificate_chain | AUTHELIA_SESSION_REDIS_TLS_CERTIFICATE_CHAIN_FILE |
| session.redis.tls.private_key | AUTHELIA_SESSION_REDIS_TLS_PRIVATE_KEY_FILE |
| session.secret | AUTHELIA_SESSION_SECRET_FILE |
| storage.encryption_key | AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE |
| storage.mysql.password | AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE |
| storage.mysql.tls.certificate_chain | AUTHELIA_STORAGE_MYSQL_TLS_CERTIFICATE_CHAIN_FILE |
| storage.mysql.tls.private_key | AUTHELIA_STORAGE_MYSQL_TLS_PRIVATE_KEY_FILE |
| storage.postgres.password | AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE |
| storage.postgres.tls.certificate_chain | AUTHELIA_STORAGE_POSTGRES_TLS_CERTIFICATE_CHAIN_FILE |
| storage.postgres.tls.private_key | AUTHELIA_STORAGE_POSTGRES_TLS_PRIVATE_KEY_FILE |
Секреты в конфигурационном файле
Хранение секретов
Если по каким-то причинам вы решили хранить секреты в конфигурационном файле, настоятельно рекомендуется убедиться, что права доступа к конфигурационному файлу установлены соответствующим образом, чтобы другие пользователи или процессы не могли получить доступ к этому файлу. Обычно для UNIX подходят следующие разрешения: 0600.Секреты, открытые в переменной окружения
Во всех версиях 4.30.0+ вы можете задать секреты с помощью переменных окружения без суффикса _FILE, установив значение, которое вы хотите задать в конфигурации, однако мы настоятельно рекомендуем не использовать эту возможность и вместо этого использовать файловые секреты, описанные выше.
3.2.2 - Файлы конфигурации
Поведение при загрузке и обнаружение
Существует несколько опций, которые влияют на загрузку файлов:
| Name | Argument | Environment Variable | Описание и назначение переменных |
|---|---|---|---|
| Files/Directories | --config, -c | X_AUTHELIA_CONFIG | Список путей к файлам или каталогам (без рекурсии) для загрузки файлов конфигурации |
| Filters | --config.experimental.filters | X_AUTHELIA_CONFIG_FILTERS | Список фильтров, применяемых к каждому файлу из опций «Файлы» или «Каталоги». |
Параметры конфигурации могут быть определены либо через аргумент, либо через переменную окружения, но не через оба параметра одновременно. Если указаны оба параметра, приоритет имеет аргумент, а переменная окружения игнорируется. Обычно рекомендуется использовать переменную окружения, если вы используете контейнер, так как это позволит вам легче выполнять другие команды из контекста контейнера.
Запуск контейнера с файлом конфигурации
docker run authelia/authelia:latest authelia --config configuration.yml
docker run -d authelia/authelia:latest authelia --config configuration.yml --config config-acl.yml --config config-other.yml
docker run -d authelia/authelia:latest authelia --config configuration.yml,config-acl.yml,config-other.yml
По умолчанию контейнер ищет файл конфигурации по адресу /config/configuration.yml
docker run -d --volume /path/to/config:/config authelia:authelia:latest authelia --config=/config/configuration.yml --config=/config/configuration.acl.yml
Docker Compose
services:
authelia:
container_name: 'authelia'
image: 'authelia/authelia:latest'
command:
- 'authelia'
- '--config=/config/configuration.yml'
- '--config=/config/configuration.acl.yml'
Kubernetes
пример файла deployment.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: authelia
namespace: authelia
labels:
app.kubernetes.io/instance: authelia
app.kubernetes.io/name: authelia
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/instance: authelia
app.kubernetes.io/name: authelia
template:
metadata:
labels:
app.kubernetes.io/instance: authelia
app.kubernetes.io/name: authelia
spec:
enableServiceLinks: false
containers:
- name: authelia
image: docker.io/authelia/authelia:latest
command:
- authelia
args:
- '--config=/configuration.yml'
- '--config=/configuration.acl.yml'
Файлы фильтров
Существуют файловые фильтры, которые позволяют изменять все конфигурационные файлы после их чтения из файловой системы, но до разбора их содержимого. Если эти фильтры не указаны явно, они НЕ подпадают под действие нашей стандартной политики версионирования.
Наступит момент, когда:
Имя аргумента CLI изменится (мы рекомендуем использовать переменную окружения, которая этого не сделает)
Фильтры настраиваются как список имен фильтров с помощью аргумента CLI –config.experimental.filters и переменной окружения X_AUTHELIA_CONFIG_FILTERS. Мы рекомендуем использовать переменную окружения, так как это гарантирует, что команды, выполняемые из контейнера, используют одни и те же фильтры, и, скорее всего, это постоянное значение, в то время как аргумент может меняться. Если используется и аргумент CLI, и переменная окружения, то переменная окружения полностью игнорируется.
Фильтры могут использоваться самостоятельно, в комбинации или вообще не использоваться. Фильтры обрабатываются в порядке их определения. Вы можете просмотреть вывод YAML-файлов при обработке с помощью фильтров, используя команду authelia config template.
docker run -d authelia/authelia:latest authelia --config /config/configuration.yml --config.experimental.filters template
docker run -d -e X_AUTHELIA_CONFIG_FILTERS=template -e X_AUTHELIA_CONFIG=/config/configuration.yml authelia/authelia:latest authelia
Используются функции шаблонизатора GO
3.2.3 - Переменные Authelia
AUTHELIA_. Все переменные окружения, начинающиеся с этого префикса, должны быть предназначены для конфигурации. Любые переменные окружения, имеющие этот префикс и не предназначенные для конфигурации, скорее всего, приведут к ошибке или, что еще хуже, к неправильной конфигурации.Синтаксис переменных
Переменные окружения должны иметь префикс AUTHELIA_. Все переменные окружения, начинающиеся с этого префикса, должны быть предназначены для конфигурации. Любые переменные окружения, имеющие этот префикс и не предназначенные для конфигурации, скорее всего, приведут к ошибке или, что еще хуже, к неправильной конфигурации.
Mapping
Параметры конфигурации сопоставляются по их имени. Уровни отступа / подклавиши заменяются символами подчеркивания.
log:
level: 'info'
server:
buffers:
read: 4096
или
AUTHELIA_LOG_LEVEL=info
AUTHELIA_SERVER_BUFFERS_READ=4096
Список переменных
| Configuration Key | Environment Variable |
|---|---|
| access_control.default_policy | AUTHELIA_ACCESS_CONTROL_DEFAULT_POLICY |
| authentication_backend.file.password.algorithm | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ALGORITHM |
| authentication_backend.file.password.argon2.iterations | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_ITERATIONS |
| authentication_backend.file.password.argon2.key_length | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_KEY_LENGTH |
| authentication_backend.file.password.argon2.memory | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_MEMORY |
| authentication_backend.file.password.argon2.parallelism | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_PARALLELISM |
| authentication_backend.file.password.argon2.salt_length | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_SALT_LENGTH |
| authentication_backend.file.password.argon2.variant | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_VARIANT |
| authentication_backend.file.password.bcrypt.cost | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_BCRYPT_COST |
| authentication_backend.file.password.bcrypt.variant | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_BCRYPT_VARIANT |
| authentication_backend.file.password.pbkdf2.iterations | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PBKDF2_ITERATIONS |
| authentication_backend.file.password.pbkdf2.salt_length | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PBKDF2_SALT_LENGTH |
| authentication_backend.file.password.pbkdf2.variant | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PBKDF2_VARIANT |
| authentication_backend.file.password.scrypt.block_size | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_BLOCK_SIZE |
| authentication_backend.file.password.scrypt.iterations | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_ITERATIONS |
| authentication_backend.file.password.scrypt.key_length | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_KEY_LENGTH |
| authentication_backend.file.password.scrypt.parallelism | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_PARALLELISM |
| authentication_backend.file.password.scrypt.salt_length | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_SALT_LENGTH |
| authentication_backend.file.password.scrypt.variant | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_VARIANT |
| authentication_backend.file.password.sha2crypt.iterations | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SHA2CRYPT_ITERATIONS |
| authentication_backend.file.password.sha2crypt.salt_length | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SHA2CRYPT_SALT_LENGTH |
| authentication_backend.file.password.sha2crypt.variant | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SHA2CRYPT_VARIANT |
| authentication_backend.file.path | AUTHELIA_AUTHENTICATION_BACKEND_FILE_PATH |
| authentication_backend.file.search.case_insensitive | AUTHELIA_AUTHENTICATION_BACKEND_FILE_SEARCH_CASE_INSENSITIVE |
| authentication_backend.file.search.email | AUTHELIA_AUTHENTICATION_BACKEND_FILE_SEARCH_EMAIL |
| authentication_backend.file.watch | AUTHELIA_AUTHENTICATION_BACKEND_FILE_WATCH |
| authentication_backend.ldap.additional_groups_dn | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ADDITIONAL_GROUPS_DN |
| authentication_backend.ldap.additional_users_dn | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ADDITIONAL_USERS_DN |
| authentication_backend.ldap.address | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ADDRESS |
| authentication_backend.ldap.attributes.birthdate | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_BIRTHDATE |
| authentication_backend.ldap.attributes.country | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_COUNTRY |
| authentication_backend.ldap.attributes.display_name | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_DISPLAY_NAME |
| authentication_backend.ldap.attributes.distinguished_name | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_DISTINGUISHED_NAME |
| authentication_backend.ldap.attributes.family_name | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_FAMILY_NAME |
| authentication_backend.ldap.attributes.gender | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_GENDER |
| authentication_backend.ldap.attributes.given_name | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_GIVEN_NAME |
| authentication_backend.ldap.attributes.group_name | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_GROUP_NAME |
| authentication_backend.ldap.attributes.locale | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_LOCALE |
| authentication_backend.ldap.attributes.locality | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_LOCALITY |
| authentication_backend.ldap.attributes.mail | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_MAIL |
| authentication_backend.ldap.attributes.member_of | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_MEMBER_OF |
| authentication_backend.ldap.attributes.middle_name | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_MIDDLE_NAME |
| authentication_backend.ldap.attributes.nickname | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_NICKNAME |
| authentication_backend.ldap.attributes.phone_extension | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_PHONE_EXTENSION |
| authentication_backend.ldap.attributes.phone_number | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_PHONE_NUMBER |
| authentication_backend.ldap.attributes.picture | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_PICTURE |
| authentication_backend.ldap.attributes.postal_code | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_POSTAL_CODE |
| authentication_backend.ldap.attributes.profile | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_PROFILE |
| authentication_backend.ldap.attributes.region | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_REGION |
| authentication_backend.ldap.attributes.street_address | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_STREET_ADDRESS |
| authentication_backend.ldap.attributes.username | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_USERNAME |
| authentication_backend.ldap.attributes.website | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_WEBSITE |
| authentication_backend.ldap.attributes.zoneinfo | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_ZONEINFO |
| authentication_backend.ldap.base_dn | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_BASE_DN |
| authentication_backend.ldap.group_search_mode | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_GROUP_SEARCH_MODE |
| authentication_backend.ldap.groups_filter | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_GROUPS_FILTER |
| authentication_backend.ldap.implementation | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_IMPLEMENTATION |
| authentication_backend.ldap.permit_feature_detection_failure | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PERMIT_FEATURE_DETECTION_FAILURE |
| authentication_backend.ldap.permit_referrals | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PERMIT_REFERRALS |
| authentication_backend.ldap.permit_unauthenticated_bind | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PERMIT_UNAUTHENTICATED_BIND |
| authentication_backend.ldap.pooling.count | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_POOLING_COUNT |
| authentication_backend.ldap.pooling.enable | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_POOLING_ENABLE |
| authentication_backend.ldap.pooling.retries | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_POOLING_RETRIES |
| authentication_backend.ldap.pooling.timeout | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_POOLING_TIMEOUT |
| authentication_backend.ldap.start_tls | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_START_TLS |
| authentication_backend.ldap.timeout | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TIMEOUT |
| authentication_backend.ldap.tls.maximum_version | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_MAXIMUM_VERSION |
| authentication_backend.ldap.tls.minimum_version | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_MINIMUM_VERSION |
| authentication_backend.ldap.tls.server_name | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_SERVER_NAME |
| authentication_backend.ldap.tls.skip_verify | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_SKIP_VERIFY |
| authentication_backend.ldap.user | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_USER |
| authentication_backend.ldap.users_filter | AUTHELIA_AUTHENTICATION_BACKEND_LDAP_USERS_FILTER |
| authentication_backend.password_change.disable | AUTHELIA_AUTHENTICATION_BACKEND_PASSWORD_CHANGE_DISABLE |
| authentication_backend.password_reset.custom_url | AUTHELIA_AUTHENTICATION_BACKEND_PASSWORD_RESET_CUSTOM_URL |
| authentication_backend.password_reset.disable | AUTHELIA_AUTHENTICATION_BACKEND_PASSWORD_RESET_DISABLE |
| authentication_backend.refresh_interval | AUTHELIA_AUTHENTICATION_BACKEND_REFRESH_INTERVAL |
Identuty
| Configuration Key | Environment Variable |
|---|---|
| certificates_directory | AUTHELIA_CERTIFICATES_DIRECTORY |
| default_2fa_method | AUTHELIA_DEFAULT_2FA_METHOD |
| duo_api.disable | AUTHELIA_DUO_API_DISABLE |
| duo_api.enable_self_enrollment | AUTHELIA_DUO_API_ENABLE_SELF_ENROLLMENT |
| duo_api.hostname | AUTHELIA_DUO_API_HOSTNAME |
| identity_providers.oidc | AUTHELIA_IDENTITY_PROVIDERS_OIDC |
| identity_providers.oidc.cors.allowed_origins_from_client_redirect_uris | AUTHELIA_IDENTITY_PROVIDERS_OIDC_CORS_ALLOWED_ORIGINS_FROM_CLIENT_REDIRECT_URIS |
| identity_providers.oidc.cors.endpoints | AUTHELIA_IDENTITY_PROVIDERS_OIDC_CORS_ENDPOINTS |
| identity_providers.oidc.discovery_signed_response_alg | AUTHELIA_IDENTITY_PROVIDERS_OIDC_DISCOVERY_SIGNED_RESPONSE_ALG |
| identity_providers.oidc.discovery_signed_response_key_id | AUTHELIA_IDENTITY_PROVIDERS_OIDC_DISCOVERY_SIGNED_RESPONSE_KEY_ID |
| identity_providers.oidc.enable_client_debug_messages | AUTHELIA_IDENTITY_PROVIDERS_OIDC_ENABLE_CLIENT_DEBUG_MESSAGES |
| identity_providers.oidc.enable_jwt_access_token_stateless_introspection | AUTHELIA_IDENTITY_PROVIDERS_OIDC_ENABLE_JWT_ACCESS_TOKEN_STATELESS_INTROSPECTION |
| identity_providers.oidc.enable_pkce_plain_challenge | AUTHELIA_IDENTITY_PROVIDERS_OIDC_ENABLE_PKCE_PLAIN_CHALLENGE |
| identity_providers.oidc.enforce_pkce | AUTHELIA_IDENTITY_PROVIDERS_OIDC_ENFORCE_PKCE |
| identity_providers.oidc.lifespans.access_token | AUTHELIA_IDENTITY_PROVIDERS_OIDC_LIFESPANS_ACCESS_TOKEN |
| identity_providers.oidc.lifespans.authorize_code | AUTHELIA_IDENTITY_PROVIDERS_OIDC_LIFESPANS_AUTHORIZE_CODE |
| identity_providers.oidc.lifespans.device_code | AUTHELIA_IDENTITY_PROVIDERS_OIDC_LIFESPANS_DEVICE_CODE |
| identity_providers.oidc.lifespans.id_token | AUTHELIA_IDENTITY_PROVIDERS_OIDC_LIFESPANS_ID_TOKEN |
| identity_providers.oidc.lifespans.jwt_secured_authorization | AUTHELIA_IDENTITY_PROVIDERS_OIDC_LIFESPANS_JWT_SECURED_AUTHORIZATION |
| identity_providers.oidc.lifespans.refresh_token | AUTHELIA_IDENTITY_PROVIDERS_OIDC_LIFESPANS_REFRESH_TOKEN |
| identity_providers.oidc.minimum_parameter_entropy | AUTHELIA_IDENTITY_PROVIDERS_OIDC_MINIMUM_PARAMETER_ENTROPY |
| identity_providers.oidc.require_pushed_authorization_requests | AUTHELIA_IDENTITY_PROVIDERS_OIDC_REQUIRE_PUSHED_AUTHORIZATION_REQUESTS |
| identity_validation.elevated_session.characters | AUTHELIA_IDENTITY_VALIDATION_ELEVATED_SESSION_CHARACTERS |
| identity_validation.elevated_session.code_lifespan | AUTHELIA_IDENTITY_VALIDATION_ELEVATED_SESSION_CODE_LIFESPAN |
| identity_validation.elevated_session.elevation_lifespan | AUTHELIA_IDENTITY_VALIDATION_ELEVATED_SESSION_ELEVATION_LIFESPAN |
| identity_validation.elevated_session.require_second_factor | AUTHELIA_IDENTITY_VALIDATION_ELEVATED_SESSION_REQUIRE_SECOND_FACTOR |
| identity_validation.elevated_session.skip_second_factor | AUTHELIA_IDENTITY_VALIDATION_ELEVATED_SESSION_SKIP_SECOND_FACTOR |
| identity_validation.reset_password.jwt_algorithm | AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_ALGORITHM |
| identity_validation.reset_password.jwt_lifespan | AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_LIFESPAN |
log
| Configuration Key | Environment Variable |
|---|---|
| log.file_path | AUTHELIA_LOG_FILE_PATH |
| log.format | AUTHELIA_LOG_FORMAT |
| log.keep_stdout | AUTHELIA_LOG_KEEP_STDOUT |
| log.level | AUTHELIA_LOG_LEVEL |
| notifier.disable_startup_check | AUTHELIA_NOTIFIER_DISABLE_STARTUP_CHECK |
| notifier.filesystem.filename | AUTHELIA_NOTIFIER_FILESYSTEM_FILENAME |
| notifier.smtp.address | AUTHELIA_NOTIFIER_SMTP_ADDRESS |
| notifier.smtp.disable_html_emails | AUTHELIA_NOTIFIER_SMTP_DISABLE_HTML_EMAILS |
| notifier.smtp.disable_require_tls | AUTHELIA_NOTIFIER_SMTP_DISABLE_REQUIRE_TLS |
| notifier.smtp.disable_starttls | AUTHELIA_NOTIFIER_SMTP_DISABLE_STARTTLS |
| notifier.smtp.identifier | AUTHELIA_NOTIFIER_SMTP_IDENTIFIER |
| notifier.smtp.sender | AUTHELIA_NOTIFIER_SMTP_SENDER |
| notifier.smtp.startup_check_address | AUTHELIA_NOTIFIER_SMTP_STARTUP_CHECK_ADDRESS |
| notifier.smtp.subject | AUTHELIA_NOTIFIER_SMTP_SUBJECT |
| notifier.smtp.timeout | AUTHELIA_NOTIFIER_SMTP_TIMEOUT |
| notifier.smtp.tls.maximum_version | AUTHELIA_NOTIFIER_SMTP_TLS_MAXIMUM_VERSION |
| notifier.smtp.tls.minimum_version | AUTHELIA_NOTIFIER_SMTP_TLS_MINIMUM_VERSION |
| notifier.smtp.tls.server_name | AUTHELIA_NOTIFIER_SMTP_TLS_SERVER_NAME |
| notifier.smtp.tls.skip_verify | AUTHELIA_NOTIFIER_SMTP_TLS_SKIP_VERIFY |
| notifier.smtp.username | AUTHELIA_NOTIFIER_SMTP_USERNAME |
| notifier.template_path | AUTHELIA_NOTIFIER_TEMPLATE_PATH |
| ntp.address | AUTHELIA_NTP_ADDRESS |
| ntp.disable_failure | AUTHELIA_NTP_DISABLE_FAILURE |
| ntp.disable_startup_check | AUTHELIA_NTP_DISABLE_STARTUP_CHECK |
| ntp.max_desync | AUTHELIA_NTP_MAX_DESYNC |
| ntp.version | AUTHELIA_NTP_VERSION |
| password_policy.standard.enabled | AUTHELIA_PASSWORD_POLICY_STANDARD_ENABLED |
| password_policy.standard.max_length | AUTHELIA_PASSWORD_POLICY_STANDARD_MAX_LENGTH |
| password_policy.standard.min_length | AUTHELIA_PASSWORD_POLICY_STANDARD_MIN_LENGTH |
| password_policy.standard.require_lowercase | AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_LOWERCASE |
| password_policy.standard.require_number | AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_NUMBER |
| password_policy.standard.require_special | AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_SPECIAL |
| password_policy.standard.require_uppercase | AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_UPPERCASE |
| password_policy.zxcvbn.enabled | AUTHELIA_PASSWORD_POLICY_ZXCVBN_ENABLED |
| password_policy.zxcvbn.min_score | AUTHELIA_PASSWORD_POLICY_ZXCVBN_MIN_SCORE |
privacy
| Configuration Key | Environment Variable |
|---|---|
| privacy_policy.enabled | AUTHELIA_PRIVACY_POLICY_ENABLED |
| privacy_policy.policy_url | AUTHELIA_PRIVACY_POLICY_POLICY_URL |
| privacy_policy.require_user_acceptance | AUTHELIA_PRIVACY_POLICY_REQUIRE_USER_ACCEPTANCE |
| regulation.ban_time | AUTHELIA_REGULATION_BAN_TIME |
| regulation.find_time | AUTHELIA_REGULATION_FIND_TIME |
| regulation.max_retries | AUTHELIA_REGULATION_MAX_RETRIES |
| regulation.modes | AUTHELIA_REGULATION_MODES |
| server.address | AUTHELIA_SERVER_ADDRESS |
| server.asset_path | AUTHELIA_SERVER_ASSET_PATH |
| server.buffers.read | AUTHELIA_SERVER_BUFFERS_READ |
| server.buffers.write | AUTHELIA_SERVER_BUFFERS_WRITE |
| server.disable_healthcheck | AUTHELIA_SERVER_DISABLE_HEALTHCHECK |
| server.endpoints.enable_expvars | AUTHELIA_SERVER_ENDPOINTS_ENABLE_EXPVARS |
| server.endpoints.enable_pprof | AUTHELIA_SERVER_ENDPOINTS_ENABLE_PPROF |
| server.endpoints.rate_limits.reset_password_finish.enable | AUTHELIA_SERVER_ENDPOINTS_RATE_LIMITS_RESET_PASSWORD_FINISH_ENABLE |
| server.endpoints.rate_limits.reset_password_start.enable | AUTHELIA_SERVER_ENDPOINTS_RATE_LIMITS_RESET_PASSWORD_START_ENABLE |
| server.endpoints.rate_limits.second_factor_duo.enable | AUTHELIA_SERVER_ENDPOINTS_RATE_LIMITS_SECOND_FACTOR_DUO_ENABLE |
| server.endpoints.rate_limits.second_factor_totp.enable | AUTHELIA_SERVER_ENDPOINTS_RATE_LIMITS_SECOND_FACTOR_TOTP_ENABLE |
| server.endpoints.rate_limits.session_elevation_finish.enable | AUTHELIA_SERVER_ENDPOINTS_RATE_LIMITS_SESSION_ELEVATION_FINISH_ENABLE |
| server.endpoints.rate_limits.session_elevation_start.enable | AUTHELIA_SERVER_ENDPOINTS_RATE_LIMITS_SESSION_ELEVATION_START_ENABLE |
| server.headers.csp_template | AUTHELIA_SERVER_HEADERS_CSP_TEMPLATE |
| server.timeouts.idle | AUTHELIA_SERVER_TIMEOUTS_IDLE |
| server.timeouts.read | AUTHELIA_SERVER_TIMEOUTS_READ |
| server.timeouts.write | AUTHELIA_SERVER_TIMEOUTS_WRITE |
| server.tls.certificate | AUTHELIA_SERVER_TLS_CERTIFICATE |
| server.tls.client_certificates | AUTHELIA_SERVER_TLS_CLIENT_CERTIFICATES |
| server.tls.key | AUTHELIA_SERVER_TLS_KEY |
| session | AUTHELIA_SESSION |
| session.expiration | AUTHELIA_SESSION_EXPIRATION |
| session.inactivity | AUTHELIA_SESSION_INACTIVITY |
| session.name | AUTHELIA_SESSION_NAME |
| session.redis.database_index | AUTHELIA_SESSION_REDIS_DATABASE_INDEX |
| session.redis.high_availability.route_by_latency | AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_ROUTE_BY_LATENCY |
| session.redis.high_availability.route_randomly | AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_ROUTE_RANDOMLY |
| session.redis.high_availability.sentinel_name | AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_SENTINEL_NAME |
| session.redis.high_availability.sentinel_username | AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_SENTINEL_USERNAME |
| session.redis.host | AUTHELIA_SESSION_REDIS_HOST |
| session.redis.max_retries | AUTHELIA_SESSION_REDIS_MAX_RETRIES |
| session.redis.maximum_active_connections | AUTHELIA_SESSION_REDIS_MAXIMUM_ACTIVE_CONNECTIONS |
| session.redis.minimum_idle_connections | AUTHELIA_SESSION_REDIS_MINIMUM_IDLE_CONNECTIONS |
| session.redis.port | AUTHELIA_SESSION_REDIS_PORT |
| session.redis.timeout | AUTHELIA_SESSION_REDIS_TIMEOUT |
| session.redis.tls.maximum_version | AUTHELIA_SESSION_REDIS_TLS_MAXIMUM_VERSION |
| session.redis.tls.minimum_version | AUTHELIA_SESSION_REDIS_TLS_MINIMUM_VERSION |
| session.redis.tls.server_name | AUTHELIA_SESSION_REDIS_TLS_SERVER_NAME |
| session.redis.tls.skip_verify | AUTHELIA_SESSION_REDIS_TLS_SKIP_VERIFY |
| session.redis.username | AUTHELIA_SESSION_REDIS_USERNAME |
| session.remember_me | AUTHELIA_SESSION_REMEMBER_ME |
| session.same_site | AUTHELIA_SESSION_SAME_SITE |
storage
| Configuration Key | Environment Variable |
|---|---|
| storage.local.path | AUTHELIA_STORAGE_LOCAL_PATH |
| storage.mysql.address | AUTHELIA_STORAGE_MYSQL_ADDRESS |
| storage.mysql.database | AUTHELIA_STORAGE_MYSQL_DATABASE |
| storage.mysql.timeout | AUTHELIA_STORAGE_MYSQL_TIMEOUT |
| storage.mysql.tls.maximum_version | AUTHELIA_STORAGE_MYSQL_TLS_MAXIMUM_VERSION |
| storage.mysql.tls.minimum_version | AUTHELIA_STORAGE_MYSQL_TLS_MINIMUM_VERSION |
| storage.mysql.tls.server_name | AUTHELIA_STORAGE_MYSQL_TLS_SERVER_NAME |
| storage.mysql.tls.skip_verify | AUTHELIA_STORAGE_MYSQL_TLS_SKIP_VERIFY |
| storage.mysql.username | AUTHELIA_STORAGE_MYSQL_USERNAME |
| storage.postgres.address | AUTHELIA_STORAGE_POSTGRES_ADDRESS |
| storage.postgres.database | AUTHELIA_STORAGE_POSTGRES_DATABASE |
| storage.postgres.schema | AUTHELIA_STORAGE_POSTGRES_SCHEMA |
| storage.postgres.timeout | AUTHELIA_STORAGE_POSTGRES_TIMEOUT |
| storage.postgres.tls.maximum_version | AUTHELIA_STORAGE_POSTGRES_TLS_MAXIMUM_VERSION |
| storage.postgres.tls.minimum_version | AUTHELIA_STORAGE_POSTGRES_TLS_MINIMUM_VERSION |
| storage.postgres.tls.server_name | AUTHELIA_STORAGE_POSTGRES_TLS_SERVER_NAME |
| storage.postgres.tls.skip_verify | AUTHELIA_STORAGE_POSTGRES_TLS_SKIP_VERIFY |
| storage.postgres.username | AUTHELIA_STORAGE_POSTGRES_USERNAME |
| telemetry.metrics.address | AUTHELIA_TELEMETRY_METRICS_ADDRESS |
| telemetry.metrics.buffers.read | AUTHELIA_TELEMETRY_METRICS_BUFFERS_READ |
| telemetry.metrics.buffers.write | AUTHELIA_TELEMETRY_METRICS_BUFFERS_WRITE |
| telemetry.metrics.enabled | AUTHELIA_TELEMETRY_METRICS_ENABLED |
| telemetry.metrics.timeouts.idle | AUTHELIA_TELEMETRY_METRICS_TIMEOUTS_IDLE |
| telemetry.metrics.timeouts.read | AUTHELIA_TELEMETRY_METRICS_TIMEOUTS_READ |
| telemetry.metrics.timeouts.write | AUTHELIA_TELEMETRY_METRICS_TIMEOUTS_WRITE |
| theme | AUTHELIA_THEME |
| totp.algorithm | AUTHELIA_TOTP_ALGORITHM |
| totp.allowed_algorithms | AUTHELIA_TOTP_ALLOWED_ALGORITHMS |
| totp.allowed_digits | AUTHELIA_TOTP_ALLOWED_DIGITS |
| totp.allowed_periods | AUTHELIA_TOTP_ALLOWED_PERIODS |
| totp.digits | AUTHELIA_TOTP_DIGITS |
| totp.disable | AUTHELIA_TOTP_DISABLE |
| totp.disable_reuse_security_policy | AUTHELIA_TOTP_DISABLE_REUSE_SECURITY_POLICY |
| totp.issuer | AUTHELIA_TOTP_ISSUER |
| totp.period | AUTHELIA_TOTP_PERIOD |
| totp.secret_size | AUTHELIA_TOTP_SECRET_SIZE |
| totp.skew | AUTHELIA_TOTP_SKEW |
| webauthn.attestation_conveyance_preference | AUTHELIA_WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE |
| webauthn.disable | AUTHELIA_WEBAUTHN_DISABLE |
| webauthn.display_name | AUTHELIA_WEBAUTHN_DISPLAY_NAME |
| webauthn.enable_passkey_login | AUTHELIA_WEBAUTHN_ENABLE_PASSKEY_LOGIN |
| webauthn.experimental_enable_passkey_upgrade | AUTHELIA_WEBAUTHN_EXPERIMENTAL_ENABLE_PASSKEY_UPGRADE |
| webauthn.experimental_enable_passkey_uv_two_factors | AUTHELIA_WEBAUTHN_EXPERIMENTAL_ENABLE_PASSKEY_UV_TWO_FACTORS |
| webauthn.filtering.prohibit_backup_eligibility | AUTHELIA_WEBAUTHN_FILTERING_PROHIBIT_BACKUP_ELIGIBILITY |
| webauthn.metadata.enabled | AUTHELIA_WEBAUTHN_METADATA_ENABLED |
| webauthn.metadata.validate_entry | AUTHELIA_WEBAUTHN_METADATA_VALIDATE_ENTRY |
| webauthn.metadata.validate_entry_permit_zero_aaguid | AUTHELIA_WEBAUTHN_METADATA_VALIDATE_ENTRY_PERMIT_ZERO_AAGUID |
| webauthn.metadata.validate_status | AUTHELIA_WEBAUTHN_METADATA_VALIDATE_STATUS |
| webauthn.metadata.validate_status_permitted | AUTHELIA_WEBAUTHN_METADATA_VALIDATE_STATUS_PERMITTED |
| webauthn.metadata.validate_status_prohibited | AUTHELIA_WEBAUTHN_METADATA_VALIDATE_STATUS_PROHIBITED |
| webauthn.metadata.validate_trust_anchor | AUTHELIA_WEBAUTHN_METADATA_VALIDATE_TRUST_ANCHOR |
| webauthn.selection_criteria.attachment | AUTHELIA_WEBAUTHN_SELECTION_CRITERIA_ATTACHMENT |
| webauthn.selection_criteria.discoverability | AUTHELIA_WEBAUTHN_SELECTION_CRITERIA_DISCOVERABILITY |
| webauthn.selection_criteria.user_verification | AUTHELIA_WEBAUTHN_SELECTION_CRITERIA_USER_VERIFICATION |
| webauthn.timeout | AUTHELIA_WEBAUTHN_TIMEOUT |
3.3 - Однофакторная аутентификация
Существует два способа интеграции Authelia с бэкэндом аутентификации:
- LDAP: пользователи хранятся на удаленных серверах, таких как OpenLDAP, OpenDJ, FreeIPA или Microsoft Active Directory.
- Файл: пользователи хранятся в YAML-файле с хэшированной версией пароля.
3.3.1 - Однофакторная аутентификация
Конфигурация аутентификации
authentication_backend:
refresh_interval: '5m'
password_reset:
disable: false
custom_url: ''
password_change:
disable: false
refresh_interval
Этот параметр управляет интервалом, через который обновляются данные из бэкэнда. В порядке важности обновляются такие данные, как группы, адрес электронной почты и отображаемое имя. Это особенно полезно для файлового провайдера, когда часы включены или вообще включены в LDAP-провайдере.
В дополнение к значениям длительности этот параметр принимает значения always и disable; при этом always будет всегда обновлять это значение, а disable - никогда не обновлять профиль.
password_reset
disable
Этот параметр определяет, могут ли пользователи сбрасывать свой пароль через веб-фронтенд или нет.
custom_url
Пользовательский URL-адрес сброса пароля. Он заменяет встроенную функцию сброса пароля и отключает конечные точки, если он настроен на что-либо, кроме “ничего” или пустой строки.
password_change
disable
Этот параметр определяет, могут ли пользователи изменять свой пароль через веб-фронтенд или нет.
file
Поставщик аутентификации файлов.
ldap
Поставщик аутентификации LDAP.
3.3.2 - LDAP
Настройка LDAP
configuration.yml
authentication_backend:
ldap:
address: 'ldap://127.0.0.1'
implementation: 'custom'
timeout: '5s'
start_tls: false
tls:
server_name: 'ldap.rabrain.ru'
skip_verify: false
minimum_version: 'TLS1.2'
maximum_version: 'TLS1.3'
certificate_chain: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
private_key: |
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
pooling:
enable: false
count: 5
retries: 2
timeout: '10 seconds'
base_dn: 'DC=rabrain,DC=ru'
additional_users_dn: 'OU=users'
users_filter: '(&({username_attribute}={input})(objectClass=person))'
additional_groups_dn: 'OU=groups'
groups_filter: '(&(member={dn})(objectClass=groupOfNames))'
group_search_mode: 'filter'
permit_referrals: false
permit_unauthenticated_bind: false
permit_feature_detection_failure: false
user: 'CN=admin,DC=rabrain,DC=ru'
password: 'password'
attributes:
distinguished_name: 'distinguishedName'
username: 'uid'
display_name: 'displayName'
family_name: 'sn'
given_name: 'givenName'
middle_name: 'middleName'
nickname: ''
gender: ''
birthdate: ''
website: 'wWWHomePage'
profile: ''
picture: ''
zoneinfo: ''
locale: ''
phone_number: 'telephoneNumber'
phone_extension: ''
street_address: 'streetAddress'
locality: 'l'
region: 'st'
postal_code: 'postalCode'
country: 'c'
mail: 'mail'
member_of: 'memberOf'
group_name: 'cn'
extra:
extra_example:
name: ''
multi_valued: false
value_type: 'string'
Описание настроек
address
URL-адрес LDAP, состоящий из схемы, имени хоста и порта. Формат - [<схема>://]<имя хоста>[:<порт>]. По умолчанию используется схема ldapi, если путь абсолютный, иначе - ldaps, а допустимыми схемами являются ldap, ldaps или ldapi (сокет домена unix).
Если схема ldapi, то за ней должен следовать абсолютный путь к существующему сокету домена unix, для доступа к которому у пользователя/группы, от имени которой запущен процесс Authelia, есть соответствующие разрешения. Например, если сокет расположен по адресу /var/run/slapd.sock, то адрес должен быть ldapi:///var/run/slapd.sock.
authentication_backend:
ldap:
address: 'ldaps://dc1.rabrain.ru'
или
authentication_backend:
ldap:
address: 'ldap://[fd00:1111:2222:3333::1]'
implementation
Настраивает реализацию LDAP, используемую Authelia.
timeout
Тайм-аут для набора номера при подключении к LDAP.
start_tls
Включает использование процесса LDAP StartTLS, который не часто используется. Настраивать его следует только в том случае, если вы знаете, что он вам нужен. Первоначальное соединение будет осуществляться через обычный текст, и Authelia попытается обновить его с помощью LDAP-сервера. URL-адреса LDAPS немного более безопасны.
tls
Если эта опция определена, она управляет параметрами проверки TLS-соединений для LDAP-сервера.
По умолчанию Authelia использует системный сертификат доверия для проверки TLS-сертификатов TLS-соединений, а глобальная опция certificates_directory может быть использована для дополнения этого параметра.
pooling
enable
Включает функцию объединения соединений.
count
Количество открытых соединений, которые должны быть доступны в пуле в любой момент времени.
retries
Количество попыток получить свободное соединение, предпринятых в течение периода таймаута. Это эффективно разбивает таймаут на части.
timeout
Время, в течение которого мы ждем, пока соединение освободится в пуле, прежде чем сдаться и выдать ошибку.
base_dn
Устанавливает базовый контейнер отличительных имен для всех LDAP-запросов. Если ваш LDAP-домен rabrain.ru, то обычно это DC=rabrain,DC=ru, однако вы можете настроить его более точно, например, чтобы включить только объекты внутри OU authelia: OU=authelia,DC=rabrain,DC=ru. К этому приставке добавляется additional_users_dn для поиска пользователей и additional_groups_dn для поиска групп.
users_filter
Фильтр LDAP, позволяющий сузить круг пользователей. Это важно установить правильно, чтобы исключить пользователей с ограниченными возможностями.
additional_groups_dn
Аналогично additional_users_dn, но применяется к групповому поиску.
groups_filter
Аналогичен фильтру users_filter, но применяется к поиску по группам. Чтобы включить в поиск группы, в которых участник не является непосредственным членом, но является членом другой группы, которая является членом этих групп (т. е. рекурсивные группы)
(&(member:1.2.840.113556.1.4.1941:={dn})(objectClass=group)(objectCategory=group))
permit_referrals
Разрешает следовать за рефералами. Это полезно, если в вашей архитектуре есть серверы, доступные только для чтения, и поэтому требуется, чтобы при выполнении операций записи ссылки выполнялись.
user
Отличительное имя пользователя в паре с паролем для привязки к операциям поиска и смены пароля.
password
Пароль, связанный с пользователем, используемый для привязки к LDAP-серверу для операций поиска и смены пароля.
attributes
Следующие параметры настраивают сопоставление атрибутов сервера каталогов.
distinguished_name
Атрибут сервера каталогов, содержащий отличительное имя, в основном используется для выполнения фильтрованного поиска. Существует четкое различие между реальным отличительным именем и атрибутом отличительного имени, все каталоги имеют отличительные имена для объектов, но не все имеют атрибут, представляющий это имя, по которому можно осуществлять поиск.
Единственная известная поддержка на данный момент - это Active Directory.
user name
Атрибут сервера каталогов, который сопоставляется с именем пользователя в Authelia. Он должен содержать заполнитель {username_attribute}.
display_name
Атрибут сервера каталогов для извлечения, который отображается в веб-интерфейсе для пользователя при входе в систему.
family_name given_name middle_name nickname
Атрибут сервера каталогов, содержащий фамилию, имя, ник, пользователя.
extra
Дополнительные атрибуты для загрузки с сервера каталогов. Эти дополнительные атрибуты могут использоваться в других областях Authelia, таких как OpenID Connect 1.0.
Ключ представляет собой имя атрибута бэкэнда и по умолчанию является именем атрибута в Authelia.
В приведенном ниже примере мы загружаем атрибут сервера каталогов exampleServerAttribute в атрибут Authelia example_authelia_attribute, рассматривая его как однозначный атрибут, имеющий базовый тип integer.
authentication_backend:
ldap:
attributes:
extra:
exampleServerAttribute:
name: 'example_authelia_attribute'
multi_valued: false
value_type: 'integer'
Refresh Interval
Рекомендуется использовать интервал обновления по умолчанию или настроить его на достаточно низкое значение, чтобы обновлять группы пользователей и их статус (удалены, отключены и т. д.) для адекватной защиты вашей среды.
3.3.3 - Файлы конфигурации
Файл конфигурации configuration.yml
authentication_backend:
file:
path: '/config/users.yml'
watch: false
search:
email: false
case_insensitive: false
extra_attributes:
extra_example:
multi_valued: false
value_type: 'string'
password:
algorithm: 'argon2'
argon2:
variant: 'argon2id'
iterations: 3
memory: 65536
parallelism: 4
key_length: 32
salt_length: 16
scrypt:
variant: 'scrypt'
iterations: 16
block_size: 8
parallelism: 1
key_length: 32
salt_length: 16
pbkdf2:
variant: 'sha512'
iterations: 310000
salt_length: 16
sha2crypt:
variant: 'sha512'
iterations: 50000
salt_length: 16
bcrypt:
variant: 'standard'
cost: 12
Опции
path
Путь к файлу со списком сведений о пользователе. Поддерживаются типы файлов: YAML-файл
watch
Позволяет перезагрузить базу данных, наблюдая за ее изменениями.
search
Функциональные возможности поиска по имени пользователя.
Позволяет пользователям входить в систему, используя свой адрес электронной почты. Если эта функция включена, два пользователя не должны иметь одинаковые адреса электронной почты, а их имена пользователей не должны быть адресами электронной почты.
extra_attributes
Дополнительные атрибуты для загрузки с сервера каталогов.
Ключ представляет собой имя атрибута бэкэнда. База данных будет проверена с учетом конфигурации multi_valued и value_type.
В приведенном ниже примере мы загружаем атрибут сервера каталогов example_file_attribute в атрибут Authelia example_file_attribute, рассматривая его как однозначный атрибут, имеющий базовый тип integer.
authentication_backend:
file:
extra_attributes:
example_file_attribute:
multi_valued: false
value_type: 'integer'
Password Options
algorithm
Управляет алгоритмом хэширования, используемым для хэширования новых паролей. Значение должно быть одним из:
argon2 для алгоритма Argon2
scrypt для алгоритма Scrypt
pbkdf2 для алгоритма PBKDF2
sha2crypt для алгоритма SHA2Crypt
bcrypt для алгоритма Bcrypt.
argon2
Реализация алгоритма Argon2. Это один из единственных алгоритмов, который был разработан исключительно для хеширования паролей, и впоследствии является одним из лучших алгоритмов для обеспечения безопасности на сегодняшний день.
scrypt
Реализация алгоритма Scrypt.
pbkdf2
Реализация алгоритма PBKDF2.
sha2crypt
Реализация алгоритма SHA2 Crypt.
bcrypt
Реализация алгоритма Bcrypt.
3.4 - Двухфакторная аутентификация
Одноразовый пароль
Authelia поддерживает настройку одноразовых паролей, основанных на времени.
Ключ безопасности
Authelia поддерживает настройку ключей безопасности WebAuthn.
Mobile Push
Authelia поддерживает настройку Duo для предоставления мобильного push-сервиса.
3.4.1 - Мобильные устройства
Файл конфигурации configuration.yml
duo_api:
disable: false
hostname: 'api-123456789.rabrain.ru'
integration_key: 'ABCDEF'
secret_key: '1234567890abcdefghifjkl'
enable_self_enrollment: false
Опции
Disable
Отключает Duo. Если имена хостов, integration_key и secret_key являются пустыми строками или не определены, это значение автоматически становится истинным.
hostname
Имя хоста API Duo. Он указывается на панели управления Duo.
integration_key
Не секретный ключ интеграции Duo. Аналогичен идентификатору клиента. Он указывается на панели управления Duo.
secret_key
Секретный ключ Duo, используемый для проверки подлинности вашего приложения. Он предоставляется на панели управления Duo.
enable_self_enrollment
Позволяет самостоятельно регистрировать устройства Duo на портале Authelia.
3.4.2 - Time-based One-Time Password
Файл конфигурации configuration.yml
totp:
disable: false
issuer: 'authelia.com'
algorithm: 'sha1'
digits: 6
period: 30
skew: 1
secret_size: 32
allowed_algorithms:
- 'SHA1'
allowed_digits:
- 6
allowed_periods:
- 30
disable_reuse_security_policy: false
Опции
Disable
Это отключает одноразовый пароль (TOTP), если установлено значение true.
issuer
Приложения, генерирующие одноразовые пароли, основанные на времени, обычно отображают эмитента, чтобы отличить приложения, зарегистрированные пользователем.
Authelia позволяет настраивать эмитента, чтобы отличить запись, созданную Authelia, от других.
algorithm
Алгоритм, используемый для ключа TOTP.
Возможные значения:
- sha1
- sha256
- sha512
Изменение этого значения влияет только на вновь зарегистрированные ключи TOTP.
digits
Количество цифр, которые пользователь должен ввести для аутентификации. Обычно не рекомендуется изменять этот параметр, поскольку многие TOTP-приложения не поддерживают ничего, кроме 6. Хуже того, некоторые TOTP-приложения позволяют добавить ключ, но не используют правильное количество цифр, указанное в ключе.
Правильные значения - 6 или 8.
period
Период времени в секундах между поворотами клавиш или временной элемент TOTP.
Рекомендуется держать это значение равным 30, минимальное значение - 15.
skew
Количество временных одноразовых паролей по обе стороны от текущего действующего временного одноразового пароля, которые также должны считаться действительными. Значение по умолчанию 1 приводит к 3 действительным одноразовым паролям на основе времени. При значении 2 их будет 5.
secret_size
Длина в байтах генерируемых общих секретов. Минимальное значение - 20 (или 160 бит), а по умолчанию - 32 (или 256 бит).
allowed_algorithms
Аналогичен алгоритму с теми же ограничениями, за исключением того, что эта опция позволяет пользователям выбирать из этого списка. Этот список всегда будет содержать значение, заданное в опции алгоритма.
disable_reuse_security_policy
Отключает политику, которая предотвращает повторное использование кодов одноразовых паролей, основанных на времени. Это дополнительная мера безопасности, которая предотвращает повторное воспроизведение кодов. Это касается только тех кодов, которые используются в течение срока действия более одного раза.
Регистрация
Когда пользователи впервые регистрируют свое устройство TOTP, текущий эмитент, алгоритм и период используются для генерации ссылки TOTP и QR-кода. Эти значения сохраняются в базе данных для последующих проверок.
Входная валидация
Параметры конфигурации периода и перекоса влияют друг на друга. По умолчанию период равен 30, а перекос - 1.
3.4.3 - WebAuthn
Файл конфигурации configuration.yml
webauthn:
disable: false
enable_passkey_login: false
display_name: 'Authelia'
attestation_conveyance_preference: 'indirect'
timeout: '60 seconds'
filtering:
permitted_aaguids: []
prohibited_aaguids: []
prohibit_backup_eligibility: false
selection_criteria:
attachment: ''
discoverability: 'preferred'
user_verification: 'preferred'
metadata:
enabled: false
validate_trust_anchor: true
validate_entry: true
validate_entry_permit_zero_aaguid: false
validate_status: true
validate_status_permitted: []
validate_status_prohibited:
- 'REVOKED'
- 'USER_KEY_PHYSICAL_COMPROMISE'
- 'USER_KEY_REMOTE_COMPROMISE'
- 'USER_VERIFICATION_BYPASS'
- 'ATTESTATION_KEY_COMPROMISE'
Опции
Disable
Это отключает WebAuthn, если установлено значение true.
enable_passkey_login
Позволяет входить в систему с помощью Passkey вместо имени пользователя и пароля. Такой вход считается только однофакторным. По умолчанию пользователю будет предложено ввести пароль, если запрос требует многофакторной аутентификации.
display_name
Устанавливает отображаемое имя, которое отправляется клиенту для отображения. Отдельные браузеры и, возможно, отдельные операционные системы сами решают, отображать ли эту информацию и каким образом.
Дополнительную информацию см. в документации W3C WebAuthn.
timeout
Это настраивает запрошенное время ожидания для взаимодействия с WebAuthn.
filtering
В этом разделе настраиваются различные параметры фильтрации при регистрации.
selection_criteria
Параметры критериев выбора задают предпочтения для выбора подходящего аутентификатора.
metadata
Настраивает службу метаданных, которая используется для проверки подлинности аутентификаторов.
3.5 - Security
Security в Authelia относится к механизмам защиты, которые обеспечивают безопасную аутентификацию и авторизацию пользователей. Authelia — это менеджер аутентификации и авторизации с открытым исходным кодом, который можно интегрировать с обратными прокси (Nginx, Traefik) для защиты веб-приложений
3.5.1 - Контроль доступа
Файл конфигурации configuration.yml
access_control:
default_policy: 'deny'
rules:
- domain: 'private.rabrain.ru'
domain_regex: '^(\d+\-)?priv-img\.rabrain\.ru$'
policy: 'one_factor'
networks:
- 'internal'
- '1.1.1.1'
subject:
- ['user:adam']
- ['user:fred']
- ['group:admins']
methods:
- 'GET'
- 'HEAD'
resources:
- '^/api.*'
query:
- - operator: 'present'
key: 'secure'
- operator: 'absent'
key: 'insecure'
- - operator: 'pattern'
key: 'token'
value: '^(abc123|zyx789)$'
- operator: 'not pattern'
key: 'random'
value: '^(1|2)$'
Опции
default_policy
Политика по умолчанию определяет политику, применяемую, если к информации, известной о запросе, не применяется ни один раздел правил. По соображениям безопасности рекомендуется настраивать это значение на отказ. Сайты, которые вы не хотите защищать с помощью Authelia, не должны быть настроены в вашем обратном прокси на выполнение аутентификации с помощью Authelia по соображениям производительности.
rules
Правила имеют множество параметров настройки. Правило совпадает, если все критерии правила соответствуют запросу, за исключением политики, которая применяется к запросу.
Правило определяет две основные вещи:
- политика, применяемая при совпадении всех критериев
- критерии соответствия запроса, представленного обратному прокси
Критерии разбиты на несколько частей:
- domain: домен или список доменов, на которые направлен запрос.
- domain_regex: regex-форма домена.
- resources: шаблон или список шаблонов, которым должен соответствовать путь.
- subject: пользователь или группа пользователей, для которых нужно определить политику.
- networks: сетевые адреса, диапазоны (нотация CIDR) или группы, из которых исходит запрос.
- methods: http-методы, используемые в запросе.
Правило выполняется, если все критерии правила совпадают. Правила оцениваются в последовательном порядке в соответствии с концепцией 1 сопоставления правил.
domain
Требуется: Этот критерий и/или критерий domain_regex являются обязательными.
Этот критерий соответствует имени домена и имеет два способа настройки: в виде одной строки или в виде списка строк. Если это список строк, правило будет соответствовать любому из доменов в списке, совпадающему с доменом запроса. При использовании в сочетании с domain_regex правило будет соответствовать критериям domain или domain_regex.
access_control:
rules:
- domain: '*.rabrain.ru'
policy: 'bypass'
- domain:
- '*.rabrain.ru'
policy: 'bypass'
access_control:
rules:
- domain: ['apple.rabrain.ru', 'banana.rabrain.ru']
policy: 'bypass'
- domain:
- 'apple.rabrain.ru'
- 'banana.rabrain.ru'
policy: 'bypass'
access_control:
rules:
- domain: 'apple.rabrain.ru'
domain_regex: '^(pub|img)-data\.rabrain\.ru$'
policy: bypass
domain_regex
Требуется: Этот критерий и/или критерий домена являются обязательными.
Этот критерий соответствует имени домена и имеет два способа настройки: в виде одной строки или в виде списка строк. Если это список строк, правило будет соответствовать, когда любой из доменов в списке совпадает с доменом запроса. При использовании в сочетании с domain правило будет соответствовать либо критерию domain, либо критерию domain_regex.
access_control:
rules:
- domain_regex:
- '^user-(?P<User>\w+)\.rabrain\.ru$'
- '^group-(?P<Group>\w+)\.rabrain\.ru$'
policy: 'one_factor'
access_control:
rules:
- domain: 'protected.rabrain.ru'
- domain_regex: '^(img|data)-private\.rabrain\.ru'
policy: 'one_factor'
policy
Конкретная политика, которую следует применить к выбранному правилу. Это не критерии для совпадения, это действие, которое нужно предпринять при совпадении.
subject
Этот критерий соответствует идентифицирующим характеристикам субъекта. В настоящее время это либо пользователь, либо группы, к которым он принадлежит. Это позволяет эффективно контролировать, к чему именно имеет доступ каждый пользователь, или требовать двухфакторной аутентификации для определенных пользователей. Субъекты должны быть снабжены следующими префиксами, чтобы соответствовать определенной части субъекта.
| Тип subject | Префикс | Описание |
|---|---|---|
| User | user: | Сопоставляет имя пользователя. |
| Group | group: | Определяет, есть ли у пользователя группа с таким именем. |
| OAuth 2.0 Client | oauth2:client: | Определяет, был ли запрос авторизован с помощью токена, выданного клиентом с указанным идентификатором, использующим тип гранта client_credentials. |
access_control:
rules:
- domain: 'rabrain.ru'
policy: 'two_factor'
subject:
- 'user:john'
- ['group:admin', 'group:app-name']
- 'group:super-admin'
- domain: 'rabrain.ru'
policy: 'two_factor'
subject:
- ['user:john']
- ['group:admin', 'group:app-name']
- ['group:super-admin']
access_control:
rules:
- domain: 'rabrain.ru'
policy: 'one_factor'
subject: 'group:super-admin'
- domain: 'rabrain.ru'
policy: 'one_factor'
subject:
- 'group:super-admin'
- domain: 'rabrain.ru'
policy: 'one_factor'
subject:
- ['group:super-admin']
methods
Этот критерий соответствует методу запроса HTTP. В первую очередь это полезно при попытке обойти аутентификацию для определенных типов запросов, когда эти запросы могут помешать основной или публичной работе сайта. Например, если вам нужно сделать предварительный CORS-запрос, вы можете применить политику обхода к OPTIONS-запросам.
Важно отметить, что Authelia не может сохранять данные запроса при перенаправлении пользователя.
| RFC | Methods | Additional Documentation |
|---|---|---|
| RFC7231 | GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE | MDN |
| RFC5789 | PATCH | MDN |
| RFC4918 | PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK |
access_control:
rules:
- domain: 'rabrain.ru'
policy: 'bypass'
methods:
- 'OPTIONS'
Обход OPTIONS-запросов к домену rabrain.ru.
networks
Эти критерии состоят из списка значений, которые могут быть IP-адресом, диапазоном сетевых адресов в нотации CIDR или именованным определением сети. Он сопоставляет первый адрес в заголовке X-Forwarded-For, или, если их нет, он возвращается к IP-адресу TCP-источника пакета. По этой причине важно правильно настроить прокси-сервер для точного соответствия запросов этим критериям. Примечание: вы можете комбинировать CIDR-сети с правилами псевдонимов по своему усмотрению.
Основное применение этого критерия - настройка требований безопасности ресурса в зависимости от местоположения пользователя. Теоретически вы можете рассматривать конкретную сеть как один из факторов, участвующих в аутентификации, можете запрещать конкретные сети и т. д.
Например, если у вас есть приложение, открытое как в локальных, так и во внешних сетях, вы можете различать эти запросы и применять к каждому из них разные политики. Либо отказывая в доступе, когда пользователь находится во внешних сетях, и разрешая доступ определенным внешним клиентам, а также внутренним клиентам, либо требуя меньших привилегий, когда пользователь находится в локальных сетях.
definitions:
network:
internal:
- '10.0.0.0/8'
- '172.16.0.0/12'
- '192.168.0.0/18'
access_control:
default_policy: 'two_factor'
rules:
- domain: 'secure.rabrain.ru'
policy: 'one_factor'
networks:
- '10.0.0.0/8'
- '172.16.0.0/12'
- '192.168.0.0/18'
- '112.134.145.167/32'
- domain: 'secure.rabrain.ru'
policy: 'one_factor'
networks:
- 'internal'
- '112.134.145.167/32'
- domain: 'secure.rabrain.ru'
policy: 'two_factor'
resources
Этот критерий соответствует пути и запросу запроса с помощью регулярных выражений. Правило выражается в виде списка строк. Если любое из регулярных выражений в списке соответствует запросу, оно считается совпавшим. Полезный инструмент для отладки этих регулярных выражений называется Regex 101 (убедитесь, что вы выбрали опцию Golang).
access_control:
rules:
- domain: 'app.rabrain.ru'
policy: 'bypass'
resources:
- '^/api([/?].*)?$'
query
Критерии запроса - это расширенный критерий, который позволяет настраивать правила, сопоставляющие определенные ключи аргументов запроса с различными правилами. Для базовых нужд рекомендуется использовать правила ресурсов.
Формат этого правила уникален тем, что представляет собой список списков. Логика, лежащая в основе этого формата, позволяет использовать логику ИЛИ и И. Первый уровень списка определяет логику ИЛИ, а второй уровень - логику И. Кроме того, каждый уровень этих списков не обязательно должен быть явно определен.
key
Ключ аргумента запроса для проверки.
value
Значение, по которому будет выполняться проверка. Оно необходимо, если оператор отсутствует или присутствует. Рекомендуется, чтобы это значение всегда заключалось в кавычки, как показано в примерах.
operator
Оператор правила для этого правила.
access_control:
rules:
- domain: 'app.rabrain.ru'
policy: 'bypass'
query:
- - operator: 'present'
key: 'secure'
- operator: 'absent'
key: 'insecure'
- - operator: 'pattern'
key: 'token'
value: '^(abc123|zyx789)$'
- operator: 'not pattern'
key: 'random'
value: '^(1|2)$'
Policies
Политика первого подходящего правила в списке определяет политику, применяемую к запросу, если ни одно правило не соответствует запросу, применяется политика по умолчанию (default_policy).
deny
Это политика, применяемая по умолчанию, и именно ее мы рекомендуем использовать по умолчанию для всех установок. Ее действие заключается в том, чтобы буквально запретить пользователю доступ к ресурсу. Кроме того, вы можете использовать эту политику для условного запрета доступа в нужных ситуациях. В качестве примера можно привести запрет доступа к API, в который не встроен механизм аутентификации.
bypass
Эта политика пропускает все проверки подлинности и позволяет любому пользователю использовать ресурс. Эта политика недоступна с правилом, включающим ограничение по субъекту, поскольку минимальный уровень аутентификации, необходимый для получения информации о субъекте, - one_factor.
one_factor
Эта политика требует, чтобы пользователь как минимум успешно выполнил 1FA (имя пользователя и пароль). Это означает, что если пользователь выполнил 2FA, ему будет разрешен доступ к ресурсу.
two_factor
Эта политика требует от пользователя успешного выполнения 2FA. В настоящее время это самый высокий уровень политики аутентификации.
Сопоставление правил
Есть две важные концепции, которые необходимо понимать, когда речь идет о сопоставлении правил.
С помощью команды authelia access-control check-policy можно легко определить, соответствует ли раздел правил управления доступом заданному запросу и почему он не соответствует.
Концепция сопоставления правил 1: последовательный порядок
Правила сопоставляются в последовательном порядке. Первая запись в списке, в которой совпадают все критерии, является правилом, которое применяется. Некоторые критерии правил дополнительно допускают список критериев, когда один из этих критериев в списке соответствует запросу, этот критерий считается подходящим для данного конкретного правила.
Например, следующее правило будет считать запросы на rabrain.ru или любой поддомен rabrain.ru соответствующими, если они имеют путь /api или если они начинаются с /api/. Это означает, что второе правило для app.rabrain.ru не будет рассматриваться, если запрос будет направлен на https://app.rabrain.ru/api, потому что первое правило совпадает с этим запросом.
- domain:
- 'rabrain.ru'
- '*.rabrain.ru'
policy: 'bypass'
resources:
- '^/api$'
- '^/api/'
- domain:
- 'app.rabrain.ru'
policy: 'two_factor'
Концепция соответствия правил 2: Критерии субъекта требуют аутентификации
Правила, содержащие элементы, зависящие от субъекта, требуют аутентификации для определения их соответствия. Поэтому такие правила не должны использоваться с политикой обхода. Критериями, которые содержат элементы, зависящие от субъекта, являются:
- Сам критерий субъекта
- Критерий domain_regex, когда он содержит именованные группы Regex.
Кроме того, если в правиле есть критерий темы, но все остальные критерии совпадают, пользователь будет немедленно перенаправлен на аутентификацию, если ни одно из предыдущих правил не соответствует запросу в соответствии с концепцией 1 соответствия правил. Это означает, что если у вас есть два одинаковых правила, одно из которых имеет зависимый от темы критерий, а другое является правилом обхода, то правило обхода должно быть первым.
Именованные группы регексов
Некоторые критерии допускают совпадение с именованными группами regex. Эти группы мы принимаем: User и Group
Именованные группы regex представлены синтаксисом (?P
definitions:
network:
internal:
- '10.10.0.0/16'
- '192.168.2.0/24'
vpn: '10.9.0.0/16'
access_control:
default_policy: 'deny'
rules:
- domain: 'public.rabrain.ru'
policy: 'bypass'
- domain: '*.rabrain.ru'
policy: 'bypass'
methods:
- 'OPTIONS'
- domain: 'secure.rabrain.ru'
policy: 'one_factor'
networks:
- 'internal'
- 'vpn'
- '192.168.1.0/24'
- '10.0.0.1'
- domain:
- 'secure.rabrain.ru'
- 'private.rabrain.ru'
policy: 'two_factor'
- domain: 'singlefactor.rabrain.ru'
policy: 'one_factor'
- domain: 'mx2.mail.rabrain.ru'
subject: 'group:admins'
policy: 'deny'
- domain: '*.rabrain.ru'
subject:
- 'group:admins'
- 'group:moderators'
policy: 'two_factor'
- domain: 'dev.rabrain.ru'
resources:
- '^/groups/dev/.*$'
subject: 'group:dev'
policy: 'two_factor'
- domain: 'dev.rabrain.ru'
resources:
- '^/users/john/.*$'
subject:
- ['group:dev', 'user:john']
- 'group:admins'
policy: 'two_factor'
3.5.2 - Регулирование
Конфигурация регулирования
regulation:
modes:
- 'user'
- 'ip'
max_retries: 3
find_time: '2m'
ban_time: '5m'
Опции
modes
Режимы для регулирования. В таблице ниже описан каждый вариант. Рекомендуемый режим - ip. Следует отметить, что независимо от настроенных в данный момент режимов запрета, если в базе данных существуют запреты, пользователю или IP будет отказано в доступе.
| Режим | Описание |
|---|---|
| user | Учетная запись пользователя является объектом любых автоматических запретов |
| ip | Удаленный ip является объектом любых автоматических запретов |
max_retries
Количество неудачных попыток входа в систему, после которых пользователь может быть забанен. Установка этого параметра в 0 полностью отключает регулирование.
find_time
Период времени, анализируемый на предмет неудачных попыток. Например, если вы установили max_retries в 3, а find_time в 2m, это означает, что у пользователя должно быть 3 неудачных входа в систему за 2 минуты.
ban_time
Период времени, на который пользователь будет заблокирован после выполнения настроек max_retries и find_time. По истечении этого срока пользователь сможет снова войти в систему.
3.5.3 - Password Policy
Конфигурация регулирования
password_policy:
standard:
enabled: false
min_length: 8
max_length: 0
require_uppercase: false
require_lowercase: false
require_number: false
require_special: false
zxcvbn:
enabled: false
min_score: 3
Опции
standard
В этом разделе можно включить стандартные политики безопасности.
enabled
Включает стандартную политику паролей.
min_length
Определяет минимально допустимую длину пароля.
max_length
Определяет максимально допустимую длину пароля.
require_uppercase
Указывает, что в пароле должна быть указана хотя бы одна буква UPPERCASE.
require_lowercase
Указывает, что в пароле должна быть указана хотя бы одна строчная буква.
require_number
Указывает, что в пароле должна быть указана хотя бы одна цифра.
require_special
Указывает, что в пароле должен быть указан хотя бы один специальный символ.
zxcvbn
Эта политика паролей включает расширенный учет надежности паролей с помощью zxcvbn.
Обратите внимание, что данная политика паролей не ограничивает вход пользователя, а лишь предоставляет ему информацию о том, насколько надежным является его пароль.
enabled
Включает политику паролей zxcvbn.
min_score
Настраивает минимальный балл zxcvbn, допустимый для новых паролей. В системе баллов zxcvbn существует 5 уровней (взято с github.com/dropbox/zxcvbn):
- оценка 0: слишком угадываемый: рискованный пароль (угадываний < 10^3)
- оценка 1: очень угадываемый: защита от дросселированных онлайн-атак (угадываний < 10^6)
- оценка 2: несколько угадываемый: защита от недросселированных онлайн-атак. (угадываний < 10^8)
- оценка 3: надежно не угадывается: умеренная защита от сценария медленного хэширования в автономном режиме. (угадываний < 10^10)
- оценка 4: очень неугадываемо: сильная защита от сценария медленного хэширования в автономном режиме. (guesses >= 10^10)
Мы не допускаем оценку 0, если вы установите значение min_score равным 0, вместо него будет использоваться значение по умолчанию.
3.6 - Проверка входа
Конфигурация
identity_validation:
elevated_session: {}
reset_password: {}
Методы проверки защищают две области:
Elevated Session, которая не позволяет вошедшему в систему пользователю выполнять привилегированные действия без предварительного подтверждения своей личности.
Reset Password — Сброс пароля, который не позволяет анонимному пользователю выполнить сброс пароля для пользователя без предварительного подтверждения его личности.
3.6.1 - Elevated Session
Elevated Session (Повышенная сессия) — это механизм безопасности в Authelia, который требует дополнительной проверки личности пользователя при выполнении критически важных действий, связанных с безопасностью аккаунта. Это предотвращает несанкционированные изменения, даже если злоумышленник получил доступ к сессии пользователя.
Как это работает?
Пользователь пытается выполнить важное действие, например:
- Смена пароля
- Настройка 2FA (TOTP, WebAuthn)
- Изменение email или других персональных данных
- Доступ к критическим разделам
Authelia запрашивает повторную аутентификацию:
- Ввод пароля
- Подтверждение через 2FA (если включено)
- Проверка биометрии (для WebAuthn)
Создается “повышенная сессия” на ограниченное время (по умолчанию — 5 минут), в течение которой пользователь может выполнять защищенные действия.
Конфигурация
identity_validation:
elevated_session:
code_lifespan: '5 minutes'
elevation_lifespan: '10 minutes'
characters: 8
require_second_factor: false
skip_second_factor: false
Опции
code_lifespan
Срок действия случайно сгенерированного одноразового кода, после которого он считается недействительным
elevation_lifespan
Время жизни возвышения после первоначальной проверки одноразового кода до истечения срока его действия.
characters
Количество символов в случайном одноразовом коде. Максимальное значение на данный момент составляет 20, но мы рекомендуем держать его в диапазоне от 8 до 12. Уменьшать значение ниже 8 крайне не рекомендуется.
require_second_factor
Требуется аутентификация по второму фактору для всех защищенных действий в дополнение к повышенному сеансу, если пользователь настроил метод аутентификации по второму фактору.
skip_second_factor
Пропускает требование повышенной сессии, если пользователь выполнил аутентификацию по второму фактору. Можно комбинировать с параметром require_second_factor, чтобы всегда (и только) требовать аутентификацию по второму фактору.
3.6.2 - Reset password
Основное назначение
- Позволяет пользователям самостоятельно сбросить пароль без вмешательства администратора.
- Альтернатива ручному сбросу через базу данных или LDAP.
- Интегрируется с email-уведомлениями для подтверждения личности.
Как это работает?
- Пользователь нажимает “Забыли пароль?” на странице входа.
- Authelia отправляет письмо с уникальной ссылкой для сброса (JWT-токен с ограниченным сроком действия).
- При переходе по ссылке открывается форма ввода нового пароля.
- После подтверждения пароль изменяется в выбранном бэкенде (LDAP, MySQL, PostgreSQL и т.д.).
Конфигурация
identity_validation:
reset_password:
jwt_secret: ''
jwt_lifespan: '5 minutes'
jwt_algorithm: 'HS256'
Опции
jwt_secret
Секрет, используемый алгоритмом HMAC для подписи JWT. Это значение должно представлять собой произвольную случайную строку с печатаемыми символами ASCII.
Настоятельно рекомендуется, чтобы это была случайная буквенно-цифровая строка из 64 или более символов.
jwt_lifespan
Время жизни JSON Web Token после его первоначальной генерации, по истечении которого он считается недействительным.
jwt_algorithm
Алгоритм JSON Web Token, используемый для подписи JWT. Должен быть HS256, HS384 или HS512.
3.7 - Seccion
Основная задача
Режим Session контролирует:
- Создание и валидацию сессионных кук после успешной аутентификации.
- Домены, для которых Authelia может выдавать авторизационные куки.
- Параметры безопасности кук (время жизни, HTTPS-only, SameSite и др.).
3.7.1 - Конфигурация
Конфигурация
session:
secret: 'insecure_session_secret'
name: 'authelia_session'
same_site: 'lax'
inactivity: '5m'
expiration: '1h'
remember_me: '1M'
cookies:
- domain: 'rabrain.ru'
authelia_url: 'https://auth.rabrain.ru'
default_redirection_url: 'https://www.rabrain.ru'
name: 'authelia_session'
same_site: 'lax'
inactivity: '5m'
expiration: '1h'
remember_me: '1d'
Конфигурация
session:
secret: 'insecure_session_secret'
name: 'authelia_session'
same_site: 'lax'
inactivity: '5m'
expiration: '1h'
remember_me: '1M'
cookies:
- domain: 'rabrain.ru'
authelia_url: 'https://auth.rabrain.ru'
default_redirection_url: 'https://www.rabrain.ru'
name: 'authelia_session'
same_site: 'lax'
inactivity: '5m'
expiration: '1h'
remember_me: '1d'
Провайдеры
В настоящее время существует два провайдера для хранения сессий (три, если считать Redis Sentinel отдельным провайдером):
- Memory (по умолчанию, с состоянием, без дополнительной настройки)
- Redis (без состояния).
- Redis Sentinel (без статических данных, высокая доступность).
Kubernetes
Kubernetes или High Availability
Важно отметить, что при выборе провайдера не рекомендуется использовать провайдеров с функцией stateless в сценариях High Availability, таких как Kubernetes. Рядом с каждым провайдером есть примечание, указывающее, является ли он государственным или нестационарным, рекомендуется использовать нестационарные провайдеры.
Опции
name
Значение имени по умолчанию для всех конфигураций cookies.
same_site
Значение same_site по умолчанию для всех конфигураций cookies.
inactivity
Значение бездействия по умолчанию для всех конфигураций cookies.
expiration
Значение срока действия по умолчанию для всех конфигураций cookies.
remember_me
Значение remember_me по умолчанию для всех конфигураций cookies.
cookies
Список определенных доменов cookie, которые Authelia настроена обрабатывать. Домены, не настроенные должным образом, будут автоматически отклоняться Authelia. Список позволяет администраторам определить несколько конфигураций доменов cookie сеанса с индивидуальными настройками.
domain
Домен, для защиты которого назначается сессионный cookie. Он должен совпадать с доменом, на котором обслуживается Authelia, или корнем домена, и, следовательно, если настроен authelia_url, должен иметь возможность читать и записывать куки для этого домена.
Например, если Authelia доступна по URL https://auth.rabrain.ru, домен должен быть либо auth.rabrain.ru, либо rabrain.ru.
Значение не должно совпадать с доменом из списка публичных суффиксов, поскольку браузеры не разрешают веб-сайтам записывать файлы cookie для таких доменов. Это касается большинства служб динамического DNS, таких как duckdns.org. Вы должны использовать свой домен вместо duckdns.org для этого значения, например example.duckdns.org.
Следовательно, если у вас есть example.duckdns.org и example-auth.duckdns.org, вы не сможете обмениваться файлами cookie между этими доменами.
authelia_url
Это обязательный URL, который является корневым URL вашей установки Authelia для этого домена cookie, который может быть использован для создания соответствующего URL перенаправления, когда требуется аутентификация. Этот URL должен:
- Уметь читать и записывать файлы cookie для настроенного домена.
- Использовать схему https://.
- Включать путь, если это необходимо (например, https://rabrain.ru/authelia, а не https://rabrain.ru, если вы используете опцию адреса сервера в authelia для указания подпути и если портал Authelia недоступен с https://rabrain.ru).
Соответствующий параметр запроса или заголовок для соответствующего прокси может отменить это поведение.
default_redirection_url
Это совершенно необязательный URL, который используется в качестве места перенаправления при прямом посещении Authelia. Эта опция отменяет глобальную опцию default_redirection_url.
name
Значение по умолчанию: Этот параметр принимает значение по умолчанию из настройки имени, приведенной выше.
Имя куки сеанса. По умолчанию устанавливается значение имени в основном разделе конфигурации сеанса.
same_site
Значение по умолчанию: Этот параметр принимает значение по умолчанию из настройки same_site, указанной выше.
Устанавливает значение cookies SameSite. До появления этого параметра по умолчанию было установлено значение None. Новое значение по умолчанию - Lax. Эта опция задается в нижнем регистре. Поэтому, например, если вы хотите установить значение Strict, то в конфигурации оно должно быть строгим.
Подробно о куках SameSite можно прочитать в MDN. Короче говоря, установка SameSite в значение Lax является наиболее предпочтительным вариантом для Authelia. None не рекомендуется, если только вы не знаете, что делаете, и не доверяете всем защищенным приложениям. Strict не будет работать во многих случаях, и мы не тестировали его в этом состоянии, но в любом случае он доступен как опция.
inactivity
Значение по умолчанию: Этот параметр принимает значение по умолчанию из настройки бездействия, приведенной выше.
Период времени, в течение которого пользователь может быть неактивен, пока сессия не будет уничтожена. Пригодится, если вам нужны длительные таймеры сеансов, но вы не хотите, чтобы неиспользуемые устройства были уязвимы.
expiration
Значение по умолчанию: Этот параметр принимает значение по умолчанию из настройки истечения срока действия, указанной выше.
Период времени до истечения срока действия cookie и уничтожения сессии. Это значение переопределяется параметром remember_me, если установлен флажок remember me.
remember_me
Значение по умолчанию: Этот параметр принимает значение по умолчанию из настройки remember_me, указанной выше.
Период времени до истечения срока действия куки и уничтожения сессии, когда установлен флажок remember me. Установка значения -1 полностью отключает эту функцию для данного домена сессионных cookie.
3.7.2 - Redis
Проблема стандартного режима (In-Memory)
По умолчанию Authelia хранит сессии в оперативной памяти (in-memory). Это приводит к:
- Потере сессий при перезагрузке Authelia.
- Невозможности масштабирования (если запущено несколько экземпляров Authelia, сессии не синхронизируются).
- Риску отказа — при падении сервера все пользователи разлогиниваются.
Как Redis решает эти проблемы?
| Проблема | Решение через Redis |
|---|---|
| Потеря сессий при перезагрузке | Сессии хранятся на внешнем сервере и сохраняются после рестарта |
| Несколько экземпляров Authelia | Все ноды читают/пишут сессии в единое хранилище |
| Высокая нагрузка | Redis оптимизирован для частых операций чтения/записи |
Конфигурация
session:
redis:
host: '127.0.0.1'
port: 6379
timeout: '5s'
max_retries: 0
username: 'authelia'
password: 'authelia'
database_index: 0
maximum_active_connections: 8
minimum_idle_connections: 0
tls:
server_name: 'myredis.rabrain.ru'
skip_verify: false
minimum_version: 'TLS1.2'
maximum_version: 'TLS1.3'
certificate_chain: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
private_key: |
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
high_availability:
sentinel_name: 'mysentinel'
# If `sentinel_username` is supplied, Authelia will connect using ACL-based
# authentication. Otherwise, it will use traditional `requirepass` auth.
sentinel_username: 'sentinel_user'
sentinel_password: 'sentinel_specific_pass'
nodes:
- host: 'sentinel-node1'
port: 26379
- host: 'sentinel-node2'
port: 26379
route_by_latency: false
route_randomly: false
Опции
host
Хост redis или путь к сокету unix. Если используется буквенный адрес IPv6, он должен быть заключен в квадратные скобки и взят в кавычки:
host: '[fd00:1111:2222:3333::1]'
timeout
Таймаут соединения с Redis.
max_retries
Максимальное количество повторных попыток при неудачной команде. Установка этого параметра в 0 полностью отключает повторные попытки.
port
Порт, на котором прослушивается Redis.
username
Имя пользователя для аутентификации в redis. Поддерживается только в redis 6.0+, и в настоящее время redis предлагает обратную совместимость с аутентификацией только по паролю. Вероятно, вам не нужно задавать это значение, если вы не проходили через процесс настройки ACL redis.
password
Пароль для аутентификации в Redis.
Настоятельно рекомендуется, чтобы это была случайная буквенно-цифровая строка из 64 или более символов, и пароль пользователя был изменен на это значение.
database_index
Номер индекса базы данных redis, то же значение, что и в команде redis SELECT.
maximum_active_connections
Максимальное количество соединений, открытых к redis в одно и то же время.
minimum_idle_connections
Минимальное количество соединений redis, которые следует держать открытыми, пока они не превышают максимальное количество активных соединений. Это полезно, если возникают большие задержки при установлении соединений.
tls
Если определено, включает соединение через TLS-сокет и дополнительно управляет параметрами проверки TLS-соединения для сервера redis.
По умолчанию Authelia использует системный сертификат доверия для проверки TLS-соединений, а глобальная опция certificates_directory может быть использована для дополнения этого параметра.
high_availability
При определении этой сессии включается соединение с redis sentinel. Возможно, в будущем мы добавим кластер redis.
sentinel_name
Имя ведущего сервера redis sentinel. Оно задается в конфигурации redis sentinel, это не имя хоста. Для конфигурации высокой доступности оно должно быть определено в данный момент.
sentinel_username
Имя пользователя для подключения к Redis Sentinel. Если оно указано, оно будет использоваться вместе с паролем sentinel_password для аутентификации на основе ACL для Redis Sentinel. Если указан только пароль, соединение с Redis Sentinel будет аутентифицировано с помощью традиционной аутентификации requirepass.
sentinel_password
Пароль для подключения к Redis Sentinel. Если указан с именем sentinel_username, Authelia настраивает аутентификацию на Redis Sentinel с помощью аутентификации на основе ACL. В противном случае используется аутентификация по requirepass.
Настоятельно рекомендуется, чтобы это была случайная буквенно-цифровая строка из 64 или более символов, и пароль пользователя был изменен на это значение.
nodes
Список узлов redis sentinel для балансировки нагрузки. Этот список добавляется к хосту в разделе redis выше. Необходимо определить либо хост redis, либо один сентинел-узел redis. Хост redis должен быть узлом redis sentinel, а не обычным узлом. Отдельные узлы redis определяются с помощью команд redis sentinel.
- host: redis-sentinel-0
port: 26379
host
Хост этого узла redis sentinel.
port
Порт этого узла redis sentinel.
route_by_latency
Приоритет отдается узлам redis sentinel с низкой задержкой, если установлено значение true.
route_randomly
Случайным образом выбирает узлы redis sentinel, если установлено значение true.
3.8 - Storage Хранилище данных
Какие данные хранятся?
| Тип данных | Примеры | Важность |
|---|---|---|
| Настройки пользователей | Выбранная тема, язык интерфейса | Низкая |
| 2FA-данные | TOTP-секреты, ключи WebAuthn | Высокая |
| Журналы аутентификации | Входы, попытки сброса пароля | Средняя |
| OAuth2-данные | Токены, authorization codes | Высокая |
| Сессии (если не используется Redis) | Активные сеансы пользователей | Высокая |
Поддерживаемые хранилища
Authelia работает с такими базами данных:
| Хранилище | Когда выбирать | Особенности |
|---|---|---|
| PostgreSQL | Production-среда | Высокая производительность, поддержка сложных запросов |
| MySQL/MariaDB | Уже есть инфраструктура MySQL | Совместимость с большинством хостингов |
| SQLite | Тестирование/разработка | Не требует сервера, но не для продакшена |
| Redis (только для сессий) | Высоконагруженные системы | Только key-value, без SQL |
Конфигурация
storage:
encryption_key: 'a_very_important_secret'
local: {}
mysql: {}
postgres: {}
Опции
encryption_key
Ключ шифрования, используемый для шифрования данных в базе данных. Мы шифруем данные, создавая контрольную сумму sha256 из указанного значения, и используем ее для шифрования данных с помощью 256-битного алгоритма AES-GCM.
Минимальная длина этого ключа - 20 символов.
Настоятельно рекомендуется, чтобы это была случайная буквенно-цифровая строка из 64 или более символов.
3.8.1 - PostgreSQL
Какие данные хранятся в PostgreSQL?
| Тип данных | Примеры | Важность |
|---|---|---|
| Учетные данные 2FA | TOTP-секреты, ключи WebAuthn | 🔥 Высокая |
| Журналы аутентификации | Входы, попытки сброса пароля | 🔍 Средняя |
| Настройки пользователей | Язык, тема интерфейса | 📌 Низкая |
| OAuth2-токены | Access/refresh tokens | 🔥 Высокая |
| Данные сессий (если не используется Redis) | Активные сеансы | ⚡ Высокая |
Почему именно PostgreSQL?
Преимущества перед другими СУБД
| Критерий | PostgreSQL | MySQL/SQLite | Redis |
|---|---|---|---|
| Поддержка сложных запросов | ✅ Да | ❌ Ограничена | ❌ Нет |
| Надежность транзакций | ✅ ACID | ✅ ACID | ❌ Key-Value |
| Производительность | ⚡ Высокая | ⚡ Средняя | ⚡ Максимальная |
| Масштабируемость | ✅ Горизонтальная | ✅ Вертикальная | ✅ Кластеры |
| Безопасность | 🔒 Row-Level Security | 🔒 Базовые права | 🔒 Нет |
Пример конфигурации
Добавьте в configuration.yml:
storage:
encryption_key: 'a_very_important_secret'
postgres:
address: 'tcp://127.0.0.1:5432'
servers: []
database: 'authelia'
schema: 'public'
username: 'authelia'
password: 'mypassword'
timeout: '5s'
tls:
server_name: 'postgres.rabrain.ru'
skip_verify: false
minimum_version: 'TLS1.2'
maximum_version: 'TLS1.3'
certificate_chain: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
private_key: |
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
Ключевые сценарии использования
Хранение секретов 2FA
- TOTP: Секретные ключи (totp_secrets таблица)
- WebAuthn: Публичные ключи устройств (webauthn_credentials)
-- Пример данных в PostgreSQL:
SELECT * FROM totp_secrets WHERE username = 'user@example.com';
Аудит безопасности
- Логи входов (authentication_logs)
- Попытки сброса пароля (identity_verification)
Масштабируемость
- Поддержка репликации для отказоустойчивости
- Возможность распределенной установки с несколькими нодами Authelia
Опции
encryption_key
Ключ шифрования, используемый для шифрования данных в базе данных. Мы шифруем данные, создавая контрольную сумму sha256 из указанного значения, и используем ее для шифрования данных с помощью 256-битного алгоритма AES-GCM.
Минимальная длина этого ключа - 20 символов.
Настоятельно рекомендуется, чтобы это была случайная буквенно-цифровая строка из 64 или более символов.
address
Настраивает адрес для сервера PostgreSQL. Сам адрес является коннектором, а схема должна быть либо схемой unix, либо одной из схем tcp.
storage:
postgres:
address: 'tcp://127.0.0.1:5432'
storage:
postgres:
address: 'tcp://[fd00:1111:2222:3333::1]:5432'
storage:
postgres:
address: 'unix:///var/run/postgres.sock'
servers
Здесь указывается список дополнительных резервных экземпляров PostgreSQL, которые будут использоваться в случае возникновения проблем с основным экземпляром, настроенным с помощью опций address и tls.
У каждого экземпляра сервера есть опции address и tls, которые имеют одинаковые требования и влияние, а также одинаковый синтаксис конфигурации. Это означает, что все остальные настройки, включая базу данных, схему, имя пользователя и пароль, должны быть такими же, как у основного экземпляра, и полностью реплицироваться.
storage:
postgres:
address: 'tcp://postgres1:5432'
tls:
server_name: 'postgres1.local'
servers:
- address: 'tcp://postgres2:5432'
tls:
server_name: 'postgres2.local'
- address: 'tcp://postgres3:5432'
tls:
server_name: 'postgres3.local'
database
Имя базы данных на сервере баз данных, к которой назначенный пользователь имеет доступ для работы с Authelia.
schema
Имя схемы базы данных, используемой на сервере базы данных, к которому назначенный пользователь имеет доступ для Authelia. По умолчанию это публичная схема.
username
Имя пользователя в паре с паролем, используемые для подключения к базе данных.
password
Пароль, связанный с именем пользователя, используемым для подключения к базе данных.
Настоятельно рекомендуется, чтобы это была случайная буквенно-цифровая строка из 64 или более символов, и пароль пользователя был изменен на это значение.
timeout
Таймаут соединения SQL.
tls
Если этот параметр определен, он включает соединение через сокет TLS и дополнительно управляет параметрами проверки TLS-соединения для сервера PostgreSQL.
По умолчанию Authelia использует системный сертификат доверия для проверки TLS-соединений, а глобальная опция certificates_directory может быть использована для дополнения этого параметра.
3.8.2 - SQLite3
Использование этого провайдера хранилища делает Authelia доступной для состояния. В сценариях высокой доступности важно использовать один из других провайдеров, и мы настоятельно рекомендуем использовать его в производственных средах, но это потребует от вас установки внешней базы данных, например PostgreSQL.
Пример конфигурации
Добавьте в configuration.yml:
storage:
encryption_key: 'a_very_important_secret'
local:
path: '/config/db.sqlite3'
Опции
encryption_key
Ключ шифрования, используемый для шифрования данных в базе данных. Мы шифруем данные, создавая контрольную сумму sha256 из указанного значения, и используем ее для шифрования данных с помощью 256-битного алгоритма AES-GCM.
Минимальная длина этого ключа - 20 символов.
Настоятельно рекомендуется, чтобы это была случайная буквенно-цифровая строка из 64 или более символов.
path
Путь, по которому будет храниться файл базы данных SQLite3. Он будет создан, если файл не существует.
3.8.3 - MySQL
Сравнение с PostgreSQL?
Преимущества перед другими СУБД
| Критерий | PostgreSQL | MySQL/SQLite | Redis |
|---|---|---|---|
| Поддержка сложных запросов | ✅ Да | ❌ Ограничена | ❌ Нет |
| Надежность транзакций | ✅ ACID | ✅ ACID | ❌ Key-Value |
| Производительность | ⚡ Высокая | ⚡ Средняя | ⚡ Максимальная |
| Масштабируемость | ✅ Горизонтальная | ✅ Вертикальная | ✅ Кластеры |
| Безопасность | 🔒 Row-Level Security | 🔒 Базовые права | 🔒 Нет |
Пример конфигурации
Добавьте в configuration.yml:
storage:
encryption_key: 'a_very_important_secret'
mysql:
address: 'tcp://127.0.0.1:3306'
database: 'authelia'
username: 'authelia'
password: 'mypassword'
timeout: '5s'
tls:
server_name: 'mysql.rabrain.ru'
skip_verify: false
minimum_version: 'TLS1.2'
maximum_version: 'TLS1.3'
certificate_chain: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
private_key: |
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
Опции
encryption_key
Ключ шифрования, используемый для шифрования данных в базе данных. Мы шифруем данные, создавая контрольную сумму sha256 из указанного значения, и используем ее для шифрования данных с помощью 256-битного алгоритма AES-GCM.
Минимальная длина этого ключа - 20 символов.
Настоятельно рекомендуется, чтобы это была случайная буквенно-цифровая строка из 64 или более символов.
address
Настраивает адрес для сервера PostgreSQL. Сам адрес является коннектором, а схема должна быть либо схемой unix, либо одной из схем tcp.
storage:
mysql:
address: 'tcp://127.0.0.1:3306'
storage:
mysql:
address: 'tcp://[fd00:1111:2222:3333::1]:3306'
storage:
mysql:
address: 'unix:///var/run/mysqld.sock'
database
Имя базы данных на сервере баз данных, к которой назначенный пользователь имеет доступ для работы с Authelia.
username
Имя пользователя в паре с паролем, используемые для подключения к базе данных.
password
Пароль, связанный с именем пользователя, используемым для подключения к базе данных.
Настоятельно рекомендуется, чтобы это была случайная буквенно-цифровая строка из 64 или более символов, и пароль пользователя был изменен на это значение.
timeout
Таймаут соединения SQL.
tls
Если этот параметр определен, он включает соединение через сокет TLS и дополнительно управляет параметрами проверки TLS-соединения для сервера MySQL.
По умолчанию Authelia использует системный сертификат доверия для проверки TLS-соединений, а глобальная опция certificates_directory может быть использована для дополнения этого параметра.
3.9 - Notifications (Уведомления)
Основные цели
- Верификация пользователя: Подтверждение email/телефона при регистрации или сбросе пароля.
- Безопасность: Уведомления о подозрительных действиях (например, вход с нового устройства).
- Восстановление доступа: Отправка временных кодов для сброса пароля или 2FA.
Типы уведомлений
| Тип уведомления | Когда отправляется | Метод отправки |
|---|---|---|
| Сброс пароля | При запросе восстановления пароля | Email/SMS |
| Подтверждение 2FA | При добавлении нового устройства | Email/Push |
| Подозрительный вход | При входе с нового IP/устройства | Email/SMS |
| Identity Verification | Для подтверждения личности | Email/SMS |
Конфигурация
notifier:
disable_startup_check: false
template_path: ''
filesystem: {}
smtp: {}
Опции
disable_startup_check
В уведомлении предусмотрена проверка запуска, которая проверяет правильность конфигурации указанного провайдера и возможность отправки писем. Эту проверку можно отключить с помощью опции disable_startup_check.
template_path
Этот параметр позволяет администратору указать путь к каталогу, в котором будут находиться пользовательские шаблоны уведомлений.
3.9.1 - SMTP
Назначение SMTP
Верификации пользователей
- Отправка ссылок для сброса пароля
- Подтверждение email при регистрации
- Коды для двухфакторной аутентификации (2FA)
Безопасности
- Уведомления о подозрительных действиях (например, вход с нового устройства)
- Предупреждения о попытках взлома
Работоспособности функций
- Без SMTP не будут работать:
- Сброс пароля (/reset-password)
- Регистрация новых пользователей
- Уведомления безопасности
Конфигурация
notifier:
disable_startup_check: false
smtp:
address: 'smtp://127.0.0.1:25'
timeout: '5s'
username: 'test'
password: 'password'
sender: "Authelia <admin@rabrain.ru>"
identifier: 'localhost'
subject: "[Authelia] {title}"
startup_check_address: 'test@rabrain.ru'
disable_require_tls: false
disable_starttls: false
disable_html_emails: false
tls:
server_name: 'smtp.rabrain.ru'
skip_verify: false
minimum_version: 'TLS1.2'
maximum_version: 'TLS1.3'
certificate_chain: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
private_key: |
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
Опции
address
Настройка адреса для SMTP-сервера. Сам адрес является коннектором, а схема должна быть smtp, submission или submissions. Единственное различие между этими схемами заключается в портах по умолчанию, а для отправки требуется транспорт TLS в соответствии с мерами безопасности портов SMTP, в то время как отправка и smtp используют стандартный транспорт TCP и обычно применяют StartTLS.
notifier:
smtp:
address: 'smtp://127.0.0.1:25'
notifier:
smtp:
address: 'submissions://[fd00:1111:2222:3333::1]:465'
timeout
Таймаут соединения SMTP.
username
Имя пользователя, отправляемое для аутентификации на SMTP-сервере. В паре с паролем.
password
Пароль в паре с именем пользователя, отправляемый для аутентификации на SMTP-сервере.
sender
Адрес отправителя используется для создания SMTP-команды MAIL FROM и добавления заголовка FROM. Этот адрес должен быть в формате RFC5322. Это означает, что он должен иметь один из двух форматов:
- jsmith@domain.com
- John Smith jsmith@domain.com
Команда MAIL FROM, отправляемая SMTP-серверам, не будет включать часть имени, она задается только в FROM в соответствии со спецификациями.
identifier
Имя, которое нужно отправить SMTP-серверу в качестве идентификатора с помощью команды HELO/EHLO. Некоторые SMTP-провайдеры, такие как Google Mail, отклоняют сообщение, если это localhost.
subject
Это тема, которую Authelia будет использовать в электронном письме. В настоящее время она имеет единственный заполнитель {title}, который должен быть включен во все электронные письма, поскольку это внутренний дескриптор содержимого письма.
startup_check_address
При запуске Authelia проверяет действительность SMTP-сервера, одна из проверок требует, чтобы мы спросили SMTP-сервер, может ли он отправить письмо от нас на определенный адрес, и это тот самый адрес. На самом деле никаких писем при этом не отправляется. Можно оставить все как есть, но вы можете настроить это, если у вас возникнут проблемы или вы захотите.
disable_require_tls
В целях безопасности настройки по умолчанию для Authelia требуют, чтобы SMTP-соединение было зашифровано с помощью TLS. Дополнительные сведения см. в разделе Безопасность. Эта опция отключает данную меру (не рекомендуется).
disable_starttls
Некоторые SMTP-серверы игнорируют спецификации SMTP и утверждают, что поддерживают STARTTLS, хотя на самом деле это не так. По соображениям безопасности Authelia отказывается отправлять сообщения на такие серверы. Данная опция отключает эту меру и включается на ВАШ собственный страх и риск.
disable_html_emails
Эта настройка полностью отключает HTML-форматирование писем и отправляет только текстовые сообщения. По умолчанию Authelia отправляет смешанные письма, содержащие как HTML, так и текст, поэтому эта опция редко бывает необходима.
tls
Если эта опция определена, она управляет параметрами проверки TLS-соединения для SMTP-сервера.
По умолчанию Authelia использует системное доверие к сертификатам для проверки TLS-соединений, а глобальная опция certificates_directory может быть использована для дополнения этого параметра.
Using Gmail
notifier:
smtp:
address: 'submission://smtp.gmail.com:587'
username: 'myaccount@gmail.com'
# Password can also be set using a secret: https://www.authelia.com/configuration/methods/secrets/
password: 'yourapppassword'
sender: 'admin@rabrain.ru'
3.9.2 - File system
Для чего используется?
- Тестирование шаблонов писем: Проверка внешнего вида email без настройки SMTP.
- Отладка логики уведомлений: Анализ содержимого сообщений (токены, ссылки).
- Локальная разработка: Когда нет доступа к SMTP-серверу.
Конфигурация
notifier:
disable_startup_check: false
filesystem:
filename: '/config/notification.txt'
Опции
filename
Файл, в который нужно добавить текст письма. Если он не существует, он будет создан.
3.10 - Telemetry (телеметрия)
Какие данные собираются?
Authelia хранит метрики только в оперативной памяти (не отправляет их автоматически наружу).
Примеры данных:
| Метрика | Описание | Пример значения |
|---|---|---|
| authelia_requests_total | Общее количество запросов | 1523 |
| authelia_2fa_attempts | Попыток 2FA (успешные/неудачные) | success: 120, failed: 5 |
| authelia_session_duration | Длительность сессий пользователей | avg: 5m |
| authelia_storage_queries | Запросы к базе данных | postgres: 42/s |
Как это работает?
- Данные собираются в реальном времени (например, при каждом входе пользователя).
- Хранятся в памяти до перезагрузки Authelia.
- Доступны для выгрузки через Prometheus или ручной запрос.
Конфигурация
telemetry:
metrics:
enabled: false
address: 'tcp://:9959/metrics'
buffers:
read: 4096
write: 4096
timeouts:
read: '6s'
write: '6s'
idle: '30s'
Опции
enabled
Определяет, включен ли Prometheus HTTP Metrics Exporter.
address
Настраивает адрес слушателя для HTTP-сервера Prometheus Metrics Exporter. Адрес сам по себе является слушателем, а схема должна быть либо схемой unix, либо одной из схем tcp.
buffers
Настройка буферов сервера.
timeouts
Настройка тайм-аутов сервера.
3.11 - Определения
3.11.1 - Network
Основные функции Network-настроек
| Настройка | За что отвечает | Пример значения |
|---|---|---|
| Прослушивание интерфейсов | На каких IP и портах доступен сервер | 0.0.0.0:9091 |
| Ограничение доверенных прокси | Какие IP могут передавать заголовки аутентификации | 192.168.1.0/24 |
| Таймауты | Защита от DDoS и медленных соединений | read: 10s |
| TLS/SSL | Шифрование соединений | Сертификаты Let’s Encrypt |
Конфигурация
definitions:
network:
network_name:
- '192.168.1.0/24'
- '192.168.2.20'
- '2001:db8::/32'
- '2001:db8:1234:5678::1'
Эти определения используются в качестве сетей управления доступом и сетей политики авторизации OpenID Connect 1.0.
Опции
key
Ключ - это имя политики. В приведенном выше примере ключом является network_name, и это значение должно использоваться в других областях конфигурации для ссылки на нее.
value
Значения, представляющие CIDR-нотацию IP-адресов, к которым применяется данное определение. В примере значение представляет собой список, содержащий 192.168.1.0/24, 192.168.2.20, 2001:db8::/32 и 2001:db8:1234:5678::1.
Нотация CIDR (например, 192.168.1.0/24) представляет собой диапазон IP-адресов. Число после косой черты указывает, сколько бит используется для сетевой части. Например, /24 означает, что первые 24 бита фиксированы, а последние 8 бит могут изменяться (что дает 256 возможных адресов). Один IP-адрес, например 192.168.2.20, может быть записан как есть или с /32.
3.11.2 - User Attributes
Конфигурация
definitions:
user_attributes:
# Boolean attribute example
is_admin:
expression: '"admin" in groups'
# String attribute example
department:
expression: 'groups[0]'
# Number attribute example
access_level:
expression: '"admin" in groups ? 10 : 5'
Опции
В этом разделе описаны отдельные параметры конфигурации. В настоящее время эти определения атрибутов используются в провайдере OpenID Connect 1.0.
Имя ключа - это имя результирующего атрибута. Важно отметить, что это имя атрибута не должно конфликтовать с дополнительными атрибутами, определенными в бэкенде аутентификации, или с общими атрибутами, которые мы определили.
В приведенном выше примере добавлены следующие атрибуты:
- is_admin
- department
- access_level
expression
Выражение Common Expression Language для этого атрибута.
3.12 - Разное
Конфигурация
certificates_directory: '/config/certs/'
default_redirection_url: 'https://home.example.com:8080/'
theme: 'light'
Опции
certificates_directory
По умолчанию Authelia использует системное хранилище сертификатов для проверки сертификатов TLS, но вы можете расширить его с помощью этой опции, которая формирует основу для доверия к TLS-соединениям в Authelia. В большинстве случаев, если не во всех TLS-соединениях, TLS-сертификат сервера проверяется с помощью этого расширенного хранилища доверия сертификатов.
Эта опция задает путь к каталогу, который может содержать один или несколько сертификатов, закодированных в формате X.509 PEM. Сами сертификаты должны иметь расширение .pem, .crt или .cer.
Эти сертификаты могут быть либо открытым ключом ЦС, который доверяет данному сертификату и любому подписанному им сертификату, либо отдельным сертификатом листа.
default_redirection_url
URL перенаправления по умолчанию - это URL, на который перенаправляются пользователи, когда Authelia не может определить целевой URL, на который направлялся пользователь.
В обычном процессе аутентификации пользователь пытается зайти на веб-сайт, и его перенаправляют на портал для входа в систему, чтобы пройти аутентификацию. Поскольку пользователь изначально нацелился на веб-сайт, портал знает, куда он направлялся, и может перенаправить его после процесса аутентификации. Однако, когда пользователь посещает портал регистрации напрямую, портал считает, что целевой веб-сайт - это портал. В этом случае, если настроен URL-адрес перенаправления по умолчанию, пользователь будет перенаправлен на этот URL-адрес. Если он не задан, пользователь не будет перенаправлен после аутентификации.
default_2fa_method
Устанавливает метод второго фактора по умолчанию для пользователей. Это должно быть пустое значение или один из включенных методов. Для новых пользователей по умолчанию будет выбран этот метод. Кроме того, если для пользователя был выбран метод webauthn, а у него был выбран метод totp, и метод totp был отключен в конфигурации, метод пользователя будет автоматически обновлен до метода webauthn.
Варианты:
- totp
- webauthn
- mobile_push
theme
В настоящее время для Authelia доступно 3 темы:
- light (по умолчанию)
- darck
- gray
Чтобы включить автоматическое переключение между темами, вы можете установить для темы значение auto. Тема будет установлена на темную или светлую в зависимости от системных предпочтений пользователя, которые определяются с помощью медиа-запросов.
3.12.1 - Server в Authelia
Ключевые функции настроек Server
| Настройка | Описание | Важность |
|---|---|---|
| address | Интерфейс и порт прослушивания | 🔥 Критично |
| tls | Настройки HTTPS (сертификаты) | 🔥 Критично |
| headers | Безопасность HTTP-заголовков | 🔐 Высокая |
| buffers | Оптимизация производительности | ⚡ Средняя |
| timeouts | Защита от DDoS/подвешенных сессий | 🛡️ Высокая |
| endpoints | Управление служебными API | 🔧 Опционально |
Конфигурация
server:
address: 'tcp://:9091/'
disable_healthcheck: false
tls:
key: ''
certificate: ''
client_certificates: []
headers:
csp_template: ''
buffers:
read: 4096
write: 4096
timeouts:
read: '6s'
write: '6s'
idle: '30s'
endpoints:
enable_pprof: false
enable_expvars: false
authz: {} ## See the dedicated "Server Authz Endpoints" configuration guide.
rate_limits: {} ## See the dedicated "Server Endpoint Rate Limits" configuration guide.
Детальный разбор параметров
Базовые настройки (address, disable_healthcheck)
server:
address: 'tcp://0.0.0.0:9091' # Слушать все интерфейсы на порту 9091
disable_healthcheck: false # Включить эндпоинт /healthcheck
Зачем:
- address: Определяет, откуда можно подключиться к Authelia.
- healthcheck: Нужен для мониторинга работы (Kubernetes, Docker Swarm).
Настройки TLS (HTTPS)
tls:
key: /etc/ssl/private/key.pem # Приватный ключ
certificate: /etc/ssl/certs/cert.pem # Сертификат
client_certificates: [] # mTLS (опционально)
Зачем:
- Без TLS пароли и сессии передаются в открытом виде.
- Важно: В production всегда используйте TLS (например, с Let’s Encrypt).
Безопасность заголовков (headers)
headers:
csp_template: "default-src 'self'" # Content Security Policy
Зачем:
- Защита от XSS-атак через CSP.
- Рекомендуемый шаблон для strict-режима:
csp_template: "default-src 'none'; script-src 'self'; style-src 'self'; font-src 'self'; img-src 'self' data:; connect-src 'self'"
Оптимизация (buffers, timeouts)
buffers:
read: 4096 # Размер буфера чтения (байт)
write: 4096 # Размер буфера записи
timeouts:
read: '6s' # Таймаут чтения запроса
write: '6s' # Таймаут отправки ответа
idle: '30s' # Таймаут неактивного соединения
####Зачем:
- buffers: Баланс между потреблением RAM и производительностью.
- timeouts: Защита от Slowloris-атак и “подвешенных” сессий.
Служебные эндпоинты (endpoints)
endpoints:
enable_pprof: false # Отключить debug-эндпоинты (/debug/pprof)
enable_expvars: false # Отключить метрики runtime (/debug/vars)
authz: {} # Настройки авторизации для API
rate_limits: {} # Лимиты запросов к API
Зачем:
- pprof/expvars: Полезны для отладки, но опасны в production.
- rate_limits: Защита API от брутфорса.
Пример production-конфигурации
server:
address: 'tcp://127.0.0.1:9091' # Только локальный доступ + Nginx/Traefik
tls:
certificate: /etc/letsencrypt/live/example.com/fullchain.pem
key: /etc/letsencrypt/live/example.com/privkey.pem
headers:
csp_template: "default-src 'self'; script-src 'none'"
timeouts:
read: '10s'
write: '15s'
idle: '1m'
Частые ошибки и решения
| Проблема | Решение |
|---|---|
| Authelia не запускается на порту | Проверьте address и отсутствие конфликта портов (netstat -tulpn) |
| Ошибки HTTPS (ERR_SSL_PROTOCOL_ERROR) | Убедитесь, что сертификаты не повреждены и имеют права 400 |
| Медленные ответы | Увеличьте buffers (например, до 8192) |
| Атаки на /debug/pprof | Всегда enable_pprof: false в production |
Интеграция с обратным прокси (Nginx/Traefik)
Для максимальной безопасности:
Настройте Authelia на 127.0.0.1:
address: 'tcp://127.0.0.1:9091'
В Nginx добавьте проксирование:
location /authelia {
proxy_pass http://127.0.0.1:9091;
proxy_set_header X-Real-IP $remote_addr;
}
Проверка конфигурации
authelia validate-config --config /etc/authelia/configuration.yml
Ожидаемый вывод:
Configuration parsed and validated successfully!
3.12.2 - Server Authz Endpoints
Назначение Server Authz Endpoints
Этот раздел конфигурации позволяет контролировать:
- Какие HTTP-методы разрешены (GET, POST, PUT, DELETE и т. д.).
- Какие URL-пути защищены (например, /api, /admin).
- Какие политики применяются (например, one_factor, two_factor, bypass, deny).
Конфигурация
server:
endpoints:
authz:
forward-auth:
implementation: 'ForwardAuth'
authn_strategies:
- name: 'HeaderAuthorization'
schemes:
- 'Basic'
scheme_basic_cache_lifespan: 0
- name: 'CookieSession'
ext-authz:
implementation: 'ExtAuthz'
authn_strategies:
- name: 'HeaderAuthorization'
schemes:
- 'Basic'
scheme_basic_cache_lifespan: 0
- name: 'CookieSession'
auth-request:
implementation: 'AuthRequest'
authn_strategies:
- name: 'HeaderAuthorization'
schemes:
- 'Basic'
scheme_basic_cache_lifespan: 0
- name: 'CookieSession'
legacy:
implementation: 'Legacy'
Опции
name
Первый уровень под директивой authz - это имя конечной точки. В примере это имена forward-auth, ext-authz, auth-request и legacy.
Имя коррелирует с путем к конечной точке. Все конечные точки начинаются с /api/authz/ и заканчиваются именем. В примере конечная точка forward-auth имеет полный путь /api/authz/forward-auth.
Допустимыми символами для имени являются буквенно-цифровые символы, а также -, _ и /. Они ДОЛЖНЫ начинаться и заканчиваться буквенно-цифровым символом.
implementation
Базовая реализация для конечной точки. Допустимые значения с учетом регистра: ForwardAuth, ExtAuthz, AuthRequest и Legacy.
authn_strategies
Список стратегий аутентификации и параметров их конфигурации. Эти стратегии расположены по порядку, и используется первая из них, оказавшаяся успешной. В случае отказа, кроме отсутствия в запросе информации, достаточной для выполнения стратегии, аутентификация немедленно прекращается, в противном случае выполняется попытка использования следующей стратегии из списка.
name
Имя стратегии. Допустимые значения с учетом регистра: CookieSession, HeaderAuthorization, HeaderProxyAuthorization, HeaderAuthRequestProxyAuthorization и HeaderLegacy.
schemes
Список схем, разрешенных для этой конечной точки. Варианты: Basic и Bearer. Эта опция применима только к стратегиям HeaderAuthorization, HeaderProxyAuthorization и HeaderAuthRequestProxyAuthorization и недоступна для устаревшей конечной точки, которая использует только Basic.
scheme_basic_cache_lifespan
Время жизни для кэширования комбинаций имени пользователя и пароля при использовании схемы Basic. Эта опция позволяет использовать кэширование, которое по умолчанию полностью отключено. Эта опция должна использоваться только при настройке схемы Basic, и, как и все новые опции, не может использоваться при реализации Legacy.
3.12.3 - Server Endpoint Rate Limits
Конфигурация
server:
endpoints:
rate_limits:
reset_password_start:
enable: true
buckets:
- period: '10 minutes'
requests: 5
- period: '15 minutes'
requests: 10
- period: '30 minutes'
requests: 15
reset_password_finish:
enable: true
buckets:
- period: '1 minute'
requests: 10
- period: '2 minutes'
requests: 15
second_factor_totp:
enable: true
buckets:
- period: '1 minute'
requests: 30
- period: '2 minutes'
requests: 40
- period: '10 minutes'
requests: 50
second_factor_duo:
enable: true
buckets:
- period: '1 minute'
requests: 10
- period: '2 minutes'
requests: 15
session_elevation_start:
enable: true
buckets:
- period: '5 minutes'
requests: 3
- period: '10 minutes'
requests: 5
- period: '1 hour'
requests: 15
session_elevation_finish:
enable: true
buckets:
- period: '10 minutes'
requests: 3
- period: '20 minutes'
requests: 5
- period: '1 hour'
requests: 15
Опции
enable
Включает заданную конфигурацию ограничения скорости. По умолчанию они включены.
buckets
Список отдельных buckets, которые необходимо рассмотреть для каждого запроса.
period
Настраивает период времени, на который распространяется действие токенизированного bucket.
requests
Настраивает количество запросов, к которым применяется токенизированный бакет.
reset_password_start
Настраивает ограничитель скорости, который применяется к конечной точке, инициализирующей поток сброса пароля.
reset_password_finish
Настраивает ограничитель скорости, который применяется к конечным точкам, потребляющим токены для потока сброса пароля.
second_factor_totp
Настраивает ограничитель скорости, который применяется к представлениям кода конечной точки TOTP для потока второго фактора.
second_factor_duo
Настраивает ограничитель скорости, применяемый к конечной точке Duo / Mobile Push, которая инициализирует поток авторизации приложения для потока второго фактора.
session_elevation_start
Настраивает ограничитель скорости, применяемый к конечной точке Elevated Session, которая инициализирует генерацию кода и уведомление для потока elevated session.
session_elevation_finish
Настраивает ограничитель скорости, применяемый к конечной точке Elevated Session, которая потребляет код для потока повышенной сессии.
4 - Bootstrap
Официальная документация Bootstrap
https://getbootstrap.com/docs/5.3/getting-started/introduction/
Шпаргалка по Bootstrap
4.1 - Работа с цветами в Bootstrap
Названия цветов в HUGO
.text-primary
.text-primary-emphasis
.text-secondary
.text-secondary-emphasis
.text-success
.text-success-emphasis
.text-danger
.text-danger-emphasis
.text-warning
.text-warning-emphasis
.text-info
.text-info-emphasis
.text-light
.text-light-emphasis
.text-dark
.text-dark-emphasis
.text-body
.text-body-emphasis
.text-body-secondary
.text-body-tertiary
.text-black
.text-white
.text-black-50
.text-white-50
<p class="text-primary">.text-primary</p>
<p class="text-primary-emphasis">.text-primary-emphasis</p>
<p class="text-secondary">.text-secondary</p>
<p class="text-secondary-emphasis">.text-secondary-emphasis</p>
<p class="text-success">.text-success</p>
<p class="text-success-emphasis">.text-success-emphasis</p>
<p class="text-danger">.text-danger</p>
<p class="text-danger-emphasis">.text-danger-emphasis</p>
<p class="text-warning bg-dark">.text-warning</p>
<p class="text-warning-emphasis">.text-warning-emphasis</p>
<p class="text-info bg-dark">.text-info</p>
<p class="text-info-emphasis">.text-info-emphasis</p>
<p class="text-light bg-dark">.text-light</p>
<p class="text-light-emphasis">.text-light-emphasis</p>
<p class="text-dark bg-white">.text-dark</p>
<p class="text-dark-emphasis">.text-dark-emphasis</p>
<p class="text-body">.text-body</p>
<p class="text-body-emphasis">.text-body-emphasis</p>
<p class="text-body-secondary">.text-body-secondary</p>
<p class="text-body-tertiary">.text-body-tertiary</p>
<p class="text-black bg-white">.text-black</p>
<p class="text-white bg-dark">.text-white</p>
<p class="text-black-50 bg-white">.text-black-50</p>
<p class="text-white-50 bg-dark">.text-white-50</p>
$blue: #0d6efd;
$indigo: #6610f2;
$purple: #6f42c1;
$pink: #d63384;
$red: #dc3545;
$orange: #fd7e14;
$yellow: #ffc107;
$green: #198754;
$teal: #20c997;
$cyan: #0dcaf0;
$primary: $blue;
$secondary: $gray-600;
$success: $green;
$info: $cyan;
$warning: $yellow;
$danger: $red;
$light: $gray-100;
$dark: $gray-900;
$white: #fff;
$gray-100: #f8f9fa;
$gray-200: #e9ecef;
$gray-300: #dee2e6;
$gray-400: #ced4da;
$gray-500: #adb5bd;
$gray-600: #6c757d;
$gray-700: #495057;
$gray-800: #343a40;
$gray-900: #212529;
$black: #000;
background
<div class="p-3 mb-2 bg-primary text-white">.bg-primary</div>
<div class="p-3 mb-2 bg-primary-subtle text-primary-emphasis">.bg-primary-subtle</div>
<div class="p-3 mb-2 bg-secondary text-white">.bg-secondary</div>
<div class="p-3 mb-2 bg-secondary-subtle text-secondary-emphasis">.bg-secondary-subtle</div>
<div class="p-3 mb-2 bg-success text-white">.bg-success</div>
<div class="p-3 mb-2 bg-success-subtle text-success-emphasis">.bg-success-subtle</div>
<div class="p-3 mb-2 bg-danger text-white">.bg-danger</div>
<div class="p-3 mb-2 bg-danger-subtle text-danger-emphasis">.bg-danger-subtle</div>
<div class="p-3 mb-2 bg-warning text-dark">.bg-warning</div>
<div class="p-3 mb-2 bg-warning-subtle text-warning-emphasis">.bg-warning-subtle</div>
<div class="p-3 mb-2 bg-info text-dark">.bg-info</div>
<div class="p-3 mb-2 bg-info-subtle text-info-emphasis">.bg-info-subtle</div>
<div class="p-3 mb-2 bg-light text-dark">.bg-light</div>
<div class="p-3 mb-2 bg-light-subtle text-light-emphasis">.bg-light-subtle</div>
<div class="p-3 mb-2 bg-dark text-white">.bg-dark</div>
<div class="p-3 mb-2 bg-dark-subtle text-dark-emphasis">.bg-dark-subtle</div>
<div class="p-3 mb-2 bg-body-secondary">.bg-body-secondary</div>
<div class="p-3 mb-2 bg-body-tertiary">.bg-body-tertiary</div>
<div class="p-3 mb-2 bg-body text-body">.bg-body</div>
<div class="p-3 mb-2 bg-black text-white">.bg-black</div>
<div class="p-3 mb-2 bg-white text-dark">.bg-white</div>
<div class="p-3 mb-2 bg-transparent text-body">.bg-transparent</div>
Прозрачность
<div class="bg-success p-2 text-white">This is default success background</div>
<div class="bg-success p-2 text-white bg-opacity-75">This is 75% opacity success background</div>
<div class="bg-success p-2 text-dark bg-opacity-50">This is 50% opacity success background</div>
<div class="bg-success p-2 text-dark bg-opacity-25">This is 25% opacity success background</div>
<div class="bg-success p-2 text-dark bg-opacity-10">This is 10% opacity success background</div>
4.2 - Mixins
Mixins в Bootstrap: что это и как использовать
Mixins (примеси) — это функции в Sass (SCSS), которые позволяют повторно использовать куски кода в CSS. В Bootstrap они используются для генерации готовых стилей (например, сетки, кнопок, утилит) без дублирования кода.
1. Зачем нужны Mixins?
- Уменьшают повторение кода — один миксин может генерировать множество вариантов стилей.
- Делают код модульным — можно кастомизировать Bootstrap, не правя исходные файлы.
- Упрощают создание адаптивных стилей — например, для сетки или отступов.
2. Примеры миксинов в Bootstrap
Bootstrap предоставляет десятки миксинов. Вот основные категории:
① Grid Mixins (Сетка)
// Пример: Создание кастомной колонки
@include make-col(6); // Колонка на 50% ширины (6/12)
② Flexbox Mixins
// Пример: Flex-контейнер с центрированием
.my-component {
@include d-flex();
@include justify-content(center);
}
③ Spacing Mixins (Отступы)
// Пример: Добавление margin-top
.element {
@include margin-top(1rem);
}
④ Breakpoint Mixins (Адаптивность)
// Пример: Стили только для экранов ≥768px
@include media-breakpoint-up(md) {
.card { width: 50%; }
}
⑤ Button Mixins (Кнопки)
// Пример: Создание кастомной кнопки
.my-btn {
@include button-variant(
$background: #ff5722,
$border: #ff5722,
$hover-background: darken(#ff5722, 10%)
);
}
3. Как использовать миксины?
Шаг 1: Подключите Bootstrap SCSS
Убедитесь, что в вашем проекте есть исходные файлы Bootstrap (SCSS), а не только скомпилированный CSS.
Шаг 2: Создайте свой SCSS-файл
Например, custom.scss:
// Импорт Bootstrap
@import "bootstrap/scss/bootstrap";
// Ваши кастомные стили с миксинами
.my-custom-grid {
@include make-col-ready();
@include make-col(4); // Колонка на 33.3%
}
@include media-breakpoint-down(sm) {
.my-custom-grid {
@include make-col(12); // На мобильных — 100%
}
}
Шаг 3: Скомпилируйте SCSS
Используйте Sass-компилятор (например, через npm):
sass custom.scss custom.css
4. Популярные миксины Bootstrap
| Миксин | Описание | Пример |
|---|---|---|
make-container() | Создает контейнер | @include make-container(); |
make-col() | Генерирует колонку | @include make-col(6); |
border-radius() | Скругление углов | @include border-radius(0.5rem); |
transition() | Анимация перехода | @include transition(all 0.3s); |
box-shadow() | Тень | @include box-shadow(0 0 10px rgba(0,0,0,0.1)); |
5. Зачем это нужно?
- Кастомизация Bootstrap — если вам нужно что-то уникальное, но на основе логики Bootstrap.
- Оптимизация CSS — миксины помогают избежать дублирования кода.
- Адаптивность — легко создавать breakpoint-зависимые стили.
6. Где найти все миксины?
- Официальная документация
- Исходные файлы Bootstrap:
node_modules/bootstrap/scss/mixins/
Итог
Mixins в Bootstrap — это мощный инструмент для тех, кто работает с Sass. Они позволяют:
✅ Гибко настраивать компоненты.
✅ Создавать адаптивные стили.
✅ Держать код чистым и модульным.
Пример использования:
// Кастомная кнопка
.my-btn {
@include button-variant(
$background: #17a2b8,
$border: #17a2b8,
$hover-background: darken(#17a2b8, 10%)
);
@include border-radius(2rem);
}
4.3 - Bootstrap Flexbox
Bootstrap 5 Flexbox Управление: Полная Таблица
Таблица с основными классами Bootstrap 5 для работы с Flexbox:
1. Основные Flex-контейнеры
| Класс | Описание | Пример |
|---|---|---|
.d-flex | Включает Flexbox | <div class="d-flex"> |
.d-inline-flex | Строчный Flex-контейнер | <span class="d-inline-flex"> |
.d-sm-flex | Адаптивный Flex (на экранах ≥576px) | <div class="d-sm-flex"> |
2. Направление осей (Flex Direction)
| Класс | Описание | CSS-аналог |
|---|---|---|
.flex-row | Горизонтальное (слева направо) | flex-direction: row |
.flex-row-reverse | Горизонтальное (справа налево) | flex-direction: row-reverse |
.flex-column | Вертикальное (сверху вниз) | flex-direction: column |
.flex-column-reverse | Вертикальное (снизу вверх) | flex-direction: column-reverse |
Пример:
<div class="d-flex flex-row"> <!-- По умолчанию -->
<div>1</div><div>2</div>
</div>
3. Выравнивание по главной оси (Justify Content)
| Класс | Описание | CSS-аналог |
|---|---|---|
.justify-content-start | В начале оси | justify-content: flex-start |
.justify-content-end | В конце оси | justify-content: flex-end |
.justify-content-center | По центру | justify-content: center |
.justify-content-between | Равные промежутки между | justify-content: space-between |
.justify-content-around | Равные отступы вокруг | justify-content: space-around |
.justify-content-evenly | Полное равномерное распределение | justify-content: space-evenly |
Пример:
<div class="d-flex justify-content-between">
<div>Лево</div><div>Право</div>
</div>
4. Выравнивание по поперечной оси (Align Items)
| Класс | Описание | CSS-аналог |
|---|---|---|
.align-items-start | В начале оси | align-items: flex-start |
.align-items-end | В конце оси | align-items: flex-end |
.align-items-center | По центру | align-items: center |
.align-items-baseline | По базовой линии | align-items: baseline |
.align-items-stretch | Растянуть (по умолчанию) | align-items: stretch |
Пример:
<div class="d-flex align-items-center" style="height: 100px;">
<div>По центру высоты</div>
</div>
5. Управление отдельными элементами (Align Self)
| Класс | Описание | CSS-аналог |
|---|---|---|
.align-self-start | Элемент в начале | align-self: flex-start |
.align-self-end | Элемент в конце | align-self: flex-end |
.align-self-center | Элемент по центру | align-self: center |
.align-self-stretch | Растянуть элемент | align-self: stretch |
Пример:
<div class="d-flex">
<div class="align-self-end">Прижат к низу</div>
</div>
6. Перенос элементов (Flex Wrap)
| Класс | Описание | CSS-аналог |
|---|---|---|
.flex-nowrap | Без переноса (по умолчанию) | flex-wrap: nowrap |
.flex-wrap | С переносом | flex-wrap: wrap |
.flex-wrap-reverse | Перенос в обратном порядке | flex-wrap: wrap-reverse |
Пример:
<div class="d-flex flex-wrap">
<div class="w-25">1</div><div class="w-25">2</div>...
</div>
7. Управление порядком (Order)
| Класс | Описание |
|---|---|
.order-0 – .order-5 | Приоритет от 0 (высокий) до 5 (низкий) |
.order-first | Первым (аналог order: -1) |
.order-last | Последним (аналог order: 6) |
Пример:
<div class="d-flex">
<div class="order-2">Второй</div>
<div class="order-1">Первый</div>
</div>
8. Автоматические отступы (Flex Fill)
| Класс | Описание |
|---|---|
.flex-fill | Элемент растягивается, заполняя пространство |
.flex-grow-1 | Аналог flex-grow: 1 |
Пример:
<div class="d-flex">
<div class="flex-fill">Занимает всё место</div>
</div>
9. Адаптивные классы
Все классы работают с breakpoints:
.flex-sm-row,.justify-content-md-center,.align-items-lg-endи т.д.
Пример:
<div class="d-flex flex-column flex-md-row">
<!-- На мобильных — вертикально, на десктопе — горизонтально -->
</div>
Итог
Bootstrap 5 предоставляет полный контроль над Flexbox через простые классы. Для сложных макетов комбинируйте их с Grid.
Совет: Используйте .gap-* для отступов между элементами:
<div class="d-flex gap-3">
<div>Элемент 1</div>
<div>Элемент 2</div>
</div>
4.4 - Bootstrap Отступы
Bootstrap 5: Горизонтальные и вертикальные отступы (Gutters) — Полная таблица
Bootstrap 5 предоставляет удобные классы для управления отступами между блоками (margin и padding).
Вот полная таблица с примерами для горизонтальных и вертикальных отступов.
1. Классы для отступов (Spacing Utilities)
Bootstrap использует систему {property}{sides}-{size}, где:
property:m— margin (внешний отступ).p— padding (внутренний отступ).
sides:t— top (верх).b— bottom (низ).s— start (лево для LTR, право для RTL).e— end (право для LTR, лево для RTL).x— горизонтальные (левый + правый).y— вертикальные (верхний + нижний).- (пусто) — все стороны.
size:0— 0px.1— 0.25rem (4px).2— 0.5rem (8px).3— 1rem (16px).4— 1.5rem (24px).5— 3rem (48px).auto— автоматический отступ.
2. Горизонтальные отступы (между колонками и блоками)
| Класс | Описание | Пример |
|---|---|---|
.gap-1 – .gap-5 | Отступ между flex-элементами (margin) | <div class="d-flex gap-3"> |
.gx-1 – .gx-5 | Горизонтальный padding (левый + правый) | <div class="row gx-3"> |
.mx-1 – .mx-5 | Горизонтальный margin (левый + правый) | <div class="mx-auto"> |
.ms-1 – .ms-5 | Отступ слева (margin-start) | <div class="ms-3"> |
.me-1 – .me-5 | Отступ справа (margin-end) | <div class="me-2"> |
.px-1 – .px-5 | Горизонтальный padding (левый + правый) | <div class="px-4"> |
Пример:
<div class="d-flex gap-3"> <!-- Отступы между flex-элементами -->
<div>Блок 1</div>
<div>Блок 2</div>
</div>
<div class="row gx-4"> <!-- Горизонтальные отступы в гриде -->
<div class="col">Колонка 1</div>
<div class="col">Колонка 2</div>
</div>
3. Вертикальные отступы (между строками и блоками)
| Класс | Описание | Пример |
|---|---|---|
.gy-1 – .gy-5 | Вертикальный padding (верх + низ) | <div class="row gy-3"> |
.my-1 – .my-5 | Вертикальный margin (верх + низ) | <div class="my-4"> |
.mt-1 – .mt-5 | Отступ сверху (margin-top) | <div class="mt-2"> |
.mb-1 – .mb-5 | Отступ снизу (margin-bottom) | <div class="mb-3"> |
.py-1 – .py-5 | Вертикальный padding (верх + низ) | <div class="py-5"> |
Пример:
<div class="row gy-4"> <!-- Вертикальные отступы в гриде -->
<div class="col-12">Строка 1</div>
<div class="col-12">Строка 2</div>
</div>
<div class="my-5"> <!-- Большой вертикальный margin -->
<p>Контент с отступами сверху и снизу</p>
</div>
4. Автоматические и специальные отступы
| Класс | Описание | Пример |
|---|---|---|
.m-auto | Автоматический margin (центрирование) | <div class="mx-auto"> |
.p-auto | Автоматический padding (редко используется) | <div class="p-auto"> |
.m-n1 – m-n5 | Отрицательный margin | <div class="m-n3"> |
Пример:
<div class="mx-auto" style="width: 200px;"> <!-- Центрирование -->
Этот блок будет по центру
</div>
5. Адаптивные отступы
Все классы поддерживают адаптивность через breakpoints:
sm(≥576px),md(≥768px),lg(≥992px),xl(≥1200px),xxl(≥1400px).
Пример:
<div class="mx-3 mx-md-5"> <!-- На мобильных mx-3, на десктопе mx-5 -->
Адаптивный отступ
</div>
Итог
✅ Горизонтальные отступы → .gap-*, .gx-*, .mx-*, .ms-*, .me-*.
✅ Вертикальные отступы → .gy-*, .my-*, .mt-*, .mb-*.
✅ Центрирование → .mx-auto.
✅ Адаптивность → .mx-sm-3, .gy-lg-4.
Совет: Для сеток (row/col) лучше использовать .gx-* и .gy-*, а для flex-контейнеров — .gap-*.
5 - Описание настроек Docker
5.1 - Шпаргалка по Docker и Docker Compose (CLI)
Основные команды Docker
| Команда | Описание |
|---|---|
docker ps | Список работающих контейнеров |
docker ps -a | Список всех контейнеров (включая остановленные) |
docker images | Список образов |
docker pull <image> | Скачать образ (например, docker pull nginx) |
docker run <image> | Запустить контейнер из образа |
docker run -d <image> | Запуск в фоновом режиме (detached) |
docker run -p 8080:80 <image> | Проброс портов (хост:контейнер) |
docker run -v /path:/path <image> | Подключение тома (volume) |
docker stop <container> | Остановить контейнер |
docker start <container> | Запустить остановленный контейнер |
docker restart <container> | Перезапустить контейнер |
docker rm <container> | Удалить контейнер |
docker rmi <image> | Удалить образ |
docker exec -it <container> bash | Войти в контейнер (интерактивный терминал) |
docker logs <container> | Просмотр логов контейнера |
docker build -t <name> . | Собрать образ из Dockerfile |
docker system prune | Очистка неиспользуемых данных (кэш, остановленные контейнеры) |
docker network ls | Список сетей |
Docker Compose (управление мультиконтейнерными приложениями)
| Команда | Описание |
|---|---|
docker-compose up | Запуск сервисов из docker-compose.yml |
docker-compose up -d | Запуск в фоновом режиме |
docker-compose down | Остановка и удаление контейнеров |
docker-compose ps | Список запущенных сервисов |
docker-compose logs | Просмотр логов |
docker-compose logs <service> | Логи конкретного сервиса |
docker-compose build | Пересобрать образы |
docker-compose exec <service> bash | Войти в контейнер сервиса |
docker-compose restart | Перезапуск сервисов |
docker-compose pull | Обновить образы из docker-compose.yml |
Полезные флаги
-d→ Запуск в фоне (detached)-p 80:80→ Проброс портов-v /data:/app→ Подключение volume--name my_container→ Задать имя контейнеру--rm→ Автоудаление контейнера после остановки-e VAR=value→ Передача переменных окружения
Примеры
- Запуск Nginx с пробросом порта
docker run -d -p 8080:80 --name my_nginx nginx - Сборка и запуск через Docker Compose
docker-compose up -d --build - Остановка всех контейнеров
docker stop $(docker ps -aq)
docker --help и docker-compose --help для справки по командам.
5.2 - Справочник по созданию образов Docker
В этом руководстве рассмотрим:
- Синтаксис Dockerfile
- Основные директивы
- Оптимизация сборки
- Команды для работы с образами
1. Структура Dockerfile
Файл Dockerfile — это инструкция для сборки Docker-образа.
Пример минимального Dockerfile
# Базовый образ
FROM ubuntu:22.04
# Установка зависимостей
RUN apt-get update && apt-get install -y curl
# Копирование файлов в образ
COPY ./app /app
# Рабочая директория
WORKDIR /app
# Команда запуска контейнера
CMD ["python", "app.py"]
2. Основные директивы
| Директива | Описание | Пример |
|---|---|---|
FROM | Базовый образ | FROM python:3.9 |
RUN | Выполнить команду при сборке | RUN apt-get update |
COPY | Копировать файлы в образ | COPY ./src /app |
ADD | Аналог COPY, но с распаковкой архивов и поддержкой URL | ADD https://example.com/file.tar.gz /tmp |
WORKDIR | Установить рабочую директорию | WORKDIR /app |
ENV | Установить переменную окружения | ENV NODE_ENV=production |
ARG | Переменная, используемая только при сборке | ARG VERSION=1.0 |
EXPOSE | Объявить порт (не пробрасывает его!) | EXPOSE 80 |
CMD | Команда по умолчанию при запуске | CMD ["npm", "start"] |
ENTRYPOINT | Основная команда контейнера | ENTRYPOINT ["/app/start.sh"] |
VOLUME | Создать точку монтирования | VOLUME /data |
USER | Задать пользователя | USER nobody |
HEALTHCHECK | Проверка здоровья контейнера | HEALTHCHECK --interval=30s CMD curl -f http://localhost/health |
3. Оптимизация сборки
Многоступенчатая сборка (Multi-stage Build)
Уменьшает размер финального образа.
# 1. Этап сборки
FROM node:18 AS builder
WORKDIR /app
COPY . .
RUN npm install && npm run build
# 2. Финальный образ
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
Кэширование слоев
COPYиADDинвалидируют кэш, если файлы меняются.RUNкэшируется, если команда не менялась.
Совет: Меняющиеся команды (apt-get update) размещайте в начале.
4. Сборка и управление образами
Сборка образа
docker build -t myapp:latest .
-t— задать имя и тег (name:tag).— путь кDockerfile
Сборка с аргументами
ARG VERSION=1.0
ENV APP_VERSION=$VERSION
docker build --build-arg VERSION=2.0 -t myapp:2.0 .
Просмотр истории образа
docker history myapp:latest
Экспорт/импорт образа
docker save myapp:latest > myapp.tar
docker load < myapp.tar
5. Продвинутые техники
.dockerignore
Исключает файлы из копирования (аналог .gitignore):
node_modules/
*.log
.git/
Динамический CMD/ENTRYPOINT
ENTRYPOINT ["/app/start.sh"]
CMD ["--port=8080"]
Запуск с переопределением:
docker run myapp --port=3000
Health Check
HEALTHCHECK --interval=5s --timeout=3s \
CMD curl -f http://localhost/ || exit 1
6. Примеры для разных языков
Python (FastAPI)
FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uvicorn", "app:app", "--host", "0.0.0.0"]
Node.js
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
CMD ["npm", "start"]
Go
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o /app/main .
FROM alpine:latest
COPY --from=builder /app/main /main
CMD ["/main"]
7. Полезные команды
| Команда | Описание |
|---|---|
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:multiarch . | Сборка мультиархитектурного образа |
docker scan myapp:latest | Проверка на уязвимости (Snyk) |
docker image prune -a | Удалить неиспользуемые образы |
Итог:
- Используйте многоступенчатую сборку для оптимизации.
- Минимизируйте количество слоев (объединяйте
RUN). - Применяйте
.dockerignore, чтобы ускорить сборку. - Для продакшена указывайте конкретные версии (
python:3.9, а неpython:latest).
5.3 - Очистка кеша при использовании Docker
Очистка кэша Docker на сервере
Для очистки кэша Docker можно использовать несколько команд, в зависимости от того, что именно нужно удалить:
1. Очистка неиспользуемых (висячих) образов, контейнеров, сетей и volumes
docker system prune
- Удалит:
- Остановленные контейнеры
- Сети, не используемые ни одним контейнером
- Висячие (dangling) образы (те, у которых нет тегов)
- Висячие билд-кэш
2. Агрессивная очистка (включая неиспользуемые образы)
docker system prune -a
- Удалит все неиспользуемые образы, а не только dangling.
3. Удаление всех остановленных контейнеров
docker container prune
4. Удаление всех неиспользуемых образам
docker image prune -a
5. Удаление кэша сборки (build cache)
docker builder prune
6. Удаление всех volumes, не привязанных к контейнерам
docker volume prune
7. Полная очистка (осторожно!)
Если нужно полностью очистить Docker (все контейнеры, образы, volumes, сети):
docker system prune -a --volumes
⚠️ Будьте осторожны! Эта команда удалит всё, что не используется в данный момент.
Дополнительные полезные команды:
- Просмотр занимаемого места:
docker system df - Удаление конкретного образа:
docker rmi <image_id> - Удаление всех образов (очень опасно!):
docker rmi $(docker images -q)
Вывод
Лучший вариант для периодической очистки — docker system prune.
Если нужно освободить максимум места — docker system prune -a --volumes.
🚀 После очистки можно проверить свободное место:
df -h
6 - Микроразметка для СЕО поиска
Микроразметка для поисковых систем: Google, Яндекс и другие
В современном цифровом мире важно не только создавать качественный контент, но и помогать поисковым системам правильно его интерпретировать. Микроразметка (Schema.org) — это мощный инструмент, который позволяет структурировать данные на сайте, улучшая их отображение в поисковой выдаче. С помощью микроразметки можно выделять рейтинги, цены, события, товары и многое другое, делая сниппеты более информативными и привлекательными для пользователей.
В этом разделе собраны подробные руководства по работе с микроразметкой для разных поисковых систем, включая Google, Яндекс и другие. Вы узнаете, какие форматы поддерживаются, как проверять разметку и какие ошибки стоит избегать.
6.1 - JSON-LD - микроразметка материалов для выдачи сниппетов в поиске Google
Оригинал статьи находится здесь
Руководство по JSON-LD для начинающих
Что такое JSON-LD?
JSON-LD расшифровывается как JavaScript Object Notation for Linked Data, что представляет собой многомерные массивы (представьте себе: список пар атрибут-значение).
Это формат реализации для структурирования данных, аналогичный Microdata и RDFa. Обычно, в контексте SEO, JSON-LD реализуется с использованием словаря Schema.org, совместной инициативы Google, Bing, Yahoo! и Yandex, созданной в 2011 году для создания единого словаря структурированных данных для веба. (Тем не менее, Bing и другие поисковые системы официально не заявили о своей поддержке реализаций JSON-LD для Schema.org.)
JSON-LD считается более простым в реализации, благодаря возможности просто вставить разметку в HTML-документ, в отличие от необходимости оборачивать разметку вокруг HTML-элементов (как это делается с Microdata).
Что делает JSON-LD?
JSON-LD аннотирует элементы на веб-странице, придавая данным структуру. Это позволяет поисковым системам лучше понимать содержимое, устранять неоднозначности и устанавливать связи между сущностями. В результате формируется более упорядоченная и понятная структура данных, что способствует созданию лучше организованного интернета в целом.

JSON-LD преобразует неструктурированные данные в структурированные
Рисунок 1 — Концептуальная визуализация работы JSON-LD: обработка неструктурированного контента в интернете, его аннотирование и структурирование для получения организованного результата.
Таким образом, JSON-LD помогает поисковым системам, таким как Google и Яндекс, точнее интерпретировать информацию на сайте, что может улучшить отображение страницы в результатах поиска (например, с помощью расширенных сниппетов).
Где в HTML-коде страницы должен располагаться JSON-LD?
Google рекомендует размещать JSON-LD в разделе <head> HTML-документа. Однако допустимо также добавлять его и внутри <body>. Кроме того, Google способен обрабатывать динамически сгенерированные JSON-LD теги в DOM (объектной модели документа).
Коротко:
- Лучше:
<head> - Но можно:
<body> - Динамические теги (например, загружаемые через JavaScript) тоже работают.
Это означает, что поисковые системы смогут распознать разметку независимо от её расположения в HTML, если она корректно сформирована.
Разбираем JSON-LD
Неизменяемые теги (Не нужно запоминать — просто копируйте и вставляйте)
<script type="application/ld+json">
{
...
}
</script>
Когда вы видите JSON-LD, первое, что должно бросаться в глаза — это тег <script>. Атрибут type="application/ld+json" сообщает браузеру: «Эй, здесь JavaScript, содержащий JSON-LD».
💡 Профессиональный совет
- Всегда закрывайте теги сразу после открытия.
Как соль и перец идут вместе, так и открывающие фигурные скобки{требуют закрывающих}. - Важно: Если ваш JSON-LD не заключён в фигурные скобки
{}, он не будет обработан. (Держите его «завёрнутым» в скобки!)
Таким образом, правильная структура JSON-LD гарантирует, что поисковые системы смогут корректно прочитать и использовать вашу разметку.
"@context": “http://schema.org”
Второй обязательный элемент в JSON-LD разметке — это @context со значением http://schema.org.
Этот параметр сообщает браузеру: «Эй, вот словарь, на который я ссылаюсь — ты можешь найти его по адресу http://schema.org».
Преимущество для SEO-специалиста:
Мы получаем доступ ко всем типам элементов (item types) и их свойствам (item properties), которые определены в Schema.org.
📌 Пример структуры:
{
"@context": "http://schema.org",
"@type": "Article",
"headline": "Пример статьи",
"author": {
"@type": "Person",
"name": "Иван Петров"
}
}
🔍 Обратите внимание:
- Видите эту запятую после
"http://schema.org"? Она говорит парсеру: «Данные продолжаются, не останавливайся».
💡 Профессиональный совет
- Следите за запятыми (и всегда проверяйте разметку в Google’s Structured Data Testing Tool).
- Пропущенная запятая = невалидная разметка. Даже опытные разработчики часто ошибаются в этом месте.
JSON-LD строго требует правильного синтаксиса, поэтому всегда проверяйте свою разметку перед публикацией!
"@type": “…”
Третий ключевой элемент JSON-LD разметки — это указание @type. После двоеточия здесь начинается аннотация данных. Параметр @type определяет тип размеченной сущности. Полный список всех доступных типов можно найти в официальной документации: https://schema.org/docs/full.html.

Как это работает?
В примере ниже:
{
"@context": "http://schema.org",
"@type": "Person",
"name": "Иван Иванов"
}
@type сообщает: «Эй, здесь используется тип Person (его описание можно найти по адресу http://schema.org/Person)».
Если ввести эту ссылку в браузер, откроется документация Schema.org с:
- Техническими спецификациями этого типа
- Списком допустимых свойств (
item properties) - Часто — примерами использования
Вложенные @type
При использовании вложенных структур потребуется указывать @type для каждого уровня. Это особенно важно в разметке:
- Товаров (
Product) - Хлебных крошек (
BreadcrumbList) - Организаций с сотрудниками (
Organization→Employee)
Пример вложенности:
{
"@context": "http://schema.org",
"@type": "Product",
"brand": {
"@type": "Brand",
"name": "Nike"
}
}
💡 Профессиональный совет:
- Всегда проверяйте допустимые свойства для вашего
@typeна Schema.org. Например, дляPersonобязательным может бытьname, а дляProduct—offers. - Используйте инструмент проверки структурированных данных Google, чтобы убедиться в отсутствии ошибок.
@type или его неверное указание сделает разметку бесполезной для поисковых систем!Пары “атрибут-значение”
Следующий шаг — аннотирование информации о выбранном типе сущности (@type). Допустимые свойства для каждого типа можно найти на соответствующей странице Schema.org.
Синтаксис JSON-LD для свойств
Каждое свойство в разметке состоит из двух элементов:
Свойство (Item Property)
- Должно быть взято из словаря Schema.org.
- Обязательно заключайте в двойные прямые кавычки (
" ").
🔹 Важно: Использование фигурных (“ ”) или одинарных (' ') кавычек приведёт к ошибке валидации! - Должно принадлежать к разрешённым свойствам для выбранного
@type(указаны в документации Schema.org).
Значение (Value)
- Сюда вписывается конкретное значение свойства.
- Правила форматирования:
- Текстовые строки и URL: всегда в двойных кавычках (
"пример"). - Числа (целые, дробные): можно без кавычек (
42), но допустимо и с ними ("42"— тогда тип данных будет строковым). - Несколько значений: используйте квадратные скобки (
["значение1", "значение2"]).
- Текстовые строки и URL: всегда в двойных кавычках (
Примеры
✅ Корректно:
{
"@type": "Book",
"name": "Война и мир",
"isbn": "978-5-699-12014-7", // Строка в кавычках
"price": 599.99, // Число без кавычек
"author": ["Лев Толстой", "Иван Тургенев"] // Массив значений
}
❌ Ошибки:
- Фигурные кавычки:
“Война и мир”→ невалидно. - Пропущенные кавычки:
name: Война и мир→ синтаксическая ошибка. - Неразрешённое свойство:
"pageCount": 1225(если@typeне поддерживает это свойство).
💡 Профессиональный совет:
- Всегда сверяйтесь со списком свойств для вашего
@type. - Для сложных случаев (например, товары с вариантами) используйте вложенные структуры и массивы.
- Проверяйте разметку в Google Rich Results Test — он покажет не только ошибки, но и потенциальные улучшения.
Запомните:
Правильный синтаксис — это не педантичность, а необходимость. Поисковые системы обрабатывают только безупречно оформленные данные!
Квадратные скобки [ ] в JSON-LD
Квадратные скобки используются, когда у свойства есть несколько значений.
Примеры использования:
Несколько значений одного свойства
Например, если у человека два имени:"givenName": ["Джейсон", "Деруло"]Здесь скобки говорят: «У этого свойства несколько значений — у Джейсона Деруло два имени».
Ссылки на соцсети (sameAs)
Часто применяется для перечисления профилей в соцсетях:"sameAs": [ "https://facebook.com/jasonderulo", "https://twitter.com/jasonderulo", "https://instagram.com/jasonderulo" ]
Важные правила:
Запятая после последнего элемента не ставится
"sameAs": [ "https://facebook.com/jasonderulo", // запятая "https://twitter.com/jasonderulo" // НЕТ запятой в конце ]Отсутствие запятой означает конец списка.
Не путать с фигурными скобками
{}
Квадратные скобки — только для перечисления однотипных значений, а фигурные — для вложенных объектов (например, адреса или организации).
💡 Профессиональный совет:
- Используйте квадратные скобки для:
- Списков (например, авторов книги).
- Альтернативных URL (например,
sameAsдля соцсетей). - Любых свойств, допускающих множественные значения по Schema.org.
- Всегда проверяйте, поддерживает ли выбранный
@typeмножественные значения для конкретного свойства.
Пример корректной и некорректной разметки:
✅ Правильно:
"author": ["Лев Толстой", "Фёдор Достоевский"]
❌ Неправильно:
"author": ["Лев Толстой", "Фёдор Достоевский",]
→ Лишняя запятая после последнего элемента.
Для проверки используйте Google’s Structured Data Testing Tool.
Вложенность (Nesting) в JSON-LD
Вложенность означает организацию данных слоями, где одни объекты содержат другие объекты. Это можно сравнить с матрешкой, где большая кукла содержит внутри меньшую — так же и данные могут быть структурированы иерархически.
Зачем нужна вложенность?
Некоторые свойства относятся только к определенным типам сущностей. Например, в разметке события (Event):
nameможет означать название события,- но внутри могут быть вложены свойства
performer(исполнитель) иvenue(место проведения), у которых тоже есть своиname.
Без вложенности поисковые системы не поймут, к чему относится каждое свойство.
Как правильно вкладывать данные в JSON-LD
Начните с основного типа (
@type)
Например,Event.Укажите свойство, требующее вложенности
Например,performerилиoffers.Откройте фигурные скобки
{ }для нового объекта
Внутри укажите:@type(тип вложенной сущности, напримерPersonилиOffer),- его свойства и значения.
Закройте вложенный объект
- Не ставьте запятую перед закрывающей скобкой
}. - Запятая после
}нужна, только если дальше идут другие свойства.
- Не ставьте запятую перед закрывающей скобкой
Пример вложенности
Разметка музыкального события:
{
"@context": "http://schema.org",
"@type": "MusicEvent",
"name": "Концерт Jason Aldean",
"performer": { // ← Начало вложенного объекта
"@type": "MusicGroup",
"name": "Jason Aldean",
"sameAs": "https://www.jasonaldean.com"
}, // ← Запятая, потому что дальше есть еще свойства
"location": {
"@type": "Place",
"name": "Мэдисон-Сквер-Гарден",
"address": "Нью-Йорк, США"
} // ← Нет запятой, это последнее свойство
}
Чек-лист по вложенности
✅ Используйте свойства, допустимые для родительского @type (см. Schema.org).
✅ Значение вложенного объекта заключайте в { }.
✅ Указывайте @type для вложенной сущности.
✅ Добавляйте обязательные свойства для вложенного типа (например, price для Offer).
❌ Не ставьте запятую перед } (это вызовет ошибку).
✅ Запятая после }, если дальше идут другие свойства.
Где чаще всего встречается вложенность?
- Товары (
Product):- Цена и условия предложения вкладываются в
offers(@type: Offer). - Отзывы — в
review(@type: Review).
- Цена и условия предложения вкладываются в
- Организации (
Organization):- Адрес (
@type: PostalAddress), - контакты, учредители.
- Адрес (
- Рецепты (
Recipe):- Ингредиенты, инструкции, питательная ценность.
💡 Профессиональный совет:
- Делайте отступы для вложенных объектов — так код легче читать.
- Проверяйте обязательные свойства для вложенных типов на Schema.org.
- Тестируйте разметку в Google Rich Results Test.
Ошибка → Пропущенный @type во вложенном объекте или лишние/недостающие запятые сделают разметку нерабочей!
Пример ошибки:
❌ Неправильно:
"performer": {
"name": "Jason Aldean" // ← Нет @type!
}
✅ Исправлено:
"performer": {
"@type": "MusicGroup",
"name": "Jason Aldean"
}
Распространённые ошибки в JSON-LD разметке
Если ваша разметка не проходит валидацию в Google’s Structured Data Testing Tool, проверьте этот список типичных проблем.
1. Синтаксические ошибки
Кавычки: прямые vs. фигурные
- ✅ Правильно:
""(прямые двойные кавычки). - ❌ Ошибка:
“”(фигурные кавычки, которые могут появиться при копировании из Word/Excel).
Запятые
- Пропущенная запятая между свойствами → разметка не валидируется.
- Лишняя запятая после последнего элемента в объекте или массиве → ошибка.
- Как найти: В инструменте тестирования ищите красный крестик (
✗) слева — он часто указывает на проблему с запятой.
Пример:
// ❌ Ошибка (лишняя запятая)
"author": {
"@type": "Person",
"name": "Иван Иванов", // ← Запятая не нужна, это последнее свойство
}
// ✅ Исправлено
"author": {
"@type": "Person",
"name": "Иван Иванов"
}
2. Ошибки словаря Schema.org
- Использование свойств, недопустимых для данного
@type.
Пример: Свойствоauthorне поддерживается для@type: Product. - Пропуск обязательных свойств.
Пример: ДляOfferобязательно указаниеpriceиpriceCurrency.
Решение:
- Всегда сверяйтесь с документацией Schema.org для вашего
@type. - Проверяйте разметку в тестере Google.
3. Нарушение правил Google
- Размеченные данные должны быть видны на странице.
Пример: Если в JSON-LD указан рейтинг 5.0, а на странице его нет — это нарушение. - Запрещены манипулятивные практики.
Пример: Добавление ложных отзывов или несвязанных сущностей для обхода алгоритмов.
Что делать:
- Ознакомьтесь с Google’s Structured Data Policies.
- Убедитесь, что контент в разметке соответствует содержимому страницы.
4. Проблемы при копировании из Microsoft Office
- Word/Excel автоматически заменяют кавычки на фигурные (
“”). - Добавляют невидимые символы форматирования.
Решение:
- Используйте HTML-редактор (например, VS Code, Sublime Text).
- Вставляйте текст через «Вставить как обычный текст» (Ctrl+Shift+V).
Итоговый чек-лист
- Кавычки: Только прямые (
""). - Запятые: Ни лишних, ни пропущенных.
- Словарь: Только разрешённые свойства для
@type. - Контент: Разметка = содержимое страницы.
- Проверка: Всегда тестируйте в Google Rich Results Test.
💡 Совет: Для сложных типов (например, Product с Review) используйте пошаговую проверку — сначала базовые свойства, затем вложенные объекты.
Ошибка → Даже одна пропущенная кавычка или запятая может привести к тому, что Google проигнорирует всю разметку!
Процесс добавления JSON-LD на сайт
Создание JSON-LD разметки зависит от вашего уровня знакомства с синтаксисом JSON-LD и словарем Schema.org. Ниже приведен пошаговый процесс для новичков, который поможет вам разобраться в основах и создать эффективную разметку.
1. Определите цель разметки
📌 Вопросы, которые нужно задать себе:
- Что вы хотите разметить?
Убедитесь, что выбранный вами контент можно аннотировать с помощью Schema.org. Некоторые вещи могут казаться логичными, но не иметь подходящего типа в словаре. - Зачем вам это нужно?
Определите, есть ли практическая польза (например, улучшение сниппетов в поиске) или вы просто экспериментируете. Разметка должна помогать поисковым системам лучше понимать ключевую информацию на странице.
2. Изучите документацию и примеры
- Проверьте, поддерживает ли Google ваш тип разметки.
Откройте официальную документацию Google и найдите примеры. - Не изобретайте велосипед!
Используйте готовые примеры от Google или Schema.org, адаптируя их под свои нужды.
3. Откройте страницу типа данных на Schema.org
- Перейдите на Schema.org и найдите нужный
@type(например,Product,Article). - Ознакомьтесь с:
- Описанием типа,
- Обязательными и рекомендуемыми свойствами,
- Примерами использования.
4. Скопируйте “неизменяемые” элементы
Начните с базовой структуры:
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "ТипДанных"
}
</script>
- Не забывайте, что тег
<script>обязателен!
5. Определите свойства и их значения
- Выпишите свойства, которые хотите добавить (например, для
Product:name,description,image). - Пока не думайте о синтаксисе — просто составьте список.
6. Добавьте синтаксис JSON-LD и вложенности
- Заполните свойства, соблюдая правила:
- Кавычки: только
"". - Запятые: между свойствами, но не после последнего.
- Кавычки: только
- Для вложенных объектов (например,
offersвProduct) используйте фигурные скобки{}и указывайте@type.
Пример для товара:
{
"@context": "http://schema.org",
"@type": "Product",
"name": "Смартфон XYZ",
"image": "https://example.com/image.jpg",
"offers": {
"@type": "Offer",
"price": "299.99",
"priceCurrency": "USD"
}
}
7. Протестируйте разметку
- Используйте Google’s Structured Data Testing Tool.
- Убедитесь, что:
- Нет ошибок (красных крестиков),
- Все свойства распознаются.
8. Добавьте разметку на сайт
- Способ 1: Вставьте код в
<head>страницы. - Способ 2: Для динамического контента согласуйте с разработчиками (например, генерация через CMS).
- Дополнительно: Используйте
itemIDиitemRefдля сложных структур (подробнее в статье Moz).
9. Делитесь опытом!
У вас есть вопросы или интересные кейсы по JSON-LD? Делитесь в комментариях!
Итог:
- Планируйте → Изучайте → Копируйте → Тестируйте → Внедряйте.
- Избегайте типичных ошибок: неправильные кавычки, запятые, нарушение правил Google.
- Используйте инструменты валидации на каждом этапе.
Теперь вы готовы создавать SEO-оптимизированную разметку!
6.2 - Документация RDF для универсальной микроразметки текстов для микропоиска
RDFa Core 1.1 — Третье издание
Синтаксис и правила обработки для встраивания RDF через атрибуты
Рекомендация W3C от 17 марта 2015 года
Актуальная версия:
http://www.w3.org/TR/2015/REC-rdfa-core-20150317/
Последняя опубликованная версия:
http://www.w3.org/TR/rdfa-core/
Отчёт о внедрении:
http://www.w3.org/2010/02/rdfa/wiki/CR-ImplementationReport
Предыдущая версия:
http://www.w3.org/TR/2014/PER-rdfa-core-20141216/
Предыдущая рекомендация:
http://www.w3.org/TR/2013/REC-rdfa-core-20130822/
Редакторы:
- Бен Адида, Creative Commons, ben@adida.net
- Марк Бирбек, webBackplane, mark.birbeck@webBackplane.com
- Шейн МакКаррон, Applied Testing and Technology, Inc., shane@aptest.com
- Иван Герман, W3C, ivan@w3.org
Английская версия данной спецификации является единственной нормативной. Неофициальные переводы могут быть доступны.
Авторские права: © 2007–2015 W3C® (MIT, ERCIM, Кейо, Бэйхан). Применяются правила W3C об ответственности, товарных знаках и использовании документов.
Аннотация
Современный Интернет в основном состоит из огромного количества документов, созданных с использованием HTML. Эти документы содержат значительный объём структурированных данных, которые в большинстве случаев недоступны для инструментов и приложений. Если издатели смогут выражать эти данные более полно, а инструменты — считывать их, откроются новые возможности для пользователей: структурированные данные можно будет передавать между приложениями и веб-сайтами, а браузеры смогут улучшить пользовательский опыт. Например:
- событие на веб-странице можно будет напрямую импортировать в настольный календарь;
- лицензию на документ можно будет автоматически определить, чтобы информировать пользователей об их правах;
- информацию о создателе фотографии, настройках камеры, разрешении, местоположении и теме можно будет публиковать так же легко, как и саму фотографию, что позволит осуществлять структурированный поиск и обмен.
RDFa Core — это спецификация атрибутов для выражения структурированных данных в любом языке разметки. Встроенные данные, уже доступные в языке разметки (например, HTML), часто можно повторно использовать в RDFa, что избавляет издателей от необходимости дублировать информацию в содержимом документа.
Абстрактное представление данных основано на RDF (RDF11-PRIMER), что позволяет издателям создавать собственные словари, расширять чужие и развивать свою терминологию с максимальной совместимостью. Выраженная структура тесно связана с данными, поэтому визуализированную информацию можно копировать вместе с её структурой.
Правила интерпретации данных универсальны и не требуют отдельных инструкций для разных форматов. Это позволяет авторам и издателям данных определять собственные форматы без необходимости обновлять ПО, регистрировать их в централизованном органе или опасаться конфликтов между разными форматами.
RDFa разделяет некоторые цели с микроформатами (MICROFORMATS). Однако если микроформаты задают и синтаксис для встраивания структурированных данных в HTML, и конкретный словарь терминов для каждого микроформата, то RDFa определяет только синтаксис, полагаясь на независимые спецификации терминов (часто называемых словарями или таксономиями). RDFa позволяет свободно комбинировать термины из разных словарей и разработан так, что язык можно анализировать без знания конкретного используемого словаря.
Этот документ представляет собой детальное описание синтаксиса RDFa, предназначенное для:
- Разработчиков процессоров RDFa, которым необходимо точное описание правил разбора.
- Тех, кто хочет интегрировать RDFa в новый язык разметки.
- Организаций, желающих рекомендовать использование RDFa и создать руководства для пользователей.
- Всем, кто знаком с RDF и хочет понять, как работает процессор RDFa «под капотом».
Для тех, кто ищет введение в RDFa и практические примеры, рекомендуется ознакомиться с RDFA-PRIMER.
Как читать этот документ
Если вы не знакомы ни с RDFa, ни с RDF и просто хотите добавить RDFa в свои документы, то вам может быть полезнее ознакомиться с RDFa Primer, который даёт более простое введение.
Если вы уже знакомы с RDFa и хотите изучить правила обработки (например, для создания собственного процессора RDFa), то наиболее интересным для вас будет раздел «Модель обработки». В нём содержится обзор каждого этапа обработки, а затем более детальные подразделы с описанием отдельных правил.
Если вы не знакомы с RDFa, но знаете RDF, то перед изучением модели обработки полезно прочитать раздел «Обзор синтаксиса», где приведены примеры разметки с использованием RDFa. Примеры помогут легче понять правила обработки.
Если вы не знакомы с RDF, то перед активной работой с RDFa рекомендуется ознакомиться с разделом «Терминология RDF». Хотя RDFa разработан так, чтобы быть простым для авторов (и для его использования не обязательно глубоко разбираться в RDF), разработчикам приложений, обрабатывающих RDFa, понимание RDF необходимо. В интернете есть множество материалов по RDF, а также растущее число инструментов, поддерживающих RDFa. В этом документе содержится лишь минимальный необходимый контекст по RDF, чтобы прояснить цели RDFa.
Примечание
RDFa — это способ выражения отношений в стиле RDF с помощью простых атрибутов в существующих языках разметки, таких как HTML.
- RDF полностью интернационализирован и допускает использование Internationalized Resource Identifiers (IRI). В этой спецификации повсеместно используется термин IRI.
- Даже если вы не знакомы с термином IRI, вы, вероятно, встречали URI или URL. IRI — это расширение URI, позволяющее использовать символы за пределами ASCII.
- RDF поддерживает такие символы, как и RDFa. В этой спецификации сознательно используется термин IRI, чтобы подчеркнуть эту возможность.
Важное уточнение
Хотя в данной спецификации упоминаются исключительно IRI, язык-хост (Host Language) может ограничивать синтаксис своих атрибутов подмножеством IRI (например, атрибут @href в HTML5).
Однако, независимо от ограничений валидации в языке-хозяине, процессор RDFa способен обрабатывать полный диапазон IRI.
Статус данного документа
Данный раздел описывает статус документа на момент его публикации. Другие документы могут заменять текущую версию. Актуальный список публикаций W3C и последнюю редакцию данного технического отчёта можно найти в индексе технических отчётов W3C по адресу: http://www.w3.org/TR/.
Редакционные изменения
Настоящая версия представляет собой редакционную правку Рекомендации, опубликованной 22 августа 2013 года. Указанный документ являлся пересмотренной версией спецификации RDFa Syntax 1.0 [RDFA-SYNTAX]. Между текущей версией и версией 1.0 существует ряд существенных различий, включая:
- Удаление специальных правил для XHTML - теперь они определены в отдельном документе XHTML+RDFa [XHTML-RDFA].
- Расширение типов данных некоторых атрибутов RDFa для поддержки Terms (терминов), CURIES и Absolute IRIs.
- Разрешение языкам-хостам определять коллекции терминов по умолчанию, префиксные отображения и словарь по умолчанию.
- Возможность определения словаря по умолчанию для использования с неопределёнными терминами.
- Требование к регистронезависимому сравнению терминов.
- Расширенное поведение атрибута @property, которое во многих случаях может заменять атрибут @rel.
- Изменённая обработка @typeof для лучшего соответствия практическому использованию.
Более подробный список изменений доступен в разделе Changes (Изменения).
Тестирование
Доступен тестовый набор, который не является исчерпывающим, но может быть полезен как пример использования RDFa.
Участие и отзывы
Документ опубликован Рабочей группой RDFa в качестве Рекомендации. Все замечания и предложения можно направлять по адресу: public-rdfa@w3.org (подписка, архивы). Отзывы приветствуются.
С отчётом о внедрении рабочей группы можно ознакомиться здесь.
Статус рекомендации
Документ был рассмотрен членами W3C, разработчиками программного обеспечения, другими группами W3C и заинтересованными сторонами. Директор W3C утвердил его в качестве официальной Рекомендации. Это стабильный документ, который может использоваться в качестве справочного материала или цитироваться в других документах. Роль W3C заключается в привлечении внимания к спецификации и содействии её широкому внедрению, что способствует улучшению функциональности и совместимости веба.
Патентная политика
Документ разработан группой, действующей в соответствии с Патентной политикой W3C от 5 февраля 2004 года. W3C ведёт публичный список патентных заявлений, связанных с результатами работы группы. На этой странице также содержатся инструкции по подаче патентных заявлений. Лица, располагающие информацией о патентах, которые могут содержать существенные пункты (Essential Claims), обязаны раскрыть эту информацию в соответствии с разделом 6 Патентной политики W3C.
Процесс W3C
Документ регулируется Процессом W3C от 14 октября 2005 года.
1. Мотивация
(Данный раздел не является нормативным)
Проблемы RDF/XML
Спецификация RDF/XML [RDF-SYNTAX-GRAMMAR] обеспечивает достаточную гибкость для представления всех абстрактных концепций RDF. Однако у неё есть ряд недостатков:
Сложность валидации
- Документы, содержащие RDF/XML, крайне сложно (или невозможно) проверять с помощью XML-схем (XML Schemas) или DTD.
- Это затрудняет интеграцию RDF/XML в другие языки разметки.
- Новые языки схем, такие как RELAX NG [RELAXNG-SCHEMA], поддерживают валидацию произвольного RDF/XML, но их широкое внедрение займёт время.
Дублирование данных
- Даже если добавить RDF/XML напрямую в XML-диалект (например, XHTML), возникнет дублирование между визуальным содержимым и структурированными данными RDF.
- Идеальным решением было бы дополнять документ RDF-разметкой без повторения существующих данных.
- Пример: если имя автора указано в тексте (например, в подписи к новости), его не нужно дублировать в RDF — разметка должна позволять интерпретировать существующие данные как часть RDF-структуры.
Преимущества интеграции структуры и содержимого
Контекстная структуризация
- Совмещение визуальных и структурированных данных упрощает передачу информации между приложениями (включая не-веб-системы).
- Пример: пользователи могут получать дополнительную информацию о данных (например, через контекстное меню по клику).
Удобство для издателей
- Организациям, публикующим много контента (например, СМИ), проще встраивать семантические данные напрямую в разметку, чем поддерживать их отдельно.
Ограничения «жёстко заданных» атрибутов
- В традиционных языках разметки (например, XHTML 1.1 [XHTML11] или HTML [HTML401]) используются атрибуты с фиксированной семантикой, такие как
@citeдля указания источника цитаты. - Однако такие атрибуты:
- Требуют от процессоров RDFa знания каждого специфичного атрибута.
- Усложняют создание универсальных инструментов извлечения метаданных.
Решение через RDFa
Гибкость вместо «жёсткой» разметки
- RDFa предлагает универсальный набор атрибутов и правил разбора, позволяющий использовать свойства из любых RDF-словарей.
- В большинстве случаев значения этих свойств уже присутствуют в документе.
Снижение нагрузки на разработчиков языков
- RDFa устраняет необходимость предугадывать все возможные требования пользователей к структуре.
- Дизайнеры языков могут легко интегрировать RDFa, обеспечивая извлечение семантических данных любыми совместимыми процессорами.
Ключевые тезисы
- RDFa избегает дублирования данных, используя существующую разметку.
- Позволяет добавлять произвольные семантические свойства без привязки к конкретному словарю.
- Упрощает создание единого стандарта для извлечения метаданных из любых документов.
6.2.1 - Обзор синтаксиса
Для более глубокого изучения рекомендуется ознакомиться с RDFa Primer.
Сокращённые IRIs (CURIEs)
В RDF принято сокращать термины словарей с помощью префиксов и ссылок. Этот механизм подробно описан в разделе Compact URI Expressions. В примерах ниже используются следующие предопределённые префиксы словарей:
Примечание о локальных идентификаторах
В некоторых примерах используются IRI с фрагментными идентификаторами (например, about="#me"), которые ссылаются на сущности внутри текущего документа. Этот подход:
- Широко применяется в RDF/XML [RDF-SYNTAX-GRAMMAR] и других сериализациях RDF.
- Позволяет легко создавать новые IRIs для объектов, описываемых через RDFa, значительно расширяя выразительные возможности.
Точная семантика таких IRIs в RDF-графах определена в разделе 7 RDF-SYNTAX-GRAMMAR.
Важно
Для корректной интерпретации фрагментных идентификаторов регистрации MIME-типов языков разметки, поддерживающих RDFa, должны ссылаться на эту спецификацию (прямо или косвенно).2.1 Атрибуты RDFa
RDFa использует ряд распространённых атрибутов, а также вводит несколько новых. Атрибуты, уже существующие в популярных языках разметки (например, HTML), сохраняют своё исходное значение, хотя в некоторых случаях их синтаксис был немного модифицирован. Например, в (X)HTML нет чёткого способа добавлять новые значения для атрибута @rel; RDFa явно решает эту проблему, разрешая использовать IRI в качестве значений. Также вводятся понятия терминов и “компактных выражений URI” (CURIEs), которые позволяют кратко выражать полные значения IRI. Полный список атрибутов RDFa и их синтаксис приведён в разделе “Атрибуты и синтаксис”.
2.2 Примеры
В (X)HTML авторы могут включать метаданные и отношения, касающиеся текущего документа, используя элементы meta и link (в этих примерах используется XHTML+RDFa [XHTML-RDFA]). Например, автор страницы вместе со ссылками на предыдущую и следующую страницы могут быть выражены следующим образом:
Пример 1
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Страница 7</title>
<meta name="author" content="Марк Бирбек" />
<link rel="prev" href="page6.html" />
<link rel="next" href="page8.html" />
</head>
<body>...</body>
</html>
RDFa использует эту концепцию, расширяя её возможностью работы с различными словарями через полные IRI:
Пример 2
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Моя домашняя страница</title>
<meta property="http://purl.org/dc/terms/creator" content="Марк Бирбек" />
<link rel="http://xmlns.com/foaf/0.1/topic" href="http://www.example.com/#us" />
</head>
<body>...</body>
</html>
Поскольку использование полных IRI, как в примере выше, может быть громоздким, RDFa также разрешает использовать компактные выражения URI (CURIEs), позволяя авторам применять сокращения для ссылок на термины из различных словарей:
Пример 3
<html
xmlns="http://www.w3.org/1999/xhtml"
prefix="foaf: http://xmlns.com/foaf/0.1/
dc: http://purl.org/dc/terms/"
>
<head>
<title>Моя домашняя страница</title>
<meta property="dc:creator" content="Марк Бирбек" />
<link rel="foaf:topic" href="http://www.example.com/#us" />
</head>
<body>...</body>
</html>
RDFa поддерживает использование @rel и @rev на любых элементах. Это становится ещё полезнее с добавлением поддержки различных словарей:
Пример 4
Этот документ распространяется по лицензии
<a prefix="cc: http://creativecommons.org/ns#"
rel="cc:license"
href="http://creativecommons.org/licenses/by-nc-nd/3.0/"
>Creative Commons By-NC-ND License</a>.
RDFa позволяет повторно использовать не только IRI в документе для предоставления метаданных, но и встроенный текст при использовании с @property:
Пример 5
<html
xmlns="http://www.w3.org/1999/xhtml"
prefix="dc: http://purl.org/dc/terms/"
>
<head><title>Моя домашняя страница</title></head>
<body>
<h1 property="dc:title">Моя домашняя страница</h1>
<p>Последнее изменение: 16 сентября 2015</p>
</body>
</html>
Когда отображаемый текст отличается от фактического значения, можно указать точное значение с помощью атрибута @content. Также можно явно указать тип данных через @datatype:
Пример 6
<html
xmlns="http://www.w3.org/1999/xhtml"
prefix="xsd: http://www.w3.org/2001/XMLSchema#
dc: http://purl.org/dc/terms/"
>
<head><title>Моя домашняя страница</title></head>
<body>
<h1 property="dc:title">Моя домашняя страница</h1>
<p>Последнее изменение:
<span property="dc:modified"
content="2015-09-16T16:00:00-05:00"
datatype="xsd:dateTime">16 сентября 2015</span>.
</p>
</body>
</html>
RDFa позволяет описывать метаданные не только для текущего документа, но и для других ресурсов:
Пример 7
<html
xmlns="http://www.w3.org/1999/xhtml"
prefix="bibo: http://purl.org/ontology/bibo/
dc: http://purl.org/dc/terms/"
>
<head>
<title>Книги Марко Пьера Уайта</title>
</head>
<body>
Я считаю, что книга Уайта
«<span about="urn:ISBN:0091808189"
property="dc:title">Кухня столовой</span>»
стоит того, чтобы её приобрести: хотя рецепты сложные,
автор объясняет их очень доступно. Вам также может понравиться
<span about="urn:ISBN:1596913614"
property="dc:description">автобиография Уайта</span>.
</body>
</html>
Для группировки свойств, относящихся к одному объекту, используется атрибут @typeof:
Пример 8
<html
xmlns="http://www.w3.org/1999/xhtml"
prefix="bibo: http://purl.org/ontology/bibo/
dc: http://purl.org/dc/terms/"
>
<head>
<title>Книги Марко Пьера Уайта</title>
</head>
<body>
Я считаю, что книга Уайта
«<span about="urn:ISBN:0091808189" typeof="bibo:Book"
property="dc:title">Кухня столовой</span>»
стоит того, чтобы её приобрести. Также рекомендую
<span about="urn:ISBN:1596913614"
typeof="bibo:Book"
property="dc:description"
>автобиографию Уайта</span>.
</body>
</html>
Для небольших фрагментов разметки иногда удобнее использовать полные IRI:
Пример 9
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Книги Марко Пьера Уайта</title>
</head>
<body>
Книга Уайта
«<span about="urn:ISBN:0091808189"
typeof="http://purl.org/ontology/bibo/Book"
property="http://purl.org/dc/terms/title"
>Кухня столовой</span>»
написана очень доступно. Также обратите внимание на
<span about="urn:ISBN:1596913614"
typeof="http://purl.org/ontology/bibo/Book"
property="http://purl.org/dc/terms/description"
>его автобиографию</span>.
</body>
</html>
Атрибут @vocab позволяет определить словарь по умолчанию для элементов:
Пример 10
<div vocab="http://xmlns.com/foaf/0.1/" about="#me">
Меня зовут <span property="name">Иван Иванов</span>, а мой блог —
<a rel="homepage" href="http://example.org/blog/">«Понимая семантику»</a>.
</div>
Приведённый выше пример (Пример 10) сгенерирует следующие триплеты в формате Turtle:
Пример 11
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
<#me> foaf:name "John Doe" ;
foaf:homepage <http://example.org/blog/> .
В простых случаях атрибут @property может использоваться вместо @rel. Фактически, когда элемент не содержит атрибутов @rel, @datatype или @content, но имеет, например, атрибут @href, эффект от @property аналогичен @rel.
Тот же пример можно переписать следующим образом:
Пример 12
<div vocab="http://xmlns.com/foaf/0.1/" about="#me">
Меня зовут <span property="name">Иван Иванов</span>, а мой блог —
<a property="homepage" href="http://example.org/blog/">«Понимая семантику»</a>.
</div>
Особенности обработки:
- Когда используется только @property с элементом, содержащим @href, система интерпретирует это как отношение (аналогично @rel)
- Такой подход упрощает разметку в случаях, когда не требуется явное указание типа связи
Это демонстрирует гибкость RDFa в интерпретации различных вариантов разметки как семантически эквивалентных структур.
6.2.2 - Терминология RDF
3. Терминология RDF
Введение
Предыдущий раздел иллюстрировал типичную разметку RDFa. Хотя для создания RDFa-разметки глубокое понимание RDF не обязательно, разработчикам систем, обрабатывающих RDF-вывод, необходимо разбираться в концепциях RDF. Далее представлены базовые понятия. Для углублённого изучения обратитесь к:
3.1 Утверждения (Statements)
Структурированные данные в RDFa представляют собой коллекцию утверждений — минимальных единиц информации, оформленных по определённым правилам для упрощения обработки. Даже сложные метаданные можно обрабатывать, разбивая их на такие утверждения.
Пример неструктурированных данных:
Альберт родился 14 марта 1879 года в Германской империи. Его фото доступно
по адресу http://en.wikipedia.org/wiki/Image:Albert_Einstein_Head.jpg.
Для машины этот текст неинтерпретируем. В формате утверждений та же информация выглядит так:
Альберт родился 14 марта 1879 года
Альберт родился в Германской империи
Альберт имеет фото http://en.wikipedia.org/...
3.2 Триплеты (Triples)
RDF формализует утверждения как триплеты — структуры из трёх компонентов:
Субъект (Subject)
- Объект, о котором делается утверждение.
- В примерах: «Альберт».
Предикат (Predicate)
- Свойство субъекта.
- В примерах: «родился», «имеет фото».
Объект (Object)
- Значение свойства.
- В примерах: дата, место, URL фото.
Пример триплетов в RDF:
<Albert> <wasBornOn> "March 14, 1879" .
<Albert> <wasBornIn> <German_Empire> .
<Albert> <hasPhoto> <http://.../Albert_Einstein_Head.jpg> .
Особенности:
- RDFa поддерживает интернационализированные символы (Unicode) во всех компонентах триплета.
- Субъекты и предикаты обычно выражаются IRI, объекты — IRI или литералы (строки/числа).
3.3 Ссылки на IRI
Разбиение сложной информации на управляемые части помогает уточнить данные, но не исключает неоднозначности. Например, о каком именно “Альберте” идёт речь? Если другая система содержит дополнительные факты об “Альберте”, как определить, что они относятся к тому же человеку? Как сопоставить предикаты “родился в” и “место рождения” из разных систем? RDF решает эти проблемы, заменяя расплывчатые термины на ссылки IRI.
Уникальные идентификаторы
Хотя IRI чаще всего используются для идентификации веб-страниц, в RDF они служат уникальными идентификаторами концепций. Например, вместо неоднозначной строки “Альберт” можно использовать IRI из DBPedia:
Пример 15
<http://dbpedia.org/resource/Albert_Einstein>
имеет имя
"Альберт Эйнштейн".
<http://dbpedia.org/resource/Albert_Einstein>
родился
"14 марта 1879".
<http://dbpedia.org/resource/Albert_Einstein>
родился в
<http://dbpedia.org/resource/German_Empire>.
<http://dbpedia.org/resource/Albert_Einstein>
имеет фотографию
<http://.../Albert_Einstein_Head.jpg>.
Идентификация объектов
IRI также используются для однозначного определения объектов (третья часть триплета). Фотография уже имеет IRI, но можно аналогично идентифицировать и “Германскую империю”. Строковые значения (литералы) выделяются кавычками:
Пример 16
<http://dbpedia.org/resource/Albert_Einstein>
<http://xmlns.com/foaf/0.1/name>
"Альберт Эйнштейн".
<http://dbpedia.org/resource/Albert_Einstein>
<http://dbpedia.org/property/dateOfBirth>
"14 марта 1879".
Унификация предикатов
IRI устраняют неоднозначность предикатов, объединяя синонимы (“место рождения”, “birthplace”, “Lieu de naissance”) под одним идентификатором:
Пример 17
<http://dbpedia.org/resource/Albert_Einstein>
<http://dbpedia.org/property/birthPlace>
<http://dbpedia.org/resource/German_Empire>.
Ключевые преимущества:
- Устранение неоднозначностей — IRI точно идентифицируют сущности
- Межсистемная совместимость — разные источники могут ссылаться на одни и те же концепции
- Поддержка многоязычия — один IRI может представлять понятие на любом языке
Особенности реализации:
- Литералы (строки, числа) всегда заключаются в кавычки
- Веб-адреса (URL) и другие IRI обрамляются угловыми скобками
- Использование общепринятых словарей (FOAF, DBpedia) улучшает связанность данных
3.4 Простые литералы (Plain Literals)
Хотя для субъектов и предикатов всегда используются IRI-идентификаторы, объект в триплете может быть как IRI, так и литералом. В примерах имя Эйнштейна представлено простым литералом — строкой без указания типа или языка:
Пример 18
<http://dbpedia.org/resource/Albert_Einstein>
<http://xmlns.com/foaf/0.1/name> "Альберт Эйнштейн".
Литералы с указанием языка
Для текстов на естественных языках используется тег языка. Например, название Германской империи на разных языках:
Пример 19
<http://dbpedia.org/resource/German_Empire>
rdfs:label "German Empire"@en;
rdfs:label "Deutsches Kaiserreich"@de;
rdfs:label "Германская империя"@ru.
3.5 Типизированные литералы (Typed Literals)
Для специальных значений (даты, числа и т.д.) в RDF предусмотрен механизм указания типа литерала. Типизированный литерал формируется путём добавления IRI типа данных после литерала с использованием символов ^^. Обычно используются типы данных из спецификации XML Schema:
Пример 20
<http://dbpedia.org/resource/Albert_Einstein>
<http://dbpedia.org/property/dateOfBirth>
"1879-03-14"^^<http://www.w3.org/2001/XMLSchema#date>.
Ключевые особенности:
Строковые литералы
- Простые текстовые значения без дополнительной информации
- Могут включать указание языка (
@"ru")
Типизированные значения
- Числа:
"42"^^xsd:integer - Даты:
"2023-05-15"^^xsd:date - Логические значения:
"true"^^xsd:boolean
- Числа:
Стандартные типы данных
- Используются XSD-типы (
xsd:string,xsd:dateTimeи др.) - Позволяют однозначно интерпретировать значения
- Используются XSD-типы (
Практическое применение:
# Числовое значение
<http://example.org/product/123>
ex:weight "2.5"^^xsd:decimal.
# Дата и время
ex:event ex:startTime "2023-05-15T19:00:00"^^xsd:dateTime.
# Булево значение
ex:user ex:isActive "true"^^xsd:boolean.
3.6 Turtle (Синтаксис Turtle)
RDF не имеет единого обязательного формата представления триплетов, поскольку ключевыми концепциями являются сами триплеты и использование IRI, а не конкретный синтаксис. Однако существует несколько способов выражения триплетов, включая RDF/XML, Turtle и, конечно, RDFa. В документации часто используется синтаксис Turtle благодаря его компактности.
Пример с префиксами:
@prefix dbp: <http://dbpedia.org/property/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
<http://dbpedia.org/resource/Albert_Einstein>
foaf:name "Альберт Эйнштейн" .
<http://dbpedia.org/resource/Albert_Einstein>
dbp:birthPlace <http://dbpedia.org/resource/German_Empire> .
Расширенный пример:
@prefix dbr: <http://dbpedia.org/resource/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
dbr:Albert_Einstein
foaf:name "Альберт Эйнштейн";
dbp:dateOfBirth "1879-03-14"^^xsd:date;
foaf:depiction <http://example.org/einstein.jpg> .
Специальные обозначения:
<>- обозначает текущий обрабатываемый документ- Префиксы используются только для удобства записи, в итоговых триплетах всегда полные IRI
3.7 Графы
Совокупность триплетов называется графом. Все триплеты, генерируемые согласно этой спецификации, содержатся в выходном графе, создаваемом процессором RDFa.
3.8 Компактные выражения URI (CURIEs)
Для сокращённой записи IRI в разметке RDFa использует механизм CURIEs. Подробное описание - в разделе “Обработка CURIE и IRI”.
Важно: CURIEs используются только в разметке и примерах, в итоговых триплетах всегда присутствуют полные IRI.
3.9 Фрагменты разметки и RDFa
При переносе фрагментов разметки между документами (например, через копирование или инструменты) следует учитывать:
- Обработка изолированных фрагментов вне контекста полного документа не определена
- Разработчикам инструментов следует предусматривать передачу необходимого контекста
- Авторам фрагментов нужно учитывать их поведение в составе полного документа
3.10 Описание RDFa в терминах RDF
Краткое соответствие между RDFa и RDF:
| Компонент RDF | Эквивалент в RDFa |
|---|---|
| Субъект | @about |
| Предикат | @property, @rel, @rev |
| Объект (IRI) | @resource, @href, @src |
| Объект (литерал) | @content или содержимое элемента |
| Тип данных | @datatype |
| Язык | @xml:lang или аналоги |
Пример соответствия:
<div about="#albert"
property="foaf:name"
content="Альберт Эйнштейн"
datatype="xsd:string">
Генерируемый триплет:
<http://example.org/doc#albert>
<http://xmlns.com/foaf/0.1/name>
"Альберт Эйнштейн"^^xsd:string .
6.2.3 - Соответствие в RDF
Ключевые слова MAY (может), MUST (должен), MUST NOT (не должен), RECOMMENDED (рекомендуется), SHOULD (следует) и SHOULD NOT (не следует) должны интерпретироваться в соответствии с [RFC2119].
4.1 Соответствие процессора RDFa
В данной спецификации термин выходной граф означает все триплеты, утвержденные документом в соответствии с разделом Модель обработки. Соответствующий требованиям процессор RDFa ДОЛЖЕН предоставить потребляющему приложению единый RDF-граф, содержащий все возможные триплеты, сгенерированные с использованием правил из раздела Модель обработки. Термин граф процессора используется для обозначения всех информационных, предупреждающих и ошибочных триплетов, которые МОГУТ быть сгенерированы процессором RDFa для отчета о своем состоянии. Выходной граф и граф процессора являются отдельными графами, и процессор RDFa НЕ ДОЛЖЕН хранить их в одном графе. Однако процессоры могут разрешать одновременное получение обоих графов; подробности см. в разделе 7.6.1.
Соответствующий требованиям процессор RDFa МОЖЕТ предоставлять дополнительные триплеты, сгенерированные с использованием правил, не описанных здесь, но эти триплеты НЕ ДОЛЖНЫ включаться в выходной граф. (Будут ли эти дополнительные триплеты доступны в одном или нескольких дополнительных RDF-графах, зависит от реализации и здесь не определяется.)
Соответствующий требованиям процессор RDFa ДОЛЖЕН сохранять пробельные символы как в простых литералах, так и в XML-литералах. Однако может случиться так, что архитектура, в которой работает процессор, изменила пробельные символы в документе до того, как он попал в процессор RDFa (например, процессоры [XMLSCHEMA11-1] могут «нормализовать» пробелы в значениях атрибутов — см. раздел 3.1.4). Чтобы обеспечить максимальную согласованность между средами обработки, авторам СЛЕДУЕТ удалять все избыточные пробелы в своих простых и XML-литералах.
Соответствующий требованиям процессор RDFa ДОЛЖЕН анализировать медиатип документа, который он обрабатывает, чтобы определить его язык-хост. Если процессор RDFa не может определить медиатип или не поддерживает его, он ДОЛЖЕН обрабатывать документ так, как если бы его медиатип был application/xml. См. Соответствие документов XML+RDFa. Язык-хост МОЖЕТ определять дополнительные механизмы объявления.
Примечание
Соответствующий требованиям процессор RDFa МОЖЕТ использовать дополнительные механизмы (например,DOCTYPE, расширение файла, корневой элемент, переопределяемый пользовательский параметр) для определения языка-хоста, если медиатип недоступен. Эти механизмы не регламентируются.4.2 Соответствие языка-хоста RDFa
Языки-хосты, включающие RDFa, должны соответствовать следующим требованиям:
- Все функции, требуемые в данной спецификации, ДОЛЖНЫ быть включены в язык-хост.
- Обязательные атрибуты, определенные в данной спецификации, ДОЛЖНЫ быть включены в модель содержимого языка-хоста.
Примечание
Во избежание сомнений, нет требования, чтобы атрибуты, такие как@href и @src, использовались в соответствующем языке-хостe. Также нет требования, чтобы все обязательные атрибуты были включены в модель содержимого всех элементов. Рабочая группа рекомендует разработчикам языков-хостов обеспечивать включение обязательных атрибутов в модель содержимого элементов, которые часто используются в языке.- Если язык-хост использует пространства имен XML [XML-NAMES], атрибуты из этой спецификации СЛЕДУЕТ определять «без пространства имен» (например, когда атрибуты используются на элементах в пространстве имен языка-хоста, они могут применяться без префикса:
<myml:myElement property="license">). Если язык-хост не использует атрибуты «без пространства имен», они ДОЛЖНЫ ссылаться на пространство имен XHTML (http://www.w3.org/1999/xhtml). - Если язык-хост имеет собственное определение для любого атрибута, описанного в данной спецификации, это определение ДОЛЖНО обеспечивать возможность обработки, требуемой данной спецификацией, когда атрибут используется в соответствии с ее требованиями.
- Язык-хост МОЖЕТ определять начальный контекст (например, IRI-отображения и/или определение терминов или IRI словаря по умолчанию). Такой начальный контекст СЛЕДУЕТ определять с использованием соглашений, описанных в Начальные контексты RDFa.
4.3 Соответствие документов XML+RDFa
Данная спецификация не определяет самостоятельный тип документа. Атрибуты здесь предназначены для интеграции в другие языки-хосты (например, HTML+RDFa или XHTML+RDFa). Однако данная спецификация определяет правила обработки для общих XML-документов — то есть документов, доставляемых с медиатипами text/xml или application/xml. Такие документы должны соответствовать всем следующим критериям:
- Документ ДОЛЖЕН быть корректно сформированным, как определено в [XML10-4e].
- Документ СЛЕДУЕТ использовать атрибуты, определенные в данной спецификации, «без пространства имен» (например,
<myml:myElement property="license">).
Примечание
Возможно, что XML-грамматика будет иметь собственные атрибуты, конфликтующие с атрибутами из этой спецификации. Это может привести к тому, что процессор RDFa сгенерирует неожиданные триплеты.- Существуют термины по умолчанию (например,
describedby,license,role), определенные вhttp://www.w3.org/2011/rdfa-context/rdfa-1.1. - Существуют префиксные отображения по умолчанию (например,
dc), определенные вhttp://www.w3.org/2011/rdfa-context/rdfa-1.1. - Нет IRI словаря по умолчанию.
- База может быть установлена с помощью атрибута
@xml:base, как определено в [XML10-4e]. - Текущий язык может быть установлен с помощью атрибута
@xml:lang.
6.2.4 - Аттрибуты и синтаксис в RDF
Атрибуты:
aboutSafeCURIEorCURIEorIRI— указывает, о чем именно представлены данные («субъект» в терминологии RDF).contentCDATA-строка — предоставляет машиночитаемое содержимое для литерала («литеральный объект» в терминологии RDF).datatypeTERMorCURIEorAbsIRI— определяет тип данных литерала.href(опциональный)
Традиционно навигационный IRI — выражает связанный ресурс отношения («ресурсный объект» в терминологии RDF).inlist
Атрибут, указывающий, что объект, связанный с атрибутамиrelилиpropertyна том же элементе, должен быть добавлен в список для данного предиката. Значение этого атрибута ДОЛЖНО игнорироваться. Наличие атрибута приводит к созданию списка, если он ещё не существует.prefix
Список пар «префикс : IRI», разделенных пробелами, в формате:NCName ':' ' '+ xsd:anyURIproperty
СписокTERMorCURIEorAbsIRI, разделенных пробелами, — выражает отношения между субъектом и либо ресурсным объектом (если указан), либо текстовым литералом («предикат»).rel
СписокTERMorCURIEorAbsIRI, разделенных пробелами, — выражает отношения между двумя ресурсами («предикаты» в терминологии RDF).resourceSafeCURIEorCURIEorIRI— выражает связанный ресурс отношения, не предназначенный для навигации (например, не «кликабельная» ссылка) («объект»).rev
СписокTERMorCURIEorAbsIRI, разделенных пробелами, — выражает обратные отношения между двумя ресурсами («предикаты»).src(опциональный)
IRI — выражает связанный ресурс отношения, когда ресурс встроен («ресурсный объект»).typeof
СписокTERMorCURIEorAbsIRI, разделенных пробелами, — указывает RDF-тип(ы), связываемые с субъектом.vocab
IRI — определяет отображение, используемое при ссылке на термин в значении атрибута. См. Общее использование терминов в атрибутах и раздел Расширение словаря.
Примечание
Во всех случаях возможно использование этих атрибутов без значения (например, @datatype="") или со значением, которое после обработки по правилам CURIE и IRI становится пустым (например, @datatype="[noprefix:foobar]").
5.1 Роли атрибутов
Атрибуты RDFa выполняют разные роли в семантически насыщенном документе. Вкратце:
- Синтаксические атрибуты:
@prefix,@vocab. - Атрибуты субъекта:
@about. - Атрибуты предиката:
@property,@rel,@rev. - Атрибуты ресурса:
@resource,@href,@src. - Атрибуты литерала:
@datatype,@content,@xml:langили@lang. - Макроатрибуты:
@typeof,@inlist.
5.2 Пробелы в значениях атрибутов
Многие атрибуты принимают список токенов, разделенных пробелами. В данной спецификации пробел определяется как:
whitespace ::= (#x20 | #x9 | #xD | #xA)+
Если атрибут принимает список токенов, разделенных пробелами, процессор RDFa ДОЛЖЕН игнорировать любые ведущие или завершающие пробелы.
Примечание
Это определение согласуется с определением из [XML10].6.2.5 - Определение синтаксиса CURIE в RDF
6. Определение синтаксиса CURIE
Примечание
Рабочая группа в настоящее время анализирует приведённые ниже правила формирования CURIE с учётом недавних замечаний от RDF Working Group и участников RDFa Working Group. Возможны незначительные изменения в правилах в ближайшем будущем, которые могут оказаться обратно несовместимыми. Однако любые такие несовместимости будут ограничены крайними случаями.
Основные положения
Ключевым компонентом RDF является IRI, но такие идентификаторы обычно длинные и неудобные. Поэтому RDFa поддерживает механизм сокращения IRI, называемый компактными URI-выражениями (CURIE).
При раскрытии CURIE ДОЛЖЕН получаться синтаксически корректный IRI ([RFC3987]). Подробнее см. Обработка CURIE и IRI. Лексическое пространство CURIE определяется правилом curie, приведённым ниже. Пространство значений — это множество IRI.
CURIE состоит из двух компонентов: префикса и ссылки. Префикс отделяется от ссылки двоеточием (:). В общем случае префикс можно опустить, создав CURIE, использующий отображение префикса по умолчанию. В RDFa отображение префикса по умолчанию — http://www.w3.org/1999/xhtml/vocab#. Также можно опустить и префикс, и двоеточие, создав CURIE, содержащий только ссылку, использующую отображение без префикса. Данная спецификация НЕ определяет отображение без префикса. Языки-хосты RDFa НЕ ДОЛЖНЫ определять отображение без префикса.
Примечание
Префикс по умолчанию в RDFa не следует путать с пространством имён по умолчанию, определённым в [XML-NAMES]. Процессор RDFa НЕ ДОЛЖЕН обрабатывать объявление пространства имён по умолчанию в XML-NAMES так, как если бы оно устанавливало префикс по умолчанию.
Общий синтаксис CURIE
Синтаксис CURIE можно описать следующим образом:
prefix ::= NCName
reference ::= ( ipath-absolute / ipath-rootless / ipath-empty )
[ "?" iquery ] [ "#" ifragment ] (как определено в [[!RFC3987]])
curie ::= [ [ prefix ] ':' ] reference
safe_curie ::= '[' [ [ prefix ] ':' ] reference ']'
Примечание
Правилоsafe_curie не является обязательным, даже в ситуациях, когда значение атрибута может быть CURIE или IRI: IRI, использующий схему, не соответствующую текущим отображениям, нельзя спутать с CURIE. Концепция safe_curie сохранена для обратной совместимости.Примечание
Можно определить отображение префикса CURIE таким образом, что оно «перекроет» определённую схему IRI. Например, документ может сопоставить префиксmailto с http://www.example.com/addresses/. Тогда атрибут @resource со значением mailto:user@example.com может создать триплет с объектом http://www.example.com/addresses/user@example.com. Более того, возможно (хотя и маловероятно), что в будущем появятся схемы, конфликтующие с отображениями префиксов в документе (например, предлагаемая схема widget [WIDGETS-URI]). В обоих случаях такое «перекрытие» не изменит способ обработки IRI другими потребителями, но может привести к неверной интерпретации CURIE автора документа. Рабочая группа считает этот риск минимальным.Контекст обработки CURIE
При обычной обработке CURIE требуется следующая контекстная информация:
- Набор отображений префиксов в IRI.
- Отображение для префикса по умолчанию (например,
:p). - Отображение для случая без префикса (например,
p). - Отображение для префикса
_, который используется для генерации уникальных идентификаторов (например,_:p).
В RDFa эти значения определяются следующим образом:
- Набор отображений префиксов в IRI предоставляется текущими активными объявлениями префиксов элемента во время разбора.
- Отображение для префикса по умолчанию — текущее отображение префикса по умолчанию.
- Отображение для случая без префикса НЕ определено.
- Отображение для префикса
_не указано явно, но, поскольку он используется для генерации blank nodes, его реализация должна быть совместима с определением RDF и правилами из Ссылки на Blank Nodes. Документ НЕ ДОЛЖЕН определять отображение для префикса_. Соответствующий требованиям процессор RDFa ДОЛЖЕН игнорировать любые определения отображений для префикса_.
Правила преобразования CURIE в IRI
CURIE представляет собой полный IRI. Правила его определения:
- Если CURIE состоит из пустого префикса и ссылки, IRI получается путём конкатенации текущего отображения префикса по умолчанию и ссылки. Если отображение префикса по умолчанию отсутствует, CURIE считается невалидным и ДОЛЖЕН игнорироваться.
- Если CURIE состоит из непустого префикса и ссылки, и для префикса существует активное отображение (сравнение без учёта регистра), то IRI создаётся путём конкатенации этого отображения и ссылки.
- Если для префикса нет активного отображения, значение не является валидным CURIE.
Примечание
См. Общее использование терминов в атрибутах для случаев, когда элементы без двоеточия могут интерпретироваться процессорами RDFa в некоторых типах данных.6.1 Почему CURIE, а не QNames?
(Этот раздел является не нормативным.)
Во многих случаях разработчики языков пытались использовать QNames в качестве механизма расширения [XMLSCHEMA11-2]. QNames действительно позволяют управлять коллекцией имён независимо и могут сопоставлять имена с ресурсами. Однако QNames в большинстве случаев не подходят, потому что:
- Использование QName в качестве идентификаторов в значениях атрибутов и содержимом элементов проблематично, как обсуждается в [QNAMES].
- Синтаксис QNames избыточно строг и не позволяет выразить все возможные IRI.
Пример проблемы: попытка определить коллекцию имён для книг. В QName часть после двоеточия должна быть валидным именем элемента, что делает следующий пример недопустимым:
isbn:0321154991
Это невалидный QName, потому что 0321154991 не является допустимым именем элемента. Однако в данном случае нам и не нужно определять валидное имя элемента — цель использования QName заключалась в ссылке на элемент в частной области видимости (ISBN). Более того, мы хотим, чтобы имена в этой области видимости сопоставлялись с IRI, раскрывающим смысл ISBN. Как видно, определение QNames противоречит этому (довольно распространённому) сценарию.
Данная спецификация решает проблему, вводя CURIE. Синтаксически CURIE являются надмножеством QNames.
Важно
Эта спецификация предназначена для разработчиков языков, а не авторов документов. Любой разработчик языка, рассматривающий использование QNames для представления IRI или уникальных токенов, должен вместо этого рассмотреть CURIE:
- CURIE изначально разработаны для использования в значениях атрибутов. QNames предназначены для однозначного именования элементов и атрибутов.
- CURIE раскрываются в IRI, и любой IRI может быть представлен таким образом. QNames обрабатываются как пары значений, но даже если их объединить в строку, можно представить только подмножество IRI.
- CURIE можно использовать в не-XML грамматиках и даже в XML-языках, не поддерживающих XML Namespaces. QNames ограничены XML-приложениями с поддержкой XML Namespaces.
7 - Latex
Сам по себе TEX представляет собой специализированный язык программирования (Кнут не только придумал язык, но и написал для него транслятор, причем таким образом, что он работает совершенно одинаково на самых разных компьютерах), на котором пишутся издательские системы, используемые на практике.
Точнее говоря, каждая издательская система на базе TEX’а представляет собой пакет макроопределений (макропакет) этого языка.
«LaTeX») — это созданная Лесли Лэмпортом (Leslie Lamport) издательская система на базе TEX’а.
7.1 - Библиотека цветных блоков и рамок tcolorbox для Latex
Официальное описание пакета по адресу: https://ctan.org/pkg/tcolorbox
tcolorbox – Цветные рамки для примеров и теорем в LaTeX и т. д.
Этот пакет предоставляет среду для цветных текстовых рамок с заголовком. По желанию, такая рамка может быть разделена на верхнюю и нижнюю части; таким образом, пакет может быть использован для настройки примеров LaTeX, где одна часть рамки отображает исходный код, а другая часть показывает результат. Другой распространенный случай использования – настройка теорем. Пакет поддерживает сохранение и повторное использование исходного кода и частей текста.
Пакет зависит от пакетов pgf, verbatim, environ и etoolbox.

Пример обложки документации
\documentclass[a4paper]{article}
\usepackage{tikz}
\usepackage[all]{tcolorbox}
\usepackage{incgraph}
\usepackage{lipsum}
\usepackage{accsupp}
\begin{document}
\begin{inctext}
\begin{tikzpicture}
\definecolorseries{boxcol}{rgb}{last}{blue}{red}
\resetcolorseries[28]{boxcol}
\coordinate (A) at (0,0); \coordinate (B) at (21,29.7);
\path[use as bounding box] (A) rectangle coordinate (C) (B);
\node[transform shape,xslant=0.7,rotate=-10,xshift=0cm] at (C) {%
\BeginAccSupp{method=plain,ActualText={}}%
\begin{tcbraster}[raster columns=4,title=tcolorbox,
fonttitle=\small\bfseries,raster width=50cm]
\foreach \b in {1,...,28} {\begin{tcolorbox}[enhanced,
watermark text=\thetcbrasternum,
colframe=boxcol!30!white,
colback=boxcol!25!white!30!white,
colbacktitle=boxcol!!+!50!black!30!white,
colupper=black!30!white]\lipsum[2]\end{tcolorbox}}
\end{tcbraster}%
\EndAccSupp{}%
};
\node at (C) {%
\begin{tcbitemize}[title=tcolorbox ,fonttitle=\small\bfseries,
enhanced jigsaw,opacityback=0.5,opacitybacktitle=0.75,
halign=center,valign=center,arc=5mm,
raster width=16cm,raster column skip=8mm,raster halign=center,
raster force size=false,
raster row 1/.style={height=6cm},
raster row 2/.style={width=6cm,height=4cm},
raster column 1/.style={flushright title,
frame style={left color=yellow!50!black,right color=green!50!black},
title style={left color=yellow!50!blue,right color=blue!50!green!50!black},
interior style={left color=yellow!70,right color=green!70},
underlay={\draw[line width=6mm,line cap=round,black!60]
([shift={(0.4,-0.15)}]frame.north east)
--([shift={(0.4,0.15)}]frame.south east); }},
raster column 2/.style={
frame style={left color=green!50!black,right color=yellow!50!black},
title style={left color=blue!50!green!50!black,right color=yellow!50!blue},
interior style={left color=green!70,right color=yellow!70}}]
\tcbitem[fontupper=\Huge\bfseries,sharp corners=east,
underlay={\draw[line width=6mm,line cap=round,black!60]
([shift={(0.4,0.30)}]frame.north east)-- coordinate(A) +(0,0.2);
\draw[line width=1mm,line cap=round,black!60](A) -- +(30:1.5cm);
\draw[line width=1mm,line cap=round,black!60](A) -- +(150:1.5cm);}]
tcolorbox
\tcbitem[fontupper=\large\bfseries,sharp corners=west]
Manual for
\tcbitem[sharp corners=northeast]
\tcbitem[sharp corners=northwest] Thomas F.~Sturm
\end{tcbitemize}%
};
\end{tikzpicture}
\end{inctext}
\end{document}
Установка пакета
\usepackage{tcolorbox}
Пакет принимает ключи опций в синтаксисе “ключ-значение”. В качестве альтернативы вы можете использовать эти ключи позже в преамбуле с помощью команды \tcbuselibrary.
\tcbuselibrary{⟨key list⟩}
Вот перевод на русский язык с примерами, обернутыми в latex:
Следующие ключи используются внутри \tcbuselibrary соответственно \usepackage без ключа:
tree path
/tcb/library/./tcb/library/skins (LIB skins)
Загружает пакетtikzfill.image→ CTAN и предоставляет дополнительные стили (skins) для внешнего вида цветных коробок;\tcbuselibrary{skins}/tcb/library/vignette (LIB vignette)
Предоставляет код для более орнаментального оформления;\tcbuselibrary{vignette}/tcb/library/raster (LIB raster)
Предоставляет дополнительные макросы и опции для наборки нескольких коробок, расположенных в виде растровой сетки;\tcbuselibrary{raster}/tcb/library/listings (LIB listings)
Загружает пакетlistings→ CTAN и предоставляет дополнительные макросы для наборки листингов\tcbuselibrary{listings}/tcb/library/listingsutf8 (LIB listingsutf8)
Загружает пакетыlistings→ CTAN иlistingsutf8для поддержки UTF-8.\tcbuselibrary{listingsutf8}/tcb/library/minted (LIB minted)
Загружает пакетminted→ CTAN для наборки листингов с помощью инструмента Pygments;\tcbuselibrary{minted}/tcb/library/theorems (LIB theorems)
Предоставляет дополнительные макросы для наборки теорем\tcbuselibrary{theorems}/tcb/library/breakable (LIB breakable)
Предоставляет поддержку автоматического разбиения коробок с одной страницы на другую;\tcbuselibrary{breakable}/tcb/library/magazine (LIB magazine)
Предоставляет поддержку для хранения частей разбитых коробок для последующего использования или в измененном порядке;\tcbuselibrary{magazine}/tcb/library/poster (LIB poster)
Предоставляет поддержку для создания постеров;\tcbuselibrary{poster}/tcb/library/fitting (LIB fitting)
Предоставляет поддержку адаптации размера шрифта содержимого коробки к размерам коробки;\tcbuselibrary{fitting}/tcb/library/hooks (LIB hooks)
Расширяет несколько опций до “hookable” ключей;\tcbuselibrary{hooks}/tcb/library/xparse (LIB xparse)
Загружает пакетxparse→ CTAN и считается устаревшей библиотекой, сохраненной для совместимости;\tcbuselibrary{xparse}/tcb/library/external (LIB external)
Предоставляет поддержку экстернализации для фрагментов документов, которые могут быть самостоятельными;\tcbuselibrary{external}/tcb/library/documentation (LIB documentation)
Предоставляет дополнительные макросы для наборки документации LATEX

Основные параметры рамок tcolorbox


Создание рамок
Команды tcolorbox и \tcbox
\begin{tcolorbox}
This is a \textbf{tcolorbox}.
\end{tcolorbox}
\begin{tcolorbox}[colback=red!5!white,colframe=red!75!black,title=My nice heading]
This is another \textbf{tcolorbox}.
\tcblower %разделитель бокса
Here, you see the lower part of the box.
\end{tcolorbox}

\tcblower
Используется внутри tcolorbox для разделения верхней части коробки от необязательной нижней части коробки. Верхняя и нижняя части рассматриваются как отдельные функциональные единицы. Если вы хотите просто провести линию, используйте \tcbline.
Пример использования:
\begin{tcolorbox}
Верхняя часть коробки.
\tcblower
Нижняя часть коробки.
\end{tcolorbox}
\tcbset{⟨options⟩}
Устанавливает параметры для всех последующих tcolorbox внутри текущей группы TEX. По умолчанию это не применяется к вложенным коробкам.
Например, цвета коробок могут быть определены для всего документа следующим образом:
\tcbset{colback=red!5!white, colframe=red!75!black}
После этого все последующие tcolorbox будут использовать указанные цвета фона и рамки.
\tcbsetforeverylayer{⟨options⟩}
Устанавливает параметры для всех последующих tcolorbox внутри текущей группы TEX. В отличие от \tcbset, это также применяется к вложенным коробкам. Технически, параметры ⟨options⟩ добавляются к значениям по умолчанию для каждой tcolorbox, которые применяются с помощью /tcb/reset
Не следует использовать этот макрос, если вы не уверены, что хотите применять ⟨options⟩ также для коробок в коробках (в коробках в коробках и т.д.).
Пример использования:
\tcbset{colback=green!10!white}
\tcbsetforeverylayer{colframe=red!75!black}
В этом примере все последующие tcolorbox будут иметь зеленый фон и красную рамку, включая вложенные коробки.
\tcbox[⟨options⟩]{⟨box content⟩}
Создает цветную коробку, которая подгоняется по ширине к заданному содержимому ⟨box content⟩. В принципе, большинство ⟨options⟩ для tcolorbox могут быть использованы для \tcbox с некоторыми ограничениями. \tcbox не может иметь нижнюю часть и не может быть разбита.
Пример использования:
\tcbox[colback=blue!10!white, colframe=blue!75!black]{Это содержимое цветной коробки.}
В этом примере создается цветная коробка с заданным фоном и рамкой, подгоняющаяся по ширине к тексту внутри.
\tcboxverb[⟨options⟩]{⟨verbatim box content⟩}
Создает цветную коробку на основе \tcbox, которая подгоняется по ширине к заданному содержимому ⟨verbatim box content⟩. Основная \tcbox стилизована с помощью /tcb/verbatim плюс заданные ⟨options⟩. Разница с \tcbox заключается в том, что ⟨verbatim box content⟩ интерпретируется как текст без форматирования. Поэтому \tcboxverb действует аналогично \verb.
Пример использования:
\tcboxverb[colback=yellow!10!white, colframe=yellow!75!black]{\texttt{Это содержимое в verbatim-формате.}}
В этом примере создается цветная коробка с заданным фоном и рамкой, подгоняющаяся по ширине к тексту, который интерпретируется без форматирования.
Создание окружений и команд tcolorbox
\newtcolorbox[⟨init options⟩]{⟨name⟩}[⟨number⟩][⟨default⟩]{⟨options⟩}
Создает новое окружение ⟨name⟩ на основе tcolorbox. В принципе, \newtcolorbox работает как \newenvironment. Это означает, что новое окружение ⟨name⟩ может принимать ⟨number⟩ аргументов, где ⟨default⟩ — это значение по умолчанию для необязательного первого аргумента. Параметры ⟨options⟩ передаются основной tcolorbox. Обратите внимание, что /tcb/savedelimiter автоматически устанавливается на заданное ⟨name⟩. Параметры ⟨init options⟩ позволяют настроить автоматическую нумерацию.
Пример использования:
\newtcolorbox[auto numbered]{mybox}[2][default value]{colback=blue!5!white, colframe=blue!75!black, title=Заголовок}
В этом примере создается новое окружение mybox, которое может принимать два аргумента, где первый аргумент имеет значение по умолчанию “default value”. Параметры для tcolorbox задают цвет фона, цвет рамки и заголовок.
\newtcolorbox{mybox}{colback=red!5!white,
colframe=red!75!black}
\begin{mybox}
This is my own box.
\end{mybox}

\newtcolorbox{mybox}[1]{colback=red!5!white,
colframe=red!75!black,fonttitle=\bfseries,
title={#1}}
\begin{mybox}{Hello there}
This is my own box with a mandatory title.
\end{mybox}

\newtcolorbox{mybox}[2][]{colback=red!5!white,
colframe=red!75!black,fonttitle=\bfseries,
colbacktitle=red!85!black,enhanced,
attach boxed title to top center={yshift=-2mm},
title={#2},#1}
\begin{mybox}[colback=yellow]{Hello there}
This is my own box with a mandatory title
and options.
\end{mybox}

\newtcolorbox[auto counter,number within=section]{pabox}[2][]{%
colback=red!5!white,colframe=red!75!black,fonttitle=\bfseries,
title=Examp.~\thetcbcounter: #2,#1}
\begin{pabox}[colback=yellow]{Hello there}
This is my own box with a mandatory
numbered title and options.
\end{pabox}

\renewtcolorbox[⟨init options⟩]{⟨name⟩}[⟨number⟩][⟨default⟩]{⟨options⟩}
Работает аналогично \newtcolorbox, но основан на \renewenvironment вместо \newenvironment. Существующее окружение переопределяется.
Пример использования:
\renewtcolorbox[auto numbered]{mybox}[2][default value]{colback=green!5!white, colframe=green!75!black, title=Обновленный заголовок}
В этом примере существующее окружение mybox переопределяется с новыми параметрами, включая цвет фона, цвет рамки и заголовок. Теперь это окружение будет использовать новые настройки при каждом вызове.
\NewTColorBox[⟨init options⟩]{⟨name⟩}{⟨specification⟩}{⟨options⟩}
Создает новое окружение ⟨name⟩ на основе tcolorbox. В принципе, \NewTColorBox работает как \NewDocumentEnvironment. Это означает, что новое окружение ⟨name⟩ создается с заданным аргументом LATEX3 ⟨specification⟩. Если окружение с именем ⟨name⟩ уже было определено, будет выдана ошибка. Параметры ⟨options⟩ передаются основной tcolorbox. Обратите внимание, что /tcb/savedelimiter автоматически устанавливается на заданное ⟨name⟩. Параметры ⟨init options⟩ позволяют настроить автоматическую нумерацию.
Пример использования:
% counter из предыдущего примера pabox продолжается в этом стиле
\NewTColorBox[use counter from=pabox]{mybox}{ O{red} m d"" !O{} }
{enhanced,colframe=#1!75!black,colback=#1!5!white,
fonttitle=\bfseries,title={\thetcbcounter~#2},
IfValueT={#3}{watermark text={#3}},#4}
\begin{mybox}{My title}
This is a tcolorbox.
\end{mybox}
\begin{mybox}[blue]{My title}
This is a tcolorbox.
\end{mybox}
\begin{mybox}[green]{My title}"My Watermark"
This is a tcolorbox.
\end{mybox}
\begin{mybox}[yellow]{My title}[colbacktitle=yellow!50!white,coltitle=black]
This is a tcolorbox.
\end{mybox}
\begin{mybox}[purple]{My title}"All together"[coltitle=yellow]
This is a tcolorbox.
\end{mybox}

В этом примере создается новое окружение mynewbox с заданной спецификацией и параметрами, включая цвет фона, цвет рамки и заголовок. Если окружение с именем mynewbox уже существует, будет выдана ошибка.
\RenewTColorBox[⟨init options⟩]{⟨name⟩}{⟨specification⟩}{⟨options⟩}
Работает аналогично \NewTColorBox , но основан на \RenewDocumentEnvironment вместо \NewDocumentEnvironment. Существующее окружение переопределяется.
Пример использования:
\RenewTColorBox[auto numbered]{mybox}{m}{colback=red!10!white, colframe=red!75!black, title=Обновленный заголовок}
В этом примере существующее окружение mybox переопределяется с новыми параметрами.
\ProvideTColorBox[⟨init options⟩]{⟨name⟩}{⟨specification⟩}{⟨options⟩}
Работает аналогично \NewTColorBox, но основан на \ProvideDocumentEnvironment вместо \NewDocumentEnvironment. Окружение ⟨name⟩ создается только в том случае, если оно еще не определено.
Пример использования:
\ProvideTColorBox[auto numbered]{mybox}{m}{colback=green!10!white, colframe=green!75!black, title=Предоставленный заголовок}
В этом примере окружение mybox будет создано только если оно еще не существует.
\DeclareTColorBox[⟨init options⟩]{⟨name⟩}{⟨specification⟩}{⟨options⟩}
Работает аналогично \NewTColorBox, но основан на \DeclareDocumentEnvironment вместо \NewDocumentEnvironment. Новое окружение всегда создается, независимо от того, существует ли уже окружение с тем же именем.
Пример использования:
\DeclareTColorBox[auto numbered]{mybox}{m}{colback=blue!10!white, colframe=blue!75!black, title=Объявленный заголовок}
В этом примере окружение mybox будет создано, даже если оно уже существует, что может привести к ошибке.
\NewTotalTColorBox[⟨init options⟩]{\⟨name⟩}{⟨specification⟩}{⟨options⟩}{⟨content⟩}
Создает новую команду \⟨name⟩ на основе tcolorbox. В отличие от \NewTColorBox, также указывается ⟨content⟩ для tcolorbox. В принципе, \NewTotalTColorBox работает как \NewDocumentCommand. Это означает, что новая команда \⟨name⟩ создается с заданным аргументом LATEX3 ⟨specification⟩. Если \⟨name⟩ уже было определено, будет выдана ошибка. Параметры ⟨options⟩ передаются основной tcolorbox, которая заполняется указанным ⟨content⟩. Обратите внимание, что /tcb/savedelimiter автоматически устанавливается на заданное \⟨name⟩. Также обратите внимание, что /tcb/saveto, /tcb/savelowerto и /tcb/redirectlowerto не могут использоваться с \NewTotalTColorBox и аналогичными командами. Параметры ⟨init options⟩ позволяют настроить автоматическую нумерацию.
Пример использования:
\NewTotalTColorBox{\diabox}{ O{} v m }
{ bicolor,nobeforeafter,equal height group=diabox,width=5.7cm,
fonttitle=\bfseries\ttfamily,adjusted title={#2},center title,
colframe=blue!20!black,leftupper=0mm,rightupper=0mm,colback=black!75!white,#1}
{ \tikz\path[fill zoom image={#2}] (0,0) rectangle (\linewidth,4cm);%
\tcblower#3}
\diabox{blueshade.png}{Created with |GIMP|.\\\url{http://www.gimp.org}}
\diabox{goldshade.png}{Created with |GIMP|.\\\url{http://www.gimp.org}}

В этом примере создается новая команда mytotalbox, которая принимает содержимое и параметры, включая цвет фона и цвет рамки. Если команда с именем mytotalbox уже существует, будет выдана ошибка.
\RenewTotalTColorBox[⟨init options⟩]{\⟨name⟩}{⟨specification⟩}{⟨options⟩}{⟨content⟩}
Работает аналогично \NewTotalTColorBox, но основан на \RenewDocumentCommand вместо \NewDocumentCommand. Существующая команда переопределяется.
Пример использования:
\RenewTotalTColorBox[auto numbered]{mytotalbox}{m}{colback=purple!10!white, colframe=purple!75!black}{Обновленное содержимое команды.}
В этом примере существующая команда mytotalbox переопределяется с новыми параметрами и содержимым.
\ProvideTotalTColorBox[⟨init options⟩]{\⟨name⟩}{⟨specification⟩}{⟨options⟩}{⟨content⟩}
Работает аналогично \NewTotalTColorBox, но основан на \ProvideDocumentCommand вместо \NewDocumentCommand. Команда \⟨name⟩ создается только в том случае, если она еще не определена.
Пример использования:
\ProvideTotalTColorBox[auto numbered]{mytotalbox}{m}{colback=teal!10!white, colframe=teal!75!black}{Предоставленное содержимое команды.}
В этом примере команда mytotalbox будет создана только если она еще не существует.
\DeclareTotalTColorBox[⟨init options⟩]{\⟨name⟩}{⟨specification⟩}{⟨options⟩}{⟨content⟩}
Работает аналогично \NewTotalTColorBox, но основан на \DeclareDocumentCommand вместо \NewDocumentCommand. Новая команда всегда создается, независимо от того, существует ли уже команда с тем же именем.
Пример использования:
\DeclareTotalTColorBox[auto numbered]{mytotalbox}{m}{colback=cyan!10!white, colframe=cyan!75!black}{Объявленное содержимое команды.}
В этом примере команда mytotalbox будет создана, даже если она уже существует, что может привести к ошибке.
Создание команд на основе \tcbox
\newtcbox[⟨init options⟩]{\⟨name⟩}[⟨number⟩][⟨default⟩]{⟨options⟩}
Создает новый макрос \⟨name⟩ на основе \tcbox. В принципе, \newtcbox работает как \newcommand. Новый макрос \⟨name⟩ может принимать ⟨number⟩+1 аргументов (до 10), где ⟨default⟩ — это значение по умолчанию для необязательного первого аргумента. В дополнение к аргументам ⟨number⟩ есть автоматический последний (обязательный) аргумент \⟨name⟩, который принимает содержимое коробки. Параметры ⟨options⟩ передаются основной tcbox. Параметры ⟨init options⟩ позволяют настроить автоматическую нумерацию.
Пример использования:
\newtcbox{\mybox}[1][red]{on line,
arc=0pt,outer arc=0pt,colback=#1!10!white,colframe=#1!50!black,
boxsep=0pt,left=1pt,right=1pt,top=2pt,bottom=2pt,
boxrule=0pt,bottomrule=1pt,toprule=1pt}
\newtcbox{\xmybox}[1][red]{on line,
arc=7pt,colback=#1!10!white,colframe=#1!50!black,
before upper={\rule[-3pt]{0pt}{10pt}},boxrule=1pt,
boxsep=0pt,left=6pt,right=6pt,top=2pt,bottom=2pt}
The \mybox[green]{quick} brown \mybox{fox} \mybox[blue]{jumps} over the \mybox[green]{lazy} \mybox{dog}.\par
The \xmybox[green]{quick} brown \xmybox{fox} \xmybox[blue]{jumps} over the \xmybox[green]{lazy} \xmybox{dog}.

В этом примере создается новый макрос mytcbox, который может принимать два аргумента, где первый аргумент имеет значение по умолчанию “default value”. Параметры для tcbox задают цвет фона и цвет рамки.
\renewtcbox[⟨init options⟩]{\⟨name⟩}[⟨number⟩][⟨default⟩]{⟨options⟩}
Работает аналогично \newtcbox, но основан на \renewcommand вместо \newcommand. Существующий макрос переопределяется.
Пример использования:
\renewtcbox[auto numbered]{mytcbox}[2][default value]{colback=blue!10!white, colframe=blue!75!black}
В этом примере существующий макрос mytcbox переопределяется с новыми параметрами и значением по умолчанию для первого аргумента.
\NewTCBox[⟨init options⟩]{\⟨name⟩}{⟨specification⟩}{⟨options⟩}
Создает новую команду \⟨name⟩ на основе \tcbox. В принципе, \NewTCBox работает как \NewDocumentCommand. Это означает, что новая команда \⟨name⟩ создается с заданным аргументом LATEX3 ⟨specification⟩. В дополнение к аргументу ⟨specification⟩ есть автоматический последний (обязательный) аргумент \⟨name⟩, который принимает содержимое коробки. Таким образом, \⟨name⟩ может иметь до 10 аргументов в сумме. Если \⟨name⟩ уже было определено, будет выдана ошибка. Параметры ⟨options⟩ передаются основной \tcbox. Обратите внимание, что /tcb/savedelimiter автоматически устанавливается на заданное \⟨name⟩. Параметры ⟨init options⟩ позволяют настроить автоматическую нумерацию.
Пример использования:
\NewTCBox[auto numbered]{mynewtcbox}{m}{colback=green!10!white, colframe=green!75!black}
В этом примере создается новая команда mynewtcbox, которая принимает спецификацию и параметры, включая цвет фона и цвет рамки. Если команда с именем mynewtcbox уже существует, будет выдана ошибка.
\RenewTCBox[⟨init options⟩]{\⟨name⟩}{⟨specification⟩}{⟨options⟩}
Работает аналогично \NewTCBox, но основан на \RenewDocumentCommand вместо \NewDocumentCommand. Существующая команда переопределяется.
Пример использования:
\RenewTCBox[auto numbered]{mytcbox}{m}{colback=red!10!white, colframe=red!75!black}
В этом примере существующая команда mytcbox переопределяется с новыми параметрами.
\ProvideTCBox[⟨init options⟩]{\⟨name⟩}{⟨specification⟩}{⟨options⟩}
Работает аналогично \NewTCBox, но основан на \ProvideDocumentCommand вместо \NewDocumentCommand. Команда \⟨name⟩ создается только в том случае, если она еще не определена.
Пример использования:
\ProvideTCBox[auto numbered]{mytcbox}{m}{colback=green!10!white, colframe=green!75!black}
В этом примере команда mytcbox будет создана только если она еще не существует.
\DeclareTCBox[⟨init options⟩]{\⟨name⟩}{⟨specification⟩}{⟨options⟩}
Работает аналогично \NewTCBox, но основан на \DeclareDocumentCommand вместо \NewDocumentCommand. Новая команда всегда создается, независимо от того, существует ли уже команда с тем же именем.
Пример использования:
\DeclareTCBox[auto numbered]{mytcbox}{m}{colback=blue!10!white, colframe=blue!75!black}
В этом примере команда mytcbox будет создана, даже если она уже существует, что может привести к ошибке.
\NewTotalTCBox[⟨init options⟩]{\⟨name⟩}{⟨specification⟩}{⟨options⟩}{⟨content⟩}
Создает новую команду \⟨name⟩ на основе \tcbox. В отличие от \NewTCBox, также указывается ⟨content⟩ для tcbox. В принципе, \NewTotalTCBox работает как \NewDocumentCommand. Это означает, что новая команда \⟨name⟩ создается с заданным аргументом LATEX3 ⟨specification⟩. Если \⟨name⟩ уже было определено, будет выдана ошибка. Параметры ⟨options⟩ передаются основной \tcbox, которая заполняется указанным ⟨content⟩. Обратите внимание, что /tcb/savedelimiter автоматически устанавливается на заданное \⟨name⟩. Параметры ⟨init options⟩ позволяют настроить автоматическую нумерацию.
Пример использования:
\NewTotalTCBox[auto numbered]{mytotaltcbox}{m}{colback=yellow!10!white, colframe=yellow!75!black}{Это содержимое новой команды.}
В этом примере создается новая команда mytotaltcbox, которая принимает спецификацию и параметры, включая цвет фона и цвет рамки, а также содержимое коробки. Если команда с именем mytotaltcbox уже существует, будет выдана ошибка.
\NewTotalTCBox{\myverb}{ O{red} v !O{} }
{ fontupper=\ttfamily,nobeforeafter,tcbox raise base,arc=0pt,outer arc=0pt,
top=0pt,bottom=0pt,left=0mm,right=0mm,
leftrule=0pt,rightrule=0pt,toprule=0.3mm,bottomrule=0.3mm,boxsep=0.5mm,
colback=#1!10!white,colframe=#1!50!black,#3}{#2}
To set a word \textbf{bold} in \myverb{\LaTeX}, use
\myverb[green]{\textbf{bold}}. Alternatively, write
\myverb[yellow]{{\bfseries bold}}.
In \myverb[blue]{\LaTeX}[enhanced,fuzzy halo], other font settings are
done in the same way, e.\,g. \myverb{\textit}, \myverb{\itshape}\\
or \myverb[brown]{\texttt}, \myverb[brown]{\ttfamily}.

% \usepackage{listings} or \tcbuselibrary{listings}
\NewTotalTCBox{\commandbox}{ s v }
{verbatim,colupper=white,colback=black!75!white,colframe=black}
{\IfBooleanT{#1}{\textcolor{red}{\ttfamily\bfseries > }}%
\lstinline[language=command.com,keywordstyle=\color{blue!35!white}\bfseries]^#2^}
\commandbox*{cd "My Documents"} changes to directory \commandbox{My Documents}.
\commandbox*{dir /A} lists the directory content.
\commandbox*{copy example.txt d:\target} copies \commandbox{example.txt} to
\commandbox{d:\target}.

\RenewTotalTCBox[⟨init options⟩]{\⟨name⟩}{⟨specification⟩}{⟨options⟩}{⟨content⟩}
Работает аналогично \NewTotalTCBox, но основан на \RenewDocumentCommand вместо \NewDocumentCommand. Существующая команда переопределяется.
Пример использования:
\RenewTotalTCBox[auto numbered]{mytotaltcbox}{m}{colback=purple!10!white, colframe=purple!75!black}{Обновленное содержимое команды.}
В этом примере существующая команда mytotaltcbox переопределяется с новыми параметрами и содержимым.
\ProvideTotalTCBox[⟨init options⟩]{\⟨name⟩}{⟨specification⟩}{⟨options⟩}{⟨content⟩}
Работает аналогично \NewTotalTCBox, но основан на \ProvideDocumentCommand вместо \NewDocumentCommand. Команда \⟨name⟩ создается только в том случае, если она еще не определена.
Пример использования:
\ProvideTotalTCBox[auto numbered]{mytotaltcbox}{m}{colback=teal!10!white, colframe=teal!75!black}{Предоставленное содержимое команды.}
В этом примере команда mytotaltcbox будет создана только если она еще не существует.
\DeclareTotalTCBox[⟨init options⟩]{\⟨name⟩}{⟨specification⟩}{⟨options⟩}{⟨content⟩}
Работает аналогично \NewTotalTCBox, но основан на \DeclareDocumentCommand вместо \NewDocumentCommand. Новая команда всегда создается, независимо от того, существует ли уже команда с тем же именем.
Пример использования:
\DeclareTotalTCBox[auto numbered]{mytotaltcbox}{m}{colback=cyan!10!white, colframe=cyan!75!black}{Объявленное содержимое команды.}
В этом примере команда mytotaltcbox будет создана, даже если она уже существует, что может привести к ошибке.
Переопределение других сред (обертывание с помощью tcolorbox)
\tcolorboxenvironment{⟨name⟩}{⟨options⟩}
Существующая среда ⟨name⟩ переопределяется, чтобы быть обернутой внутри tcolorbox с заданными ⟨options⟩.
% tcbuselibrary{skins}
\newenvironment{myitemize}{%
\begin{itemize}}{\end{itemize}}
\tcolorboxenvironment{myitemize}{blanker,
before skip=6pt,after skip=6pt,
borderline west={3mm}{0pt}{red}}
Some text.
\begin{myitemize}
\item Alpha
\item Beta
\item Gamma
\end{myitemize}
More text.

7.1.1 - Ключи к командам tcolorbox
Ключи для TCB
| Ключ | Синтаксис | Назначение |
|---|---|---|
/tcb/ | Префикс для ключей | Обозначение пространства имен tcolorbox. |
add to height | add to height=<length> | Добавляет фиксированную высоту к общему размеру бокса. |
add to list | add to list=<text> | Регистрирует бокс в списке (например, для оглавления). |
add to natural height | add to natural height=<length> | Увеличивает “естественную” высоту бокса (без учета boxsep и boxrule). |
add to width | add to width=<length> | Добавляет фиксированную ширину к общему размеру бокса. |
adjust text | adjust text=<options> | Настраивает параметры текста (например, hyphenation). |
adjusted title | adjusted title=<text> | Заголовок с динамическим форматированием (например, для нумерации). |
adjusted title after break | adjusted title after break=<text> | Заголовок после разрыва многостраничного бокса. |
after | after={<code>} | Код TikZ/LaTeX, выполняемый после рисования бокса. |
after app | after app={<code>} | Код, выполняемый после добавления бокса в приложении. |
after doc body | after doc body={<code>} | Код, вставляемый после основного содержимого документа. |
after doc body command | after doc body command=<command> | Команда LaTeX, выполняемая после тела документа. |
after doc body environment | after doc body env=<env> | Окружение LaTeX, добавляемое после тела документа. |
after doc body key | after doc body key=<key> | Ключ TikZ, применяемый после тела документа. |
after doc body path | after doc body path=<path> | Путь TikZ, рисуемый после тела документа. |
after float | after float={<code>} | Код, выполняемый после плавающего бокса (float). |
after float app | after float app={<code>} | Аналог after float для приложений. |
after float pre | after float pre={<code>} | Код перед плавающим боксом (для приложений). |
after lower | after lower={<code>} | Код, выполняемый после нижней части (lower part) бокса. |
after lower app | after lower app={<code>} | Аналог after lower для приложений. |
after lower pre | after lower pre={<code>} | Код перед нижней частью (для приложений). |
after lower* | after lower*={<code>} | Код после нижней части (без группировки в {}). |
after pre | after pre={<code>} | Код перед завершением бокса (для приложений). |
after skip | after skip=<length> | Вертикальный отступ после бокса. |
after skip balanced | after skip balanced=<length> | Сбалансированный отступ (учитывает разрывы страниц). |
after title | after title={<code>} | Код, выполняемый после заголовка. |
after title app | after title app={<code>} | Аналог after title для приложений. |
after title pre | after title pre={<code>} | Код перед заголовком (для приложений). |
after title* | after title*={<code>} | Код после заголовка (без группировки в {}). |
after upper | after upper={<code>} | Код, выполняемый после верхней части (upper part) бокса. |
after upper app | after upper app={<code>} | Аналог after upper для приложений. |
after upper pre | after upper pre={<code>} | Код перед верхней частью (для приложений). |
after upper* | after upper*={<code>} | Код после верхней части (без группировки в {}). |
alert | alert | Стиль для выделенных боксов (например, в Beamer). |
alt | alt=<text> | Альтернативный текст (для PDF-тегов или подписей). |
ams align | ams align | Включает окружение align из amsmath в основной части. |
ams align lower | ams align lower | Аналог ams align для нижней части. |
ams align upper | ams align upper | Аналог ams align для верхней части. |
ams align* | ams align* | Версия align* (без нумерации). |
ams equation | ams equation | Включает окружение equation из amsmath. |
ams equation lower | ams equation lower | Аналог ams equation для нижней части. |
ams equation upper | ams equation upper | Аналог ams equation для верхней части. |
ams gather | ams gather | Включает окружение gather из amsmath. |
ams nodisplayskip | ams nodisplayskip | Убирает отступы вокруг формул amsmath. |
arc | arc=<length> | Радиус скругления углов. |
arc is angular | arc is angular | Делает скругление углов “острым” (стиль TikZ). |
arc is curved | arc is curved | Делает скругление плавным (по умолчанию). |
at begin tikz | at begin tikz={<code>} | Код TikZ, выполняемый в начале рисования. |
attach boxed title to bottom | attach boxed title to bottom | Размещает заголовок внизу бокса. |
attach boxed title to top | attach boxed title to top | Размещает заголовок вверху бокса (по умолчанию). |
attach title | attach title | Включает прикрепленный заголовок. |
auto outer arc | auto outer arc | Автонастройка внешних дуг для сложных рамок. |
autoparskip | autoparskip | Автоматически регулирует parskip внутри бокса. |
baseline | baseline=<length> | Выравнивание бокса по базовой линии текста. |
beamer | beamer | Стиль для презентаций Beamer. |
beamer alerted | beamer alerted | Стиль для “alerted” боксов в Beamer. |
beamer hidden | beamer hidden | Стиль для скрытых боксов в Beamer. |
bean arc | bean arc | Альтернативный стиль скругления углов (“бобовый”). |
before | before={<code>} | Код, выполняемый перед рисованием бокса. |
before skip | before skip=<length> | Вертикальный отступ перед боксом. |
bicolor | bicolor | Двухцветный стиль (разные цвета для верхней/нижней частей). |
blank | blank | Пустой стиль (без рамок и фона). |
blanker | blanker | Еще более минималистичный стиль, чем blank. |
blankest | blankest | Максимально упрощенный стиль (только текст). |
blend before title | blend before title | Смешивает фон перед заголовком с основным фоном. |
bookmark | bookmark=<text> | Добавляет закладку PDF для бокса. |
borderline | borderline={<options>} | Рисует дополнительные границы (например, тени). |
bottomrule | bottomrule=<length> | Толщина нижней границы. |
bottomrule at break | bottomrule at break=<length> | Толщина нижней границы на разрыве страницы. |
box align | box align=<baseline/top/bottom> | Выравнивание содержимого внутри бокса. |
boxed title size | boxed title size=<options> | Размеры рамки заголовка. |
boxrule | boxrule=<length> | Толщина основной рамки. |
boxsep | boxsep=<length> | Внутренний отступ содержимого от границ. |
colback | colback=<color> | Цвет фона основной части. |
colbacklower | colbacklower=<color> | Цвет фона нижней части (для bicolor). |
colbacktitle | colbacktitle=<color> | Цвет фона заголовка. |
colframe | colframe=<color> | Цвет рамки бокса. |
collower | collower=<color> | Цвет текста в нижней части бокса. |
color color | color color=<name> | Настройка цвета (внутренний ключ для управления цветами). |
color command | color command=<cmd> | Команда для применения цвета. |
color counter | color counter=<ctr> | Счетчик для генерации цветов. |
color definition | color definition={<code>} | Определение нового цвета. |
color environment | color environment=<env> | Окружение для применения цвета. |
color fade | color fade={<options>} | Градиентная заливка фона. |
color hyperlink | color hyperlink={<options>} | Цвет гиперссылок внутри бокса. |
color key | color key=<key> | Ключ для доступа к цвету. |
color length | color length=<len> | Длина цветового перехода. |
color option | color option={<opt>} | Опции цвета. |
color path | color path={<path>} | Путь TikZ для градиента. |
color value | color value=<val> | Значение цвета (например, red!50). |
coltext | coltext=<color> | Цвет основного текста. |
coltitle | coltitle=<color> | Цвет текста заголовка. |
colupper | colupper=<color> | Цвет текста в верхней части бокса. |
comment | comment={<text>} | Добавляет комментарий внутри бокса. |
comment above listing | comment above listing={<text>} | Комментарий над листингом кода. |
comment above* listing | comment above* listing={<text>} | Комментарий над листингом (без форматирования). |
comment and listing | comment and listing={<text>} | Комбинация комментария и листинга. |
comment only | comment only={<text>} | Только комментарий (без листинга). |
comment outside listing | comment outside listing={<text>} | Комментарий вне листинга (например, сбоку). |
comment side listing | comment side listing={<text>} | Комментарий сбоку от листинга. |
comment style | comment style={<style>} | Стиль оформления комментариев. |
compilable listing | compilable listing | Листинг, который можно компилировать. |
compress page | compress page | Сжимает страницу для экономии места. |
ctan formatter | ctan formatter={<code>} | Форматирование для CTAN-документации. |
default minted options | default minted options={<opt>} | Опции по умолчанию для пакета minted. |
description color | description color=<color> | Цвет текста в описании. |
description delimiters | description delimiters={<left><right>} | Разделители для описаний (например, скобки). |
description delimiters none | description delimiters none | Убирает разделители описаний. |
description delimiters parenthesis | description delimiters parenthesis | Использует круглые скобки для описаний. |
description font | description font={<font>} | Шрифт для описаний. |
description formatter | description formatter={<code>} | Функция форматирования описаний. |
detach title | detach title | Отделяет заголовок от основного бокса. |
do not store to box array | do not store to box array | Запрещает сохранение бокса в массив. |
doc description | doc description={<text>} | Описание для документации. |
doc head | doc head={<text>} | Заголовок раздела документации. |
doc head command | doc head command={<cmd>} | Команда для заголовка документации. |
doc head environment | doc head environment={<env>} | Окружение для заголовка документации. |
doc head key | doc head key={<key>} | Ключ для заголовка документации. |
doc head path | doc head path={<path>} | Путь TikZ для заголовка документации. |
doc index | doc index={<text>} | Индекс для документации. |
doc into index | doc into index={<text>} | Добавляет запись в индекс документации. |
doc key prefix | doc key prefix={<prefix>} | Префикс для ключей документации. |
doc keypath | doc keypath={<path>} | Путь к ключу документации. |
doc label | doc label={<label>} | Метка для перекрестных ссылок. |
doc left | doc left={<text>} | Текст слева в документации. |
doc left indent | doc left indent={<len>} | Отступ слева в документации. |
doc marginnote | doc marginnote={<text>} | Заметка на полях документации. |
doc name | doc name={<name>} | Имя элемента документации. |
doc new | doc new | Пометка нового элемента в документации. |
doc new and updated | doc new and updated | Пометка нового и обновленного элемента. |
doc no index | doc no index | Исключает элемент из индекса. |
doc parameter | doc parameter={<param>} | Параметр для документации. |
doc raster | doc raster={<options>} | Сетка (raster) для документации. |
doc right | doc right={<text>} | Текст справа в документации. |
doc right indent | doc right indent={<len>} | Отступ справа в документации. |
doc sort index | doc sort index={<key>} | Ключ сортировки индекса. |
doc updated | doc updated | Пометка обновленного элемента. |
docexample | docexample={<code>} | Пример кода для документации. |
documentation listing options | documentation listing options={<opt>} | Опции листинга в документации. |
documentation listing style | documentation listing style={<style>} | Стиль листинга в документации. |
documentation minted language | documentation minted language={<lang>} | Язык для minted в документации. |
documentation minted options | documentation minted options={<opt>} | Опции minted для документации. |
documentation minted style | documentation minted style={<style>} | Стиль minted для документации. |
draft | draft | Черновой режим (упрощенное отображение). |
draftmode | draftmode | Режим черновика с дополнительными опциями. |
drop fuzzy midday shadow | drop fuzzy midday shadow={<opt>} | Размытая тень с эффектом “полдень”. |
drop fuzzy shadow | drop fuzzy shadow={<opt>} | Размытая тень вокруг бокса. |
drop large lifted shadow | drop large lifted shadow={<opt>} | Большая “приподнятая” тень. |
drop lifted shadow | drop lifted shadow={<opt>} | Эффект приподнятого бокса с тенью. |
drop midday shadow | drop midday shadow={<opt>} | Тень с акцентом на верхнюю границу. |
drop shadow | drop shadow={<opt>} | Стандартная тень. |
empty | empty | Полностью пустой бокс (без содержимого). |
enforce breakable | enforce breakable | Принудительно разрешает разрыв бокса. |
english language | english language | Устанавливает английский язык для текста. |
enhanced | enhanced | Включает улучшенный режим рисования (с TikZ). |
enhanced jigsaw | enhanced jigsaw | Режим “пазла” с закругленными углами. |
enlarge bottom at break by | enlarge bottom at break by=<len> | Увеличивает нижний отступ при разрыве. |
enlarge bottom by | enlarge bottom by=<len> | Увеличивает нижний отступ. |
enlarge left by | enlarge left by=<len> | Увеличивает левый отступ. |
enlarge right by | enlarge right by=<len> | Увеличивает правый отступ. |
enlarge top at break by | enlarge top at break by=<len> | Увеличивает верхний отступ при разрыве. |
enlarge top by | enlarge top by=<len> | Увеличивает верхний отступ. |
enlargepage | enlargepage | Расширяет страницу для размещения бокса. |
enlargepage flexible | enlargepage flexible | Гибкое расширение страницы. |
environment lower | environment lower={<env>} | Окружение для нижней части бокса. |
environment lower app | environment lower app={<env>} | Окружение для нижней части (для приложений). |
environment lower args | environment lower args={<args>} | Аргументы для окружения нижней части. |
environment lower args app | environment lower args app={<args>} | Аргументы окружения нижней части для приложений |
environment lower args pre | environment lower args pre={<args>} | Аргументы окружения нижней части (предварительные) |
environment lower pre | environment lower pre={<env>} | Окружение нижней части (предварительное) |
environment title | environment title={<env>} | Окружение для заголовка |
environment title app | environment title app={<env>} | Окружение заголовка для приложений |
environment title args | environment title args={<args>} | Аргументы окружения заголовка |
environment title args app | environment title args app={<args>} | Аргументы окружения заголовка для приложений |
environment title args pre | environment title args pre={<args>} | Аргументы окружения заголовка (предварительные) |
environment title pre | environment title pre={<env>} | Окружение заголовка (предварительное) |
environment upper | environment upper={<env>} | Окружение верхней части |
environment upper app | environment upper app={<env>} | Окружение верхней части для приложений |
environment upper args | environment upper args={<args>} | Аргументы окружения верхней части |
environment upper args app | environment upper args app={<args>} | Аргументы окружения верхней части для приложений |
environment upper args pre | environment upper args pre={<args>} | Аргументы окружения верхней части (предварительные) |
environment upper pre | environment upper pre={<env>} | Окружение верхней части (предварительное) |
equal height group | equal height group=<name> | Группа боксов с одинаковой высотой |
every box | every box={<options>} | Стиль для всех боксов |
every box on higher layers | every box on higher layers={<options>} | Стиль для боксов на верхних слоях |
every box on layer n | every box on layer n={<options>} | Стиль для боксов на конкретном слое |
every float | every float={<options>} | Стиль для плавающих боксов |
every listing line | every listing line={<options>} | Стиль для каждой строки листинга |
every listing line* | every listing line*={<options>} | Альтернативный стиль строк листинга |
extend freelance | extend freelance={<options>} | Расширение freelance-стиля |
extend freelancefirst | extend freelancefirst={<options>} | Расширение для первого freelance-бокса |
extend freelancelast | extend freelancelast={<options>} | Расширение для последнего freelance-бокса |
extend freelancemiddle | extend freelancemiddle={<options>} | Расширение для средних freelance-боксов |
external | external={<options>} | Внешнее содержимое бокса |
externalize example | externalize example | Внешний пример (без форсирования) |
externalize example! | externalize example! | Внешний пример (с форсированием) |
externalize listing | externalize listing | Внешний листинг (без форсирования) |
externalize listing! | externalize listing! | Внешний листинг (с форсированием) |
extras | extras={<options>} | Дополнительные стили |
extras broken | extras broken={<options>} | Стили для разорванного бокса |
extras broken pre | extras broken pre={<options>} | Предварительные стили для разорванного бокса |
extras first | extras first={<options>} | Стили для первой части |
extras first and middle | extras first and middle={<options>} | Стили для первой и средней частей |
extras first and middle pre | extras first and middle pre={<options>} | Предварительные стили для первой и средней частей |
extras first pre | extras first pre={<options>} | Предварительные стили для первой части |
extras last | extras last={<options>} | Стили для последней части |
extras last pre | extras last pre={<options>} | Предварительные стили для последней части |
extras middle | extras middle={<options>} | Стили для средней части |
extras middle and last | extras middle and last={<options>} | Стили для средней и последней частей |
extras middle and last pre | extras middle and last pre={<options>} | Предварительные стили для средней и последней частей |
extras middle pre | extras middle pre={<options>} | Предварительные стили для средней части |
extras pre | extras pre={<options>} | Предварительные дополнительные стили |
extras title after break | extras title after break={<options>} | Стили заголовка после разрыва |
extras unbroken | extras unbroken={<options>} | Стили для неразорванного бокса |
extras unbroken and first | extras unbroken and first={<options>} | Стили для неразорванного и первого бокса |
extras unbroken and first pre | extras unbroken and first pre={<options>} | Предварительные стили для неразорванного и первого бокса |
extras unbroken and last | extras unbroken and last={<options>} | Стили для неразорванного и последнего бокса |
extras unbroken and last pre | extras unbroken and last pre={<options>} | Предварительные стили для неразорванного и последнего бокса |
extras unbroken pre | extras unbroken pre={<options>} | Предварительные стили для неразорванного бокса |
extrude bottom by | extrude bottom by=<length> | Выступ снизу бокса |
extrude by | extrude by=<length> | Выступ со всех сторон |
extrude left by | extrude left by=<length> | Выступ слева |
extrude right by | extrude right by=<length> | Выступ справа |
extrude top by | extrude top by=<length> | Выступ сверху |
fill downwards | fill downwards | Заполнение содержимого сверху вниз |
finish | finish={<options>} | Завершающие стили |
finish broken | finish broken={<options>} | Завершающие стили для разорванного бокса |
finish broken pre | finish broken pre={<options>} | Предварительные завершающие стили для разорванного бокса |
finish fading vignette | finish fading vignette={<options>} | Завершение fading vignette-эффекта |
finish first | finish first={<options>} | Завершающие стили для первой части |
finish first and middle | finish first and middle={<options>} | Завершающие стили для первой и средней частей |
finish first and middle pre | finish first and middle pre={<options>} | Предварительные завершающие стили для первой и средней частей |
finish first pre | finish first pre={<options>} | Предварительные завершающие стили для первой части |
finish last | finish last={<options>} | Завершающие стили для последней части |
finish last pre | finish last pre={<options>} | Предварительные завершающие стили для последней части |
finish middle | finish middle={<options>} | Завершающие стили для средней части |
finish middle and last | finish middle and last={<options>} | Завершающие стили для средней и последней частей |
finish middle and last pre | finish middle and last pre={<options>} | Предварительные завершающие стили для средней и последней частей |
finish middle pre | finish middle pre={<options>} | Предварительные завершающие стили для средней части |
finish pre | finish pre={<options>} | Предварительные завершающие стили |
finish raised fading vignette | finish raised fading vignette={<options>} | Завершение raised fading vignette-эффекта |
finish unbroken | finish unbroken={<options>} | Завершающие стили для неразорванного бокса |
finish unbroken and first | finish unbroken and first={<options>} | Завершающие стили для неразорванного и первого бокса |
finish unbroken and first pre | finish unbroken and first pre={<options>} | Предварительные завершающие стили для неразорванного и первого бокса |
finish unbroken and last | finish unbroken and last={<options>} | Завершающие стили для неразорванного и последнего бокса |
finish unbroken and last pre | finish unbroken and last pre={<options>} | Предварительные завершающие стили для неразорванного и последнего бокса |
finish unbroken pre | finish unbroken pre={<options>} | Предварительные завершающие стили для неразорванного бокса |
finish vignette | finish vignette={<options>} | Завершение vignette-эффекта |
fit | fit={<options>} | Подгонка размера содержимого |
fit algorithm | fit algorithm=<name> | Алгоритм подгонки |
fit basedim | fit basedim=<length> | Базовый размер для подгонки |
fit fontsize macros | fit fontsize macros={<names>} | Макросы размера шрифта для подгонки |
fit height from | fit height from={<code>} | Вычисление высоты из кода |
fit height plus | fit height plus={<length>} | Дополнительная высота при подгонке |
fit maxfontdiff | fit maxfontdiff=<value> | Максимальная разница шрифтов |
fit maxfontdiffgap | fit maxfontdiffgap=<value> | Максимальный промежуток разницы шрифтов |
fit maxstep | fit maxstep=<value> | Максимальное количество шагов |
fit maxwidthdiff | fit maxwidthdiff=<value> | Максимальная разница ширины |
fit maxwidthdiffgap | fit maxwidthdiffgap=<value> | Максимальный промежуток разницы ширины |
fit skip | fit skip={<options>} | Пропуск элементов при подгонке |
fit to | fit to={<dimensions>} | Подгонка к указанным размерам |
fit to height | fit to height={<height>} | Подгонка по высоте |
fit warning | fit warning={<options>} | Предупреждения при подгонке |
fit width from | fit width from={<code>} | Вычисление ширины из кода |
fit width plus | fit width plus={<length>} | Дополнительная ширина при подгонке |
flip title | flip title | Переворот заголовка |
float | float | Плавающий бокс |
float* | float* | Альтернативный плавающий бокс |
floatplacement | floatplacement={<placement>} | Позиционирование плавающего бокса |
flush left | flush left | Выравнивание по левому краю |
flush right | flush right | Выравнивание по правому краю |
flushleft lower | flushleft lower | Выравнивание нижней части по левому краю |
flushleft title | flushleft title | Выравнивание заголовка по левому краю |
flushleft upper | flushleft upper | Выравнивание верхней части по левому краю |
flushright lower | flushright lower | Выравнивание нижней части по правому краю |
flushright title | flushright title | Выравнивание заголовка по правому краю |
flushright upper | flushright upper | Выравнивание верхней части по правому краю |
fontlower | fontlower={<font>} | Шрифт нижней части |
fonttitle | fonttitle={<font>} | Шрифт заголовка |
fontupper | fontupper={<font>} | Шрифт верхней части |
force nobeforeafter | force nobeforeafter | Принудительное отключение before/after |
frame code | frame code={<code>} | Пользовательский код рамки |
frame code app | frame code app={<code>} | Код рамки для приложений |
frame code pre | frame code pre={<code>} | Предварительный код рамки |
frame empty | frame empty | Пустая рамка |
frame engine | frame engine=<name> | Движок отрисовки рамки |
frame hidden | frame hidden | Скрытая рамка |
frame style | frame style={<style>} | Стиль рамки |
frame style image | frame style image={<image>} | Стиль рамки с изображением |
frame style tile | frame style tile={<options>} | Стиль рамки с плиткой |
freelance | freelance={<options>} | Freelance-стиль |
freeze extension | freeze extension={<ext>} | Расширение для замороженных файлов |
freeze file | freeze file={<name>} | Имя замороженного файла |
freeze jpg | freeze jpg | Заморозка в JPG |
freeze none | freeze none | Без заморозки |
freeze pdf | freeze pdf | Заморозка в PDF |
freeze png | freeze png | Заморозка в PNG |
fuzzy halo | fuzzy halo={<options>} | Размытое гало |
fuzzy shadow | fuzzy shadow={<options>} | Размытая тень |
geometry nodes | geometry nodes={<names>} | Геометрические узлы |
graphics directory | graphics directory={<path>} | Директория с графикой |
graphics options | graphics options={<options>} | Опции графики |
graphics orientation | graphics orientation={<angle>} | Ориентация графики |
graphics pages | graphics pages={<range>} | Страницы графики |
grow sidewards by | grow sidewards by={<length>} | Рост вбок |
grow to left by | grow to left by={<length>} | Рост влево |
grow to right by | grow to right by={<length>} | Рост вправо |
halign | halign=<alignment> | Горизонтальное выравнивание |
halign code | halign code={<code>} | Код горизонтального выравнивания |
halign lower | halign lower=<alignment> | Выравнивание нижней части |
halign lower code | halign lower code={<code>} | Код выравнивания нижней части |
halign title | halign title=<alignment> | Выравнивание заголовка |
halign title code | halign title code={<code>} | Код выравнивания заголовка |
halign upper | halign upper=<alignment> | Выравнивание верхней части |
halign upper code | halign upper code={<code>} | Код выравнивания верхней части |
halo | halo={<options>} | Эффект гало |
hbox | hbox | Горизонтальная коробка |
hbox boxed title | hbox boxed title | Горизонтальная коробка заголовка |
height | height={<length>} | Фиксированная высота |
height fill | height fill | Заполнение высоты |
height fixed for | height fixed for={<name>} | Фиксированная высота для группы |
height from | height from={<code>} | Высота из кода |
height plus | height plus={<length>} | Дополнительная высота |
hide | hide | Скрытый бокс |
highlight math | highlight math | Подсветка математики |
highlight math style | highlight math style={<style>} | Стиль подсветки математики |
hyperlink | hyperlink={<name>} | Гиперссылка |
hyperlink interior | hyperlink interior={<name>} | Гиперссылка на внутреннюю часть |
hyperlink node | hyperlink node={<name>} | Гиперссылка на узел |
hyperlink title | hyperlink title={<name>} | Гиперссылка на заголовок |
hyperref | hyperref={<options>} | Настройки hyperref |
hyperref interior | hyperref interior={<options>} | Hyperref для внутренней части |
hyperref node | hyperref node={<options>} | Hyperref для узла |
hyperref title | hyperref title={<options>} | Hyperref для заголовка |
hypertarget | hypertarget={<name>} | Цель гиперссылки |
hyperurl | hyperurl={<url>} | Гиперссылка-URL |
hyperurl interior | hyperurl interior={<url>} | URL для внутренней части |
hyperurl node | hyperurl node={<url>} | URL для узла |
hyperurl title | hyperurl title={<url>} | URL для заголовка |
hyperurl* | hyperurl*={<url>} | Альтернативный гиперurl |
hyperurl* interior | hyperurl* interior={<url>} | Альтернативный URL для внутренней части |
hyperurl* node | hyperurl* node={<url>} | Альтернативный URL для узла |
hyperurl* title | hyperurl* title={<url>} | Альтернативный URL для заголовка |
hyphenationfix | hyphenationfix | Исправление переносов |
if odd page | if odd page={<code>} | Условие для нечетной страницы |
if odd page or oneside | if odd page or oneside={<code>} | Условие для нечетной/односторонней страницы |
if odd page or oneside* | if odd page or oneside*={<code>} | Альтернативное условие |
if odd page* | if odd page*={<code>} | Альтернативное условие нечетной страницы |
IfBlankF | IfBlankF={<arg>}{<code>} | Условный код если аргумент пуст (ложь) |
IfBlankT | IfBlankT={<arg>}{<code>} | Условный код если аргумент пуст (истина) |
IfBlankTF | IfBlankTF={<arg>}{<if>}{<else>} | Полное условие для пустого аргумента |
IfBooleanF | IfBooleanF={<arg>}{<code>} | Условие для булева значения (ложь) |
IfBooleanT | IfBooleanT={<arg>}{<code>} | Условие для булева значения (истина) |
IfBooleanTF | IfBooleanTF={<arg>}{<if>}{<else>} | Полное булево условие |
IfEmptyF | IfEmptyF={<arg>}{<code>} | Условие для пустого значения (ложь) |
IfEmptyT | IfEmptyT={<arg>}{<code>} | Условие для пустого значения (истина) |
IfEmptyTF | IfEmptyTF={<arg>}{<if>}{<else>} | Полное условие для пустого значения |
IfNoValueF | IfNoValueF={<arg>}{<code>} | Условие если нет значения (ложь) |
IfNoValueT | IfNoValueT={<arg>}{<code>} | Условие если нет значения (истина) |
IfNoValueTF | IfNoValueTF={<arg>}{<if>}{<else>} | Полное условие для отсутствия значения |
IfValueF | IfValueF={<arg>}{<code>} | Условие если есть значение (ложь) |
IfValueT | IfValueT={<arg>}{<code>} | Условие если есть значение (истина) |
IfValueTF | IfValueTF={<arg>}{<if>}{<else>} | Полное условие для наличия значения |
ignore nobreak | ignore nobreak | Игнорирование запрета разрыва |
image comment | image comment={<text>} | Комментарий к изображению |
index | index={<entry>} | Запись в индекс |
index actual | index actual={<options>} | Фактические настройки индекса |
index annotate | index annotate={<options>} | Аннотации индекса |
index colorize | index colorize={<options>} | Раскрашивание индекса |
index command | index command={<cmd>} | Команда индекса |
index command name | index command name={<name>} | Имя команды индекса |
index default settings | index default settings | Настройки индекса по умолчанию |
index format | index format={<format>} | Формат индекса |
index gather all | index gather all | Сбор всех элементов в индекс |
index gather colors | index gather colors | Сбор цветов в индекс |
index gather commands | index gather commands | Сбор команд в индекс |
index gather counters | index gather counters | Сбор счетчиков в индекс |
index gather environments | index gather environments | Сбор окружений в индекс |
index gather keys | index gather keys | Сбор ключей в индекс |
index gather lengths | index gather lengths | Сбор длин в индекс |
index gather none | index gather none | Отключение сбора в индекс |
index gather paths | index gather paths | Сбор путей в индекс |
index gather values | index gather values | Сбор значений в индекс |
index german settings | index german settings | Немецкие настройки индекса |
index key formatter | index key formatter={<formatter>} | Форматирование ключей индекса |
index keys formatter | index keys formatter={<formatter>} | Форматирование нескольких ключей |
index level | index level={<level>} | Уровень индекса |
index quote | index quote={<text>} | Цитата в индексе |
index* | index*={<entry>} | Альтернативная запись в индекс |
inherit height | inherit height | Наследование высоты |
interior code | interior code={<code>} | Пользовательский код внутренней части |
interior code app | interior code app={<code>} | Код внутренней части для приложений |
interior code pre | interior code pre={<code>} | Предварительный код внутренней части |
interior empty | interior empty | Пустая внутренняя часть |
interior engine | interior engine={<name>} | Движок внутренней части |
interior hidden | interior hidden | Скрытая внутренняя часть |
interior style | interior style={<style>} | Стиль внутренней части |
interior style image | interior style image={<image>} | Стиль внутренней части с изображением |
interior style tile | interior style tile={<options>} | Стиль внутренней части с плиткой |
interior titled code | interior titled code={<code>} | Код внутренней части с заголовком |
interior titled code app | interior titled code app={<code>} | Код внутренней части с заголовком для приложений |
interior titled code pre | interior titled code pre={<code>} | Предварительный код внутренней части с заголовком |
interior titled empty | interior titled empty | Пустая внутренняя часть с заголовком |
interior titled engine | interior titled engine=<name> | Движок для внутренней части с заголовком |
invisible | invisible | Делает бокс полностью невидимым (но сохраняет содержимое) |
keywords bold | keywords bold | Выделение ключевых слов жирным шрифтом в документации |
label | label=<text> | Метка для перекрестных ссылок |
label is label | label is label | Использовать стандартные метки LaTeX |
label is zlabel | label is zlabel | Использовать zref-метки |
label separator | label separator=<text> | Разделитель между меткой и текстом |
label type | label type=<type> | Тип метки (например, ’tcb@label') |
left | left=<length> | Отступ слева для основного содержимого |
left skip | left skip=<length> | Горизонтальный отступ слева |
left* | left*=<length> | Альтернативный отступ слева |
lefthand ratio | lefthand ratio=<value> | Соотношение для левой части (в split боксах) |
lefthand width | lefthand width=<length> | Ширина левой части (в split боксах) |
leftlower | leftlower=<length> | Отступ слева для нижней части |
leftright skip | leftright skip=<length> | Одновременный отступ слева и справа |
leftrule | leftrule=<length> | Толщина левой границы |
lefttitle | lefttitle=<length> | Отступ слева для заголовка |
leftupper | leftupper=<length> | Отступ слева для верхней части |
lifted shadow | lifted shadow={<options>} | Эффект “приподнятой” тени |
lines before break | lines before break=<number> | Минимальное количество строк перед разрывом |
list entry | list entry=<text> | Запись для списка (оглавления) |
list text | list text=<text> | Текст для списка |
listing above comment | listing above comment={<text>} | Листинг с комментарием сверху |
listing above text | listing above text={<text>} | Листинг с текстом сверху |
listing and comment | listing and comment={<text>} | Комбинация листинга и комментария |
listing engine | listing engine=<name> | Движок для обработки листингов |
listing file | listing file={<filename>} | Файл с кодом для листинга |
listing inputencoding | listing inputencoding=<encoding> | Кодировка входного файла листинга |
listing only | listing only | Только листинг (без дополнительного текста) |
listing options | listing options={<options>} | Опции для листинга |
listing remove caption | listing remove caption | Удаление подписи у листинга |
listing side comment | listing side comment={<text>} | Листинг с боковым комментарием |
listing side text | listing side text={<text>} | Листинг с боковым текстом |
listing style | listing style={<style>} | Стиль оформления листинга |
listing utf8 | listing utf8 | Использование UTF-8 для листинга |
lower separated | lower separated | Разделение нижней части визуальной линией |
lowerbox | lowerbox | Обработка нижней части как бокса |
marker | marker={<options>} | Маркеры для оформления |
math | math | Математический режим в основном содержимом |
math lower | math lower | Математический режим в нижней части |
math upper | math upper | Математический режим в верхней части |
middle | middle=<length> | Вертикальное выравнивание по середине |
minipage | minipage | Обработка содержимого как minipage |
minipage boxed title | minipage boxed title | Заголовок как minipage |
minted language | minted language={<lang>} | Язык для пакета minted |
minted options | minted options={<options>} | Опции для minted |
minted style | minted style={<style>} | Стиль для minted |
move upwards | move upwards=<length> | Сдвиг содержимого вверх |
nameref | nameref | Использование nameref для ссылок |
natural height | natural height | Естественная высота содержимого |
no borderline | no borderline | Удаление дополнительных границ |
no boxed title style | no boxed title style | Отключение стиля для заголовка в рамке |
no extras | no extras | Отключение дополнительных стилей |
no finish | no finish | Отключение завершающих стилей |
no label type | no label type | Отключение специального типа метки |
no listing options | no listing options | Отключение опций листинга |
no overlay | no overlay | Отключение наложений |
no shadow | no shadow | Отключение теней |
no underlay | no underlay | Отключение подложек |
no watermark | no watermark | Отключение водяных знаков |
nobeforeafter | nobeforeafter | Отключение отступов before/after |
nofloat | nofloat | Запрет плавающего размещения |
noparskip | noparskip | Отключение parskip |
notitle | notitle | Отключение заголовка |
octogon arc | octogon arc | Восьмиугольная форма углов |
on line | on line | Размещение в строке текста |
only | only={<options>} | Условное отображение содержимого |
opacityback | opacityback=<value> | Прозрачность фона |
opacitybacktitle | opacitybacktitle=<value> | Прозрачность фона заголовка |
opacityframe | opacityframe=<value> | Прозрачность рамки |
opacitytext | opacitytext=<value> | Прозрачность текста |
outer arc | outer arc | Скругление внешних углов |
overlay | overlay={<code>} | Наложение TikZ-кода |
oversize | oversize | Разрешение содержимому выходить за границы |
pad at break | pad at break=<length> | Заполнение при разрыве |
page ref formatter | page ref formatter={<code>} | Форматирование ссылок на страницы |
parbox | parbox | Обработка содержимого как parbox |
parskip | parskip | Использование parskip между абзацами |
phantom | phantom | Невидимый бокс, занимающий место |
process code | process code={<code>} | Обработка кода перед вставкой |
raster columns | raster columns=<number> | Количество колонок в сетке |
raster equal height | raster equal height | Выравнивание высоты элементов сетки |
raster rows | raster rows=<number> | Количество строк в сетке |
record | record | Запись параметров бокса |
right | right=<length> | Отступ справа для основного содержимого |
right skip | right skip=<length> | Горизонтальный отступ справа |
rightrule | rightrule=<length> | Толщина правой границы |
rotate | rotate=<angle> | Вращение бокса |
rounded corners | rounded corners=<length> | Скругление углов |
run pdflatex | run pdflatex | Запуск pdflatex для обработки содержимого |
savedelimiter | savedelimiter={<text>} | Сохранение разделителя |
saveto | saveto={<filename>} | Сохранение содержимого в файл |
scale | scale=<factor> | Масштабирование содержимого |
segmentation at break | segmentation at break | Разделитель при разрыве |
segmentation code | segmentation code={<code>} | Пользовательский код разделителя |
segmentation style | segmentation style={<style>} | Стиль линии-разделителя между верхней и нижней частями |
separator sign | separator sign={<char>} | Символ-разделитель в описаниях |
separator sign colon | separator sign colon | Использование двоеточия как разделителя |
separator sign dash | separator sign dash | Использование тире как разделителя |
separator sign none | separator sign none | Отсутствие разделителя |
set alt | set alt={<text>} | Установка альтернативного текста |
set temporal | set temporal={<text>} | Временная установка значения |
shadow | shadow={<options>} | Настройка тени вокруг бокса |
sharp corners | sharp corners | Острые углы (без скругления) |
sharpish corners | sharpish corners | Слегка скругленные углы |
shield externalize | shield externalize | Защита от externalize |
short title | short title={<text>} | Краткий вариант заголовка |
show bounding box | show bounding box | Отображение ограничивающей рамки |
shrink break goal | shrink break goal={<length>} | Целевое значение сжатия при разрыве |
shrink tight | shrink tight | Плотное сжатие содержимого |
sidebyside | sidebyside | Размещение содержимого бок о бок |
sidebyside align | sidebyside align={<option>} | Выравнивание side-by-side содержимого |
sidebyside gap | sidebyside gap={<length>} | Зазор между side-by-side элементами |
sidebyside switch | sidebyside switch | Переключение порядка side-by-side |
size | size={<option>} | Размер бокса (normal, small, etc.) |
skin | skin={<name>} | Скин для оформления бокса |
skin first | skin first={<name>} | Скин для первого бокса в группе |
skin last | skin last={<name>} | Скин для последнего бокса в группе |
skin middle | skin middle={<name>} | Скин для средних боксов в группе |
smart shadow arc | smart shadow arc | Умное скругление теней |
space | space={<length>} | Вертикальный промежуток |
space to | space to={<length>} | Гибкий вертикальный промежуток |
space to lower | space to lower={<length>} | Промежуток до нижней части |
space to upper | space to upper={<length>} | Промежуток до верхней части |
spartan | spartan | Минималистичный стиль оформления |
split | split={<options>} | Разделение бокса на части |
spread | spread | Равномерное распределение пространства |
spread downwards | spread downwards | Распределение вниз |
spread inwards | spread inwards | Распределение внутрь |
spread outwards | spread outwards | Распределение наружу |
spread upwards | spread upwards | Распределение вверх |
square | square | Квадратная форма бокса |
squeezed title | squeezed title | Сжатый заголовок |
standard | standard | Стандартный стиль оформления |
standard jigsaw | standard jigsaw | Стандартный стиль с “пазлами” |
step | step={<counter>} | Шаг нумерации |
step and label | step and label | Автоматическая нумерация и метка |
store to box array | store to box array={<name>} | Сохранение в массив боксов |
subtitle style | subtitle style={<style>} | Стиль подзаголовка |
tabularx | tabularx | Использование tabularx внутри |
tcbimage comment | tcbimage comment={<text>} | Комментарий к изображению |
tcbox raise | tcbox raise={<length>} | Поднятие бокса |
tempfile | tempfile | Использование временного файла |
temporal | temporal={<text>} | Временное значение |
terminator sign | terminator sign={<char>} | Конечный символ в описаниях |
text above listing | text above listing={<text>} | Текст над листингом |
text and listing | text and listing | Комбинация текста и листинга |
text fill | text fill | Заполнение текстом |
text height | text height={<length>} | Высота текстовой области |
text width | text width={<length>} | Ширина текстовой области |
theorem | theorem | Стиль для теорем |
theorem label supplement | theorem label supplement={<text>} | Дополнение к метке теоремы |
theorem style | theorem style={<name>} | Стиль оформления теоремы |
tikz | tikz={<options>} | Опции TikZ |
tikz lower | tikz lower={<options>} | TikZ для нижней части |
tikz upper | tikz upper={<options>} | TikZ для верхней части |
tikznode | tikznode | Обработка как TikZ-узел |
tile | tile | Плиточное оформление фона |
title | title={<text>} | Заголовок бокса |
title after break | title after break={<text>} | Заголовок после разрыва |
title style | title style={<style>} | Стиль заголовка |
titlerule | titlerule={<length>} | Линия под заголовком |
toggle enlargement | toggle enlargement | Переключение увеличения |
toggle left and right | toggle left and right | Переключение левого/правого |
top | top={<length>} | Отступ сверху |
toprule | toprule={<length>} | Верхняя граница |
unbreakable | unbreakable | Запрет разрыва бокса |
underlay | underlay={<code>} | Подложка (TikZ-код под содержимым) |
underlay boxed title | underlay boxed title={<code>} | Подложка для заголовка |
underlay first | underlay first={<code>} | Подложка для первой части |
underlay last | underlay last={<code>} | Подложка для последней части |
underlay middle | underlay middle={<code>} | Подложка для средней части |
underlay vignette | underlay vignette={<options>} | Виньетка в качестве подложки |
upperbox | upperbox | Обработка верхней части как бокса |
use alt | use alt | Использование альтернативного текста |
use color stack | use color stack | Использование стека цветов |
valign | valign={<option>} | Вертикальное выравнивание |
varwidth upper | varwidth upper | Переменная ширина верхней части |
verbatim | verbatim | Режим verbatim |
visible | visible | Видимый бокс (антоним invisible) |
watermark graphics | watermark graphics={<file>} | Водяной знак из изображения |
watermark opacity | watermark opacity={<value>} | Прозрачность водяного знака |
watermark text | watermark text={<text>} | Текстовый водяной знак |
watermark tikz | watermark tikz={<code>} | Водяной знак TikZ |
width | width={<length>} | Ширина бокса |
Основные ключи оформления заголовка (/tcb/boxtitle/)
| Ключ | Синтаксис | Назначение |
|---|---|---|
xshift | xshift=<length> | Горизонтальное смещение заголовка |
yshift | yshift=<length> | Вертикальное смещение заголовка |
yshift* | yshift*=<length> | Альтернативное вертикальное смещение |
yshifttext | yshifttext=<length> | Смещение текста заголовка |
Ключи документации (/tcb/doclang/)
| Ключ | Синтаксис | Назначение |
|---|---|---|
color | color={<name>} | Цвет для документации |
commands | commands={<list>} | Список команд |
counter | counter={<name>} | Счетчик для документации |
environment | environment={<name>} | Окружение для документации |
index | index={<options>} | Настройки индекса |
key | key={<name>} | Ключ документации |
length | length={<name>} | Длина для документации |
new | new | Пометка нового элемента |
path | path={<name>} | Путь для документации |
updated | updated | Пометка обновленного элемента |
value | value={<val>} | Значение для документации |
Ключи внешнего контента (/tcb/external/)
| Ключ | Синтаксис | Назначение |
|---|---|---|
- | - | Стандартный режим externalize |
! | ! | Форсированный режим externalize |
compiler | compiler={<name>} | Компилятор для внешних файлов |
environment | environment={<name>} | Окружение для внешнего контента |
externalize | externalize | Активация externalize |
name | name={<base>} | Базовое имя для файлов |
preamble | preamble={<code>} | Преамбула для внешних файлов |
prefix | prefix={<text>} | Префикс для имен файлов |
runner | runner={<command>} | Команда для запуска |
safety | safety={<options>} | Настройки безопасности |
Библиотеки (/tcb/library/)
| Ключ | Назначение |
|---|---|
all | Все библиотеки |
breakable | Поддержка разрывов |
documentation | Документационные стили |
external | Внешний контент |
fitting | Автоподгонка размеров |
listings | Поддержка листингов |
minted | Интеграция с Minted |
raster | Сеточная компоновка |
skins | Дополнительные скины |
theorems | Стили для теорем |
Ключи постеров (/tcb/poster/)
| Ключ | Синтаксис | Назначение |
|---|---|---|
colspacing | colspacing=<length> | Расстояние между колонками |
columns | columns=<number> | Количество колонок |
height | height=<length> | Высота постера |
rowspacing | rowspacing=<length> | Расстояние между строками |
showframe | showframe | Показать рамки |
width | width=<length> | Ширина постера |
Ключи виньетирования (/tcb/vig/)
| Ключ | Синтаксис | Назначение |
|---|---|---|
base color | base color={<color>} | Базовый цвет виньетки |
east size | east size=<length> | Размер восточной части |
fade in | fade in={<options>} | Эффект плавного появления |
lower left corner | lower left corner={<coord>} | Левый нижний угол |
size | size={<length>} | Общий размер |
upper right corner | upper right corner={<coord>} | Правый верхний угол |
Интеграция с TikZ (/tikz/)
| Ключ | Синтаксис | Назначение |
|---|---|---|
tcb fill frame | tcb fill frame={<color>} | Заливка рамки |
tcb fill interior | tcb fill interior={<color>} | Заливка внутренней части |
tcb fill title | tcb fill title={<color>} | Заливка заголовка |
Особенности:
- Группы ключей организованы по функциональности (заголовки, документация, внешний контент и т.д.)
- Виньетки (/tcb/vig/) предоставляют сложные эффекты затемнения/осветления углов
- Постеры (/tcb/poster/) позволяют создавать сложные сеточные компоновки
- Интеграция с TikZ дает полный контроль над графическими элементами
Каждая группа ключей решает специфические задачи, от базового позиционирования до сложных эффектов оформления.
7.1.2 - Команды для Title
| Команда | Полный синтаксис | Описание и назначение |
|---|---|---|
title | /tcb/title=⟨text⟩ | Создает заголовок с указанным текстом. |
notitle | /tcb/notitle | Удаляет строку заголовка, если установлено. |
adjusted title | /tcb/adjusted title=⟨text⟩ | Создает заголовок с автоматической подгонкой высоты под текст (полезно для выравнивания высоты боксов в группе). |
adjust text | /tcb/adjust text=⟨text⟩ | Устанавливает эталонный текст для подгонки высоты в adjusted title. |
squeezed title | /tcb/squeezed title=⟨text⟩ | Создает заголовок, сжимая текст, если он не помещается в доступное пространство. |
squeezed title* | /tcb/squeezed title*=⟨text⟩ | Комбинация adjusted title и squeezed title (подгонка высоты и сжатие текста). |
titlebox | /tcb/titlebox=⟨mode⟩ | Управляет отображением заголовка (visible — стандартное отображение, invisible — скрывает текст, оставляя пустое место). |
detach title | /tcb/detach title | Отделяет заголовок от стандартной позиции, сохраняя его в \tcbtitletext и \tcbtitle. |
attach title | /tcb/attach title | Возвращает заголовок в стандартную позицию (отменяет detach title). |
attach title to upper | /tcb/attach title to upper=⟨text⟩ | Прикрепляет заголовок к началу верхней части содержимого бокса (с дополнительным текстом между заголовком и содержимым). |
\tcbset{colback=White,arc=0mm,width=(\linewidth-4pt)/4,
equal height group=AT,before=,after=\hfill,fonttitle=\bfseries}
The following titles are not adjusted:\\
\foreach \n in {xxx,ggg,AAA,\"Agypten}
{\begin{tcolorbox}[title=\n,colframe=red!75!black]
Some content.\end{tcolorbox}}
Now, we try again with adjusted titles:\\
\foreach \n in {xxx,ggg,AAA,\"Agypten}
{\begin{tcolorbox}[adjusted title=\n,colframe=blue!75!black]
Some content.\end{tcolorbox}}
7.1.3 - Команды для SubTitle
Таблица команд для управления Subtitle в пакете tcolorbox
| Команда | Полный синтаксис | Описание и назначение |
|---|---|---|
\tcbsubtitle | \tcbsubtitle[⟨options⟩]{⟨text⟩} | Добавляет подзаголовок внутри tcolorbox. Наследует стили родительского бокса, но может быть дополнительно настроен через ⟨options⟩. |
subtitle style | /tcb/subtitle style=⟨options⟩ | Задает стиль для всех подзаголовков (\tcbsubtitle) внутри бокса. Позволяет централизованно настроить оформление. |
Примеры использования
1. Базовый подзаголовок
\begin{tcolorbox}[title=Основной заголовок, colback=blue!5!white, colframe=blue!75!black]
Основное содержимое.
\tcbsubtitle{Первый подзаголовок}
Текст под первым подзаголовком.
\tcbsubtitle{Второй подзаголовок}
Текст под вторым подзаголовком.
\end{tcolorbox}
2. Настройка стиля подзаголовков
\begin{tcolorbox}[
title=Пример с subtitle style,
colback=green!5!white,
colframe=green!75!black,
subtitle style={
colback=yellow!20!white,
colframe=red!50!black,
fontupper=\bfseries,
boxrule=1pt
}
]
Основной текст.
\tcbsubtitle{Настроенный подзаголовок}
Текст с кастомным оформлением.
\end{tcolorbox}
3. Локальная переопределение через ⟨options⟩
\begin{tcolorbox}[title=Локальные настройки, colback=purple!5!white]
\tcbsubtitle[colback=orange!30!white, before skip=10pt]{Особый подзаголовок}
Текст с увеличенным отступом сверху и оранжевым фоном.
\end{tcolorbox}
7.1.4 - Команды для Part
Таблица команд для управления частями (Upper/Lower Part) в пакете tcolorbox
| Команда | Полный синтаксис | Описание и назначение |
|---|---|---|
upperbox | /tcb/upperbox=⟨mode⟩ | Управляет отображением верхней части бокса. Допустимые значения: visible (стандартное отображение), invisible (скрывает содержимое). |
lowerbox | /tcb/lowerbox=⟨mode⟩ | Управляет отображением нижней части (после \tcblower). Аналогично upperbox. |
visible | /tcb/visible | Сокращение для upperbox=visible, lowerbox=visible, titlebox=visible. |
invisible | /tcb/invisible | Сокращение для upperbox=invisible, lowerbox=invisible, titlebox=invisible. |
saveto | /tcb/saveto=⟨file name⟩ | Сохраняет весь контент бокса (включая нижнюю часть, если есть) в указанный файл. Несовместимо с savelowerto/redirectlowerto. |
savelowerto | /tcb/savelowerto=⟨file name⟩ | Сохраняет только нижнюю часть (после \tcblower) в файл. |
redirectlowerto | /tcb/redirectlowerto=⟨file name⟩ | Перенаправляет нижнюю часть в файл (без отображения в документе). |
Примеры использования
1. Управление видимостью частей
\begin{tcolorbox}[upperbox=invisible, colback=white]
Этот текст не виден (верхняя часть скрыта).
\end{tcolorbox}
\begin{tcolorbox}[lowerbox=invisible, colback=white]
Виден только верх.
\tcblower
Нижняя часть скрыта.
\end{tcolorbox}
Результат:
- Первый бокс: пустое пространство (верх скрыт).
- Второй бокс: отображается только текст до
\tcblower.
2. Сокращенные команды visible/invisible
\begin{tcolorbox}[invisible, title=Скрытый бокс]
Весь контент (включая заголовок) не виден.
\tcblower
Нижняя часть тоже скрыта.
\end{tcolorbox}
Результат: Пустое место (все части скрыты).
3. Сохранение контента в файл
\begin{tcolorbox}[saveto=mybox.tex, title=Сохраненный бокс]
Верхняя часть.
\tcblower
Нижняя часть.
\end{tcolorbox}
Загружаем сохраненное:
\input{mybox.tex}
Результат:
- В документе отображается оригинальный бокс.
- Содержимое сохранено в
mybox.texи может быть повторно загружено через\input.
4. Работа с нижней частью
\begin{tcolorbox}[savelowerto=lower.tex]
Верхняя часть (отображается).
\tcblower
Нижняя часть (сохраняется в файл).
\end{tcolorbox}
Результат:
- В документе видна только верхняя часть.
- Нижняя часть сохранена в
lower.tex.
Важные нюансы:
Разделение частей:
- Верхняя часть обязательна, нижняя — опциональна (активируется
\tcblower). - Без
\tcblowerвесь контент считается верхней частью.
- Верхняя часть обязательна, нижняя — опциональна (активируется
Совместимость:
savetoнельзя использовать сsavelowertoилиredirectlowerto.
Применение:
invisibleполезен для скрытия контента (например, при сохранении в файл без отображения).savelowertoудобен для извлечения доп. материалов (решений задач, примечаний).
7.1.5 - Команды для Lower Part
Таблица команд для управления нижней частью (Lower Part) в пакете tcolorbox
| Команда | Полный синтаксис | Описание и назначение |
|---|---|---|
lowerbox | /tcb/lowerbox=⟨mode⟩ | Управляет отображением нижней части. Допустимые значения: visible (стандартное отображение), invisible (скрывает содержимое, оставляя пустое место), ignored (полностью игнорирует нижнюю часть). |
savelowerto | /tcb/savelowerto=⟨file name⟩ | Сохраняет содержимое нижней части в указанный файл для последующего использования. Несовместимо с saveto. |
redirectlowerto | /tcb/redirectlowerto=⟨file name⟩ | Комбинация savelowerto и lowerbox=ignored. Сохраняет нижнюю часть в файл, но не отображает её в документе. Полезно для работы с счётчиками. |
lower separated | `/tcb/lower separated=true | false(по умолчаниюtrue`) |
savedelimiter | /tcb/savedelimiter=⟨name⟩ | Используется при создании новых окружений на основе tcolorbox для корректной работы с savelowerto или redirectlowerto. ⟨name⟩ должно совпадать с именем нового окружения. |
Примеры использования
1. Управление видимостью нижней части
\begin{tcolorbox}[lowerbox=invisible, colback=white]
Верхняя часть (видна).
\tcblower
Нижняя часть (скрыта, но место остаётся).
\end{tcolorbox}
\begin{tcolorbox}[lowerbox=ignored, colback=white]
Верхняя часть (видна).
\tcblower
Нижняя часть (полностью игнорируется).
\end{tcolorbox}
Результат:
- Первый бокс: нижняя часть скрыта, но занимает место.
- Второй бокс: нижняя часть отсутствует.
2. Сохранение нижней части в файл
\begin{tcolorbox}[savelowerto=lower_content.tex, lowerbox=invisible]
Верхняя часть.
\tcblower
Нижняя часть (сохранена в файл).
\end{tcolorbox}
Загружаем сохранённое:
\input{lower_content.tex}
Результат:
- В документе отображается только верхняя часть.
- Нижняя часть сохранена в
lower_content.texи может быть загружена через\input.
3. Перенаправление нижней части без отображения
\setcounter{enumi}{1}
Значение счётчика: \theenumi
\begin{tcolorbox}[redirectlowerto=counter_example.tex]
Верхняя часть.
\tcblower
Нижняя часть. \stepcounter{enumi} Новое значение: \theenumi.
\end{tcolorbox}
Загружаем:
\input{counter_example.tex}
Результат:
- В документе: отображается только верхняя часть, счётчик не изменён.
- В файле
counter_example.tex: сохранён текст нижней части с обновлённым счётчиком.
4. Визуальное разделение частей
\begin{tcolorbox}[title=Разделённые части, lower separated=true]
Верхняя часть.
\tcblower
Нижняя часть (визуально отделена).
\end{tcolorbox}
\begin{tcolorbox}[title=Неразделённые части, lower separated=false]
Верхняя часть.
\tcblower
Нижняя часть (без разделения).
\end{tcolorbox}
Результат:
- Первый бокс: части разделены линией (зависит от стиля).
- Второй бокс: части сливаются.
5. Создание пользовательского окружения с сохранением
\newtcolorbox{mybox}[1]{%
savelowerto=#1, lowerbox=ignored,
colback=blue!5!white, colframe=blue!75!black,
title=Мой бокс
}
\begin{mybox}{saved_part.tex}
Верхняя часть.
\tcblower
Сохранённая нижняя часть.
\end{mybox}
Используем сохранённое:
\input{saved_part.tex}
Результат:
- В документе: только верхняя часть с заголовком “Мой бокс”.
- В файле
saved_part.tex: сохранена нижняя часть.
Ключевые особенности:
Гибкость:
lowerbox=ignoredполностью исключает нижнюю часть из обработки, что полезно для оптимизации.redirectlowertoпозволяет сохранять контент без побочных эффектов (например, изменения счётчиков).
Совместимость:
savelowertoиredirectlowertoнельзя использовать вместе сsaveto.
Дизайн:
- Разделение частей (
lower separated) можно настроить для разных стилей (например,beamerилиraster).
- Разделение частей (
7.1.6 - Команды для Color и Font
Таблица управления цветами и шрифтами в tcolorbox
Основные параметры цвета
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
colframe | /tcb/colframe=⟨color⟩ | Цвет рамки бокса. По умолчанию: black!75!white. | colframe=red |
colback | /tcb/colback=⟨color⟩ | Цвет фона содержимого бокса. По умолчанию: black!5!white. | colback=blue!10 |
colbacktitle | /tcb/colbacktitle=⟨color⟩ | Цвет фона заголовка. По умолчанию: black!50!white. | colbacktitle=green!20 |
colupper | /tcb/colupper=⟨color⟩ | Цвет текста верхней части. По умолчанию: black. | colupper=red!50 |
collower | /tcb/collower=⟨color⟩ | Цвет текста нижней части. По умолчанию: black. | collower=blue!50 |
coltext | /tcb/coltext=⟨color⟩ | Устанавливает одинаковый цвет текста для верхней и нижней части. | coltext=purple |
coltitle | /tcb/coltitle=⟨color⟩ | Цвет текста заголовка. По умолчанию: white. | coltitle=yellow |
Управление отображением заголовка
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
title filled | `/tcb/title filled=true | false` | Включает/отключает заливку фона заголовка. По умолчанию: false. |
Параметры шрифтов
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
fontupper | /tcb/fontupper=⟨text⟩ | Устанавливает шрифт для верхней части. | fontupper=\bfseries |
fontlower | /tcb/fontlower=⟨text⟩ | Устанавливает шрифт для нижней части. | fontlower=\itshape |
fonttitle | /tcb/fonttitle=⟨text⟩ | Устанавливает шрифт для заголовка. | fonttitle=\sffamily |
Примеры использования
1. Настройка цветов
\begin{tcolorbox}[colframe=red, colback=yellow!10, colbacktitle=blue!20, coltitle=white, title=Цветной бокс]
Это пример цветного tcolorbox.
\tcblower
Нижняя часть с другим цветом текста.
\end{tcolorbox}
2. Управление шрифтами
\begin{tcolorbox}[fonttitle=\sffamily\bfseries\large, fontupper=\itshape, fontlower=\bfseries, title=Шрифты]
Верхняя часть курсивом.
\tcblower
Нижняя часть жирным.
\end{tcolorbox}
3. Комбинированный пример
\begin{tcolorbox}[
colframe=green!50!black,
colback=green!10,
colbacktitle=green!40,
coltitle=white,
fonttitle=\bfseries,
title filled=true,
title=Комбинированный пример,
fontupper=\small,
collower=red
]
Верхняя часть мелким шрифтом.
\tcblower
Нижняя часть красным цветом.
\end{tcolorbox}
Особенности:
- Все цветовые параметры поддерживают стандартные цветовые модели LaTeX (например,
red!50!white). - Для шрифтов можно использовать любые стандартные команды изменения шрифта (
\bfseries,\itshapeи т.д.). - Параметр
title filledавтоматически активируется при установкеcolbacktitleили других связанных с заголовком параметров. coltextудобен для установки единого цвета текста во всем боксе, тогда какcolupperиcollowerпозволяют дифференцировать части.
7.1.7 - Команды для выравнивания текста
Таблица управления выравниванием текста в tcolorbox
Горизонтальное выравнивание
| Параметр | Синтаксис | Допустимые значения | Описание | Пример |
|---|---|---|---|---|
halign / halign upper | /tcb/halign=⟨alignment⟩ | justify, left, flush left, right, flush right, center, flush center | Выравнивание верхней части (или всего содержимого, если нет нижней части) | halign=flush center |
halign lower | /tcb/halign lower=⟨alignment⟩ | те же, что для halign | Выравнивание нижней части | halign lower=right |
halign title | /tcb/halign title=⟨alignment⟩ | те же, что для halign | Выравнивание заголовка | halign title=center |
halign code / halign upper code | /tcb/halign code={⟨code⟩} | произвольный LaTeX-код | Произвольное выравнивание верхней части | halign code={\raggedright} |
halign lower code | /tcb/halign lower code={⟨code⟩} | произвольный LaTeX-код | Произвольное выравнивание нижней части | halign lower code={\centering} |
halign title code | /tcb/halign title code={⟨code⟩} | произвольный LaTeX-код | Произвольное выравнивание заголовка | halign title code={\raggedleft} |
Вертикальное выравнивание
| Параметр | Синтаксис | Допустимые значения | Описание | Пример |
|---|---|---|---|---|
valign / valign upper | /tcb/valign=⟨alignment⟩ | top, center, bottom, scale, scale* | Вертикальное выравнивание верхней части | valign=center |
valign lower | /tcb/valign lower=⟨alignment⟩ | те же, что для valign | Вертикальное выравнивание нижней части | valign lower=bottom |
valign scale limit | /tcb/valign scale limit=⟨real⟩ | число (по умолчанию 1.1) | Максимальный коэффициент масштабирования для scale* | valign scale limit=1.5 |
Сокращённые команды
| Команда | Эквивалент | Описание |
|---|---|---|
flushleft upper | halign=flush left | Выравнивание верхней части по левому краю |
center upper | halign=flush center | Выравнивание верхней части по центру |
flushright upper | halign=flush right | Выравнивание верхней части по правому краю |
flushleft lower | halign lower=flush left | Выравнивание нижней части по левому краю |
center lower | halign lower=flush center | Выравнивание нижней части по центру |
flushright lower | halign lower=flush right | Выравнивание нижней части по правому краю |
flushleft title | halign title=flush left | Выравнивание заголовка по левому краю |
center title | halign title=flush center | Выравнивание заголовка по центру |
flushright title | halign title=flush right | Выравнивание заголовка по правому краю |
Примеры использования
1. Горизонтальное выравнивание
\begin{tcolorbox}[halign=flush left, title=Пример выравнивания]
Текст, выровненный по левому краю.
\tcblower
Нижняя часть с выравниванием по правому краю.
\end{tcolorbox}
2. Вертикальное выравнивание
\begin{tcolorbox}[valign=center, height=4cm]
Текст, выровненный по центру по вертикали.
\end{tcolorbox}
3. Выравнивание заголовка
\begin{tcolorbox}[halign title=center, title=Центрированный заголовок]
Содержимое бокса.
\end{tcolorbox}
Особенности:
Разница между
flushи не-flushверсиями:flushверсии используют стандартные LaTeX-команды (\raggedright,\centering,\raggedleft)- Не-
flushверсии реализованы через TikZ и могут давать более сбалансированное расположение с переносами
Вертикальное выравнивание имеет смысл только при явно заданной высоте бокса
Параметры
scaleиscale*масштабируют текст по вертикали, что может быть полезно для точного заполнения пространства
7.1.8 - Команды для управления размерами и отступами в боксах
Управление геометрией в tcolorbox
4.7.1 Ширина (Width)
| Команда | Синтаксис | Описание | Пример |
|---|---|---|---|
width | /tcb/width=⟨length⟩ | Устанавливает общую ширину бокса | width=\linewidth/2 |
text width | /tcb/text width=⟨length⟩ | Устанавливает ширину текста в верхней части | text width=4cm |
add to width | /tcb/add to width=⟨length⟩ | Добавляет значение к текущей ширине бокса | add to width=1cm |
4.7.2 Границы (Rules)
| Команда | Синтаксис | Описание | Пример |
|---|---|---|---|
toprule | /tcb/toprule=⟨length⟩ | Толщина верхней границы | toprule=3mm |
bottomrule | /tcb/bottomrule=⟨length⟩ | Толщина нижней границы | bottomrule=3mm |
leftrule | /tcb/leftrule=⟨length⟩ | Толщина левой границы | leftrule=3mm |
rightrule | /tcb/rightrule=⟨length⟩ | Толщина правой границы | rightrule=3mm |
titlerule | /tcb/titlerule=⟨length⟩ | Толщина линии под заголовком | titlerule=3mm |
boxrule | /tcb/boxrule=⟨length⟩ | Устанавливает толщину всех границ | boxrule=3mm |
4.7.3 Скругления (Arcs)
| Команда | Синтаксис | Описание | Пример |
|---|---|---|---|
arc | /tcb/arc=⟨length⟩ | Радиус скругления углов | arc=3mm |
circular arc | /tcb/circular arc | Делает бокс круглым (при равных ширине и высоте) | circular arc |
bean arc | /tcb/bean arc | Автоматический радиус скругления | bean arc |
octogon arc | /tcb/octogon arc | Создает восьмиугольник | octogon arc |
arc is angular | /tcb/arc is angular | Заменяет скругления на углы | arc is angular |
arc is curved | /tcb/arc is curved | Восстанавливает скругления (по умолчанию) | arc is curved |
outer arc | /tcb/outer arc=⟨length⟩ | Внешний радиус скругления | outer arc=1mm |
auto outer arc | /tcb/auto outer arc | Автоматический внешний радиус | auto outer arc |
4.7.4 Отступы (Spacing)
| Команда | Синтаксис | Описание | Пример |
|---|---|---|---|
boxsep | /tcb/boxsep=⟨length⟩ | Общий внутренний отступ | boxsep=5mm |
left | /tcb/left=⟨length⟩ | Левый отступ для всех частей | left=0mm |
left* | /tcb/left*=⟨length⟩ | Левый отступ от границы | left*=0mm |
lefttitle | /tcb/lefttitle=⟨length⟩ | Левый отступ заголовка | lefttitle=3cm |
leftupper | /tcb/leftupper=⟨length⟩ | Левый отступ верхней части | leftupper=3cm |
leftlower | /tcb/leftlower=⟨length⟩ | Левый отступ нижней части | leftlower=3cm |
right | /tcb/right=⟨length⟩ | Правый отступ для всех частей | right=2cm |
right* | /tcb/right*=⟨length⟩ | Правый отступ от границы | right*=0mm |
righttitle | /tcb/righttitle=⟨length⟩ | Правый отступ заголовка | righttitle=2cm |
rightupper | /tcb/rightupper=⟨length⟩ | Правый отступ верхней части | rightupper=2cm |
rightlower | /tcb/rightlower=⟨length⟩ | Правый отступ нижней части | rightlower=2cm |
top | /tcb/top=⟨length⟩ | Верхний отступ | top=0mm |
toptitle | /tcb/toptitle=⟨length⟩ | Верхний отступ заголовка | toptitle=3mm |
bottom | /tcb/bottom=⟨length⟩ | Нижний отступ | bottom=0mm |
bottomtitle | /tcb/bottomtitle=⟨length⟩ | Нижний отступ заголовка | bottomtitle=3mm |
middle | /tcb/middle=⟨length⟩ | Отступ между частями | middle=0mm |
4.7.5 Размеры (Size Shortcuts)
| Команда | Синтаксис | Описание | Пример |
|---|---|---|---|
size | /tcb/size=⟨name⟩ | Предустановленные размеры: normal, title, small, fbox, tight, minimal | size=small |
oversize | /tcb/oversize=⟨length⟩ | Расширяет ширину за пределы страницы | oversize |
4.7.6 Переключение сторон (Toggle Left and Right)
| Команда | Синтаксис | Описание | Пример |
|---|---|---|---|
toggle left and right | /tcb/toggle left and right=⟨toggle preset⟩ | Переключает левую и правую стороны (none, forced, evenpage) | toggle left and right=evenpage |
Примеры использования
Настройка ширины
\begin{tcolorbox}[width=0.5\linewidth, text width=4cm]
Бокс с ограниченной шириной текста
\end{tcolorbox}
Границы и скругления
\begin{tcolorbox}[
boxrule=2mm,
arc=5mm,
arc is angular,
toprule=3mm,
bottomrule=1mm
]
Бокс с нестандартными границами
\end{tcolorbox}
Отступы
\begin{tcolorbox}[
boxsep=2mm,
left=1cm,
right*=0mm,
toptitle=5mm
]
Бокс с кастомными отступами
\end{tcolorbox}
Размеры
\begin{tcolorbox}[size=small, oversize]
Компактный бокс, расширенный за поля
\end{tcolorbox}
Переключение сторон
\begin{tcolorbox}[
toggle left and right=evenpage,
leftrule=1cm,
rightrule=1mm
]
Бокс с переключением границ на четных страницах
\end{tcolorbox}
7.1.9 - Команды для управления параметрами углов в боксах
Управление углами (Corners) в tcolorbox
Основные команды для работы с углами
| Команда | Синтаксис | Допустимые значения | Описание | Пример |
|---|---|---|---|---|
sharp corners | /tcb/sharp corners=⟨position⟩ | northwest, northeast, southwest, southeast, north, south, east, west, downhill, uphill, all | Делает указанные углы острыми | sharp corners=northwest |
rounded corners | /tcb/rounded corners=⟨position⟩ | Те же, что для sharp corners | Делает указанные углы скругленными (по умолчанию) | rounded corners=all |
sharpish corners | /tcb/sharpish corners | - | Делает углы визуально острыми (технически остаются скругленными) | sharpish corners |
Особенности работы с углами:
- По умолчанию все углы скруглены (
rounded corners=all) sharpish corners- это компромиссный вариант, когда углы выглядят острыми, но технически остаются скругленными (влияет на тени и границы)- Можно комбинировать разные типы углов в одном боксе
Примеры использования
1. Острые углы
\begin{tcolorbox}[
colback=white,
colframe=blue,
sharp corners=northwest, % только северо-западный угол острый
title=Бокс с острым углом
]
Содержимое бокса
\end{tcolorbox}
2. Полностью острый бокс
\begin{tcolorbox}[
colback=white,
colframe=red,
sharp corners, % все углы острые
title=Полностью острый бокс
]
Содержимое бокса
\end{tcolorbox}
3. Комбинирование углов
\begin{tcolorbox}[
colback=white,
colframe=green,
sharp corners=north, % верхние углы острые
rounded corners=south, % нижние углы скругленные
title=Комбинированный бокс
]
Содержимое бокса
\end{tcolorbox}
4. Sharpish corners
\begin{tcolorbox}[
colback=white,
colframe=purple,
sharpish corners, # углы выглядят острыми
title=Бокс с sharpish corners
]
Содержимое бокса
\end{tcolorbox}
Визуальные различия:
Обычные скругленные углы (
rounded corners):- Плавные изгибы
- Тени и границы полностью повторяют форму
Sharpish corners:
- Углы выглядят почти острыми
- Тени и границы слегка скруглены
Полностью острые углы (
sharp corners):- Четкие прямые углы
- Тени и границы имеют острые края
Советы по использованию:
- Для большинства случаев достаточно
sharp cornersилиrounded corners - Используйте
sharpish corners, если нужен компромисс между внешним видом и поведением теней - Можно точечно менять отдельные углы для создания уникальных дизайнов
- Настройки углов влияют на:
- Основную рамку бокса
- Границы (
borderline) - Тени (
shadow)
7.1.10 - Команды для управления прозрачностью в боксах
Таблица управления прозрачностью в tcolorbox
Основные параметры прозрачности
| Параметр | Синтаксис | Описание | Диапазон значений | Пример |
|---|---|---|---|---|
opacityframe | /tcb/opacityframe=⟨fraction⟩ | Прозрачность рамки | 0.0 (полная прозрачность) - 1.0 (непрозрачный) | opacityframe=0.5 |
opacityback | /tcb/opacityback=⟨fraction⟩ | Прозрачность фона содержимого | 0.0-1.0 | opacityback=0.3 |
opacitybacktitle | /tcb/opacitybacktitle=⟨fraction⟩ | Прозрачность фона заголовка | 0.0-1.0 | opacitybacktitle=0.7 |
opacityfill | /tcb/opacityfill=⟨fraction⟩ | Прозрачность заливки (рамка + фон + заголовок) | 0.0-1.0 | opacityfill=0.6 |
opacityupper | /tcb/opacityupper=⟨fraction⟩ | Прозрачность текста верхней части | 0.0-1.0 | opacityupper=0.4 |
opacitylower | /tcb/opacitylower=⟨fraction⟩ | Прозрачность текста нижней части | 0.0-1.0 | opacitylower=0.8 |
opacitytext | /tcb/opacitytext=⟨fraction⟩ | Прозрачность всего текста (верх + низ) | 0.0-1.0 | opacitytext=0.5 |
opacitytitle | /tcb/opacitytitle=⟨fraction⟩ | Прозрачность текста заголовка | 0.0-1.0 | opacitytitle=0.9 |
Примеры использования
1. Полупрозрачная рамка и фон
\begin{tcolorbox}[
colframe=blue,
colback=white,
opacityframe=0.3,
opacityback=0.7,
title=Пример прозрачности
]
Этот бокс имеет полупрозрачную рамку и фон
\end{tcolorbox}
2. Прозрачный заголовок
\begin{tcolorbox}[
colframe=red,
colbacktitle=yellow,
opacitybacktitle=0.5,
opacitytitle=0.8,
title=Прозрачный заголовок
]
Текст содержимого
\end{tcolorbox}
3. Разная прозрачность частей
\begin{tcolorbox}[
opacityupper=0.9,
opacitylower=0.5,
opacityframe=0.6,
opacityback=0.8
]
Верхний текст более непрозрачный
\tcblower
Нижний текст более прозрачный
\end{tcolorbox}
4. Комплексный пример с jigsaw-скином
\begin{tcolorbox}[
enhanced jigsaw,
colframe=green!75!black,
colback=green!10!white,
opacityframe=0.4,
opacityback=0.6,
opacitybacktitle=0.8,
opacitytitle=1.0,
title=Сложный пример
]
Бокс с различными настройками прозрачности
\end{tcolorbox}
Особенности работы с прозрачностью:
Визуальные эффекты:
- Значение 0.0 делает элемент полностью невидимым
- Значение 1.0 - полностью непрозрачным
- Промежуточные значения создают эффект просвечивания
Рекомендации:
- Для лучшего визуального восприятия используйте значения в диапазоне 0.3-0.8
- Прозрачность особенно эффектна при наложении элементов или использовании фоновых изображений
- В сочетании с jigsaw-скинами можно создавать интересные дизайнерские решения
Технические ограничения:
- Прозрачность может по-разному отображаться в различных PDF-ридерах
- При печати эффекты прозрачности могут не сохраняться в зависимости от принтера
Комбинации:
- Можно комбинировать несколько параметров прозрачности для одного бокса
- Эффекты прозрачности суммируются при наложении элементов
Эти параметры позволяют создавать сложные визуальные эффекты и гибко управлять внешним видом элементов tcolorbox.
7.1.11 - Команды для управления высотой боксов
Управление высотой в tcolorbox
Основные параметры высоты
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
natural height | /tcb/natural height | Естественная высота по содержимому | natural height |
height | /tcb/height=⟨length⟩ | Фиксированная высота бокса | height=3cm |
height plus | /tcb/height plus=⟨length⟩ | Максимальное увеличение высоты | height plus=1cm |
height from | /tcb/height from=⟨min⟩ to ⟨max⟩ | Диапазон высот | height from=2cm to 5cm |
text height | /tcb/text height=⟨length⟩ | Высота текстовой области | text height=4cm |
add to height | /tcb/add to height=⟨length⟩ | Добавление к текущей высоте | add to height=0.5cm |
add to natural height | /tcb/add to natural height=⟨length⟩ | Добавление к естественной высоте | add to natural height=1cm |
height fill | /tcb/height fill=true|false|maximum | Заполнение оставшегося пространства | height fill=true |
inherit height | /tcb/inherit height=⟨fraction⟩ | Наследование высоты от родителя | inherit height=0.8 |
square | /tcb/square | Квадратный бокс (высота=ширине) | square |
Распределение пространства
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
space | /tcb/space=⟨fraction⟩ | Распределение пространства (0-1) | space=0.3 |
space to upper | /tcb/space to upper | Все пространство в верхнюю часть | space to upper |
space to lower | /tcb/space to lower | Все пространство в нижнюю часть | space to lower |
space to both | /tcb/space to both | Равное распределение | space to both |
space to | /tcb/space to=⟨macro⟩ | Сохранение пространства в макрос | space to=\myspace |
split | /tcb/split=⟨fraction⟩ | Позиция разделителя (0-1) | split=0.7 |
Группы высот
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
equal height group | /tcb/equal height group=⟨id⟩ | Группа с одинаковой высотой | equal height group=A |
minimum for equal height group | /tcb/minimum for equal height group=⟨id⟩:⟨length⟩ | Минимальная высота группы | minimum for equal height group=A:3cm |
minimum for current equal height group | /tcb/minimum for current equal height group=⟨length⟩ | Минимальная высота текущей группы | minimum for current equal height group=2cm |
use height from group | /tcb/use height from group=⟨id⟩ | Использование высоты группы | use height from group=A |
\tcbheightfromgroup | \tcbheightfromgroup{⟨macro⟩}{⟨id⟩} | Получение высоты группы | \tcbheightfromgroup{\myheight}{A} |
Примеры использования
1. Фиксированная высота
\begin{tcolorbox}[height=4cm, valign=center]
Бокс с фиксированной высотой 4cm
\end{tcolorbox}
2. Автоматическое выравнивание высоты
\begin{tcolorbox}[equal height group=A]
Первый бокс
\end{tcolorbox}
\begin{tcolorbox}[equal height group=A]
Второй бокс с большим количеством текста, который делает высоту больше
\end{tcolorbox}
3. Заполнение пространства
\begin{tcolorbox}[height fill]
Бокс заполнит все доступное вертикальное пространство
\end{tcolorbox}
4. Квадратный бокс
\begin{tcolorbox}[width=3cm, square]
Квадратный бокс 3x3cm
\end{tcolorbox}
5. Наследование высоты
\begin{tcolorbox}[height=5cm]
\begin{tcolorbox}[inherit height=0.5]
Бокс с половиной высоты родителя
\end{tcolorbox}
\end{tcolorbox}
Особенности работы с высотой:
- Для работы некоторых параметров (
height fill) требуется библиотекаbreakable - Параметры групп высот требуют двойной компиляции
natural height- это высота по умолчанию, рассчитываемая автоматически- При использовании
equal height groupвсе боксы в группе получают высоту самого высокого бокса height plusпозволяет задать максимально возможное увеличение высоты при необходимости
7.1.12 - Команды для добавления различного контента в боксы
Управление содержимым бокса в tcolorbox
Добавление контента в различные части бокса
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
before title | /tcb/before title=⟨code⟩ | Код перед заголовком (с \ignorespaces) | before title={\textbf{Важно:}~} |
before title* | /tcb/before title*=⟨code⟩ | Код перед заголовком (без \ignorespaces) | before title*={\textbf{Важно:}} |
after title | /tcb/after title=⟨code⟩ | Код после заголовка (с \unskip) | after title={\hfill\small[подпись]} |
after title* | /tcb/after title*=⟨code⟩ | Код после заголовка (без \unskip) | after title*={\quad[подпись]} |
before upper | /tcb/before upper=⟨code⟩ | Код перед верхней частью (с \ignorespaces) | before upper={\begin{quote}} |
before upper* | /tcb/before upper*=⟨code⟩ | Код перед верхней частью (без \ignorespaces) | before upper*=\begin{tabular} |
after upper | /tcb/after upper=⟨code⟩ | Код после верхней части (с \unskip) | after upper={\end{quote}} |
after upper* | /tcb/after upper*=⟨code⟩ | Код после верхней части (без \unskip) | after upper*=\end{tabular} |
before lower | /tcb/before lower=⟨code⟩ | Код перед нижней частью (с \ignorespaces) | before lower={\textbf{Примечание:}} |
before lower* | /tcb/before lower*=⟨code⟩ | Код перед нижней частью (без \ignorespaces) | before lower*=\begin{itemize} |
after lower | /tcb/after lower=⟨code⟩ | Код после нижней части (с \unskip) | after lower={\hfill\footnotesize*} |
after lower* | /tcb/after lower*=⟨code⟩ | Код после нижней части (без \unskip) | after lower*=\end{itemize} |
Специальные окружения для контента
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
text fill | /tcb/text fill | Включает minipage для вертикального выравнивания | text fill |
tabulars | /tcb/tabulars=⟨preamble⟩ | Окружает контент tabular* | tabulars={lcr} |
tabulars* | /tcb/tabulars*={⟨code⟩}{⟨preamble⟩} | Tabular* с дополнительным кодом | tabulars*={\small}{lcr} |
tabularx | /tcb/tabularx=⟨preamble⟩ | Окружает контент tabularx | `tabularx={X |
tabularx* | /tcb/tabularx*={⟨code⟩}{⟨preamble⟩} | Tabularx с дополнительным кодом | `tabularx*={\footnotesize}{X |
tikz upper | /tcb/tikz upper=⟨options⟩ | Окружает верхнюю часть tikzpicture | tikz upper={scale=0.5} |
tikz lower | /tcb/tikz lower=⟨options⟩ | Окружает нижнюю часть tikzpicture | tikz lower={rotate=30} |
tikznode upper | /tcb/tikznode upper=⟨options⟩ | Помещает контент в TikZ node | tikznode upper={draw} |
tikznode lower | /tcb/tikznode lower=⟨options⟩ | Помещает нижнюю часть в TikZ node | tikznode lower={fill=yellow} |
tikznode | /tcb/tikznode=⟨options⟩ | Применяет tikznode к обеим частям | tikznode={shape=circle} |
varwidth upper | /tcb/varwidth upper=⟨length⟩ | Окружает varwidth окружением | varwidth upper=5cm |
environment upper | /tcb/environment upper=⟨name⟩ | Окружает верхнюю часть указанным окружением | environment upper=itemize |
environment upper args | /tcb/environment upper args={⟨name⟩}{⟨code⟩} | Окружение с дополнительными параметрами | environment upper args={tabular}{{cc}} |
environment lower | /tcb/environment lower=⟨name⟩ | Окружает нижнюю часть указанным окружением | environment lower=enumerate |
environment lower args | /tcb/environment lower args={⟨name⟩}{⟨code⟩} | Окружение с дополнительными параметрами | environment lower args={tabular}{{lr}} |
environment title | /tcb/environment title=⟨name⟩ | Окружает заголовок указанным окружением | environment title=center |
environment title args | /tcb/environment title args={⟨name⟩}{⟨code⟩} | Окружение с дополнительными параметрами | environment title args={flushright}{} |
Примеры использования
1. Добавление текста вокруг содержимого
\begin{tcolorbox}[
before title={\textbf{Внимание:}~},
after title={\hfill\footnotesize[источник]},
before upper={\textit{Начало текста:}\par},
after upper={\par\hfill\textit{окончание}}
]
Заголовок
\tcblower
Основное содержимое бокса
\end{tcolorbox}
2. Использование окружений
\begin{tcolorbox}[
environment upper=itemize,
environment lower args={tabular}{{ll}}
\item Первый пункт
\item Второй пункт
\tcblower
A & B \\
C & D
\end{tcolorbox}
3. Таблицы в боксе
\begin{tcolorbox}[
tabulars={|l|c|r|},
title=Таблица в боксе
]
Левый & Центр & Правый \\
A & B & C
\end{tcolorbox}
4. TikZ рисунки
\begin{tcolorbox}[
tikz upper={scale=0.8},
title=TikZ рисунок
]
\draw (0,0) circle (1cm);
\fill (0,0) circle (2pt);
\end{tcolorbox}
Особенности работы:
- Параметры с
*(например,before upper*) не добавляют автоматические пробелы (\ignorespaces/\unskip) - Для работы
tabulars/tabularxтребуются соответствующие пакеты text fillполезен для вертикального выравнивания с\vfill- TikZ-окружения позволяют легко встраивать графику
- Окружения
environmentне работают с другими tcolorbox-окружениями
7.1.13 - Команды для упрвления слоями в боксах
Управление наложениями (Overlays) в tcolorbox
Основные параметры наложений
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
overlay | /tcb/overlay=⟨graphical code⟩ | Графическое наложение для всех состояний бокса | overlay={\draw[red] (frame.south west) rectangle (frame.north east);} |
no overlay | /tcb/no overlay | Отключает все наложения | no overlay |
overlay broken | /tcb/overlay broken=⟨graphical code⟩ | Наложение только для разорванных боксов | overlay broken={\draw[dashed] (frame.south west) -- (frame.north east);} |
overlay unbroken | /tcb/overlay unbroken=⟨graphical code⟩ | Наложение только для целых боксов | overlay unbroken={\fill[yellow] (frame.center) circle (5mm);} |
overlay first | /tcb/overlay first=⟨graphical code⟩ | Наложение для первой части разорванного бокса | overlay first={\node at (frame.center) {First};} |
overlay middle | /tcb/overlay middle=⟨graphical code⟩ | Наложение для средних частей разорванного бокса | overlay middle={\node at (frame.center) {Middle};} |
overlay last | /tcb/overlay last=⟨graphical code⟩ | Наложение для последней части разорванного бокса | overlay last={\node at (frame.center) {Last};} |
Комбинированные параметры
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
overlay unbroken and first | /tcb/overlay unbroken and first=⟨graphical code⟩ | Комбинация unbroken и first | overlay unbroken and first={\draw[blue] (frame.south west) -- (frame.north east);} |
overlay middle and last | /tcb/overlay middle and last=⟨graphical code⟩ | Комбинация middle и last | overlay middle and last={\draw[green] (frame.south west) -- (frame.north east);} |
overlay unbroken and last | /tcb/overlay unbroken and last=⟨graphical code⟩ | Комбинация unbroken и last | overlay unbroken and last={\draw[red] (frame.south west) -- (frame.north east);} |
overlay first and middle | /tcb/overlay first and middle=⟨graphical code⟩ | Комбинация first и middle | overlay first and middle={\draw[yellow] (frame.south west) -- (frame.north east);} |
Примеры использования
1. Простое наложение
\begin{tcolorbox}[
enhanced,
overlay={\draw[red, line width=2pt] (frame.south west) rectangle (frame.north east);},
title=Пример с наложением
]
Содержимое бокса с красной рамкой
\end{tcolorbox}
2. Наложение для разорванных боксов
\begin{tcolorbox}[
breakable,
overlay first={\node[rotate=45] at (frame.center) {Начало};},
overlay middle={\node[rotate=45] at (frame.center) {Продолжение};},
overlay last={\node[rotate=45] at (frame.center) {Конец};},
title=Разорванный бокс
]
Много текста, который будет разорван на несколько частей...
\end{tcolorbox}
3. Комбинированное наложение
\begin{tcolorbox}[
enhanced,
overlay unbroken and first={\fill[yellow!50] (frame.north west) rectangle ([xshift=2cm]frame.north east);},
title=Комбинированный пример
]
Содержимое бокса с желтой полосой вверху для unbroken/first состояний
\end{tcolorbox}
4. Водяной знак
\begin{tcolorbox}[
enhanced,
overlay={\node[rotate=45,scale=10,text=gray!20] at (frame.center) {ЧЕРНОВИК};},
title=Документ с водяным знаком
]
Текст документа с полупрозрачным водяным знаком
\end{tcolorbox}
Особенности работы с наложениями:
- Для сложных наложений рекомендуется использовать
enhancedрежим из библиотекиskins - Наложения применяются после рисования рамки и фона, но перед отображением текста
- Для позиционирования элементов можно использовать узлы геометрии (
frame.north west,title.southи т.д.) - При работе с разорванными боксами (
breakable) можно задавать разные наложения для разных частей - Наложения могут содержать любые допустимые TikZ-команды
Советы:
- Используйте
overlayдля элементов, которые должны отображаться всегда - Для разорванных боксов применяйте
overlay first/middle/lastдля разных частей - Комбинированные параметры (
unbroken and firstи т.д.) помогают избежать дублирования кода - Для сложных графических элементов создавайте стили с наложениями и переиспользуйте их
7.1.14 - Команды для управления плавающими объектами боксов
Управление плавающими объектами (Floating Objects) в tcolorbox
Основные параметры плавающих объектов
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
floatplacement | /tcb/floatplacement=⟨values⟩ | Устанавливает параметры размещения по умолчанию | floatplacement=tbp |
float | /tcb/float=⟨values⟩ | Превращает бокс в плавающий объект | float=ht |
float* | /tcb/float*=⟨values⟩ | Плавающий объект на всю ширину страницы | float*=b, width=\textwidth |
nofloat | /tcb/nofloat | Отключает плавающее поведение | nofloat |
every float | /tcb/every float={⟨code⟩} | Код, выполняемый перед каждым плавающим объектом | every float=\centering |
before float | /tcb/before float={⟨code⟩} | Код перед началом float-окружения | before float=\small |
after float | /tcb/after float={⟨code⟩} | Код после окончания float-окружения | after float=\vspace{1cm} |
Примеры использования
1. Базовый плавающий бокс
\begin{tcolorbox}[
float=htb,
title=Пример плавающего бокса,
colback=blue!5!white,
colframe=blue!75!black
]
Этот бокс будет автоматически размещен в подходящем месте документа
(обычно вверху страницы, если возможно).
\end{tcolorbox}
2. Плавающий бокс на всю ширину
\begin{tcolorbox}[
float*=t,
width=\textwidth,
title=Широкий плавающий бокс,
colback=green!5!white,
colframe=green!75!black
]
Этот бокс занимает всю ширину страницы и будет размещен вверху.
\end{tcolorbox}
3. Центрирование плавающих объектов
\begin{tcolorbox}[
float,
every float=\centering,
title=Центрированный плавающий бокс,
colback=red!5!white,
colframe=red!75!black
]
Этот плавающий бокс будет центрирован на странице.
\end{tcolorbox}
4. Плавающий бокс с дополнительным кодом
\begin{tcolorbox}[
float,
before float={\small Начало float-окружения},
after float={\vspace{5mm} Конец float-окружения},
title=Бокс с дополнительным кодом,
colback=yellow!5!white,
colframe=yellow!75!black
]
Этот плавающий бокс имеет дополнительный код до и после.
\end{tcolorbox}
Особенности работы с плавающими объектами:
Параметры размещения (для
floatиfloat*):h- здесь (если возможно)t- вверху страницыb- внизу страницыp- на отдельной странице!- принудительное размещение
Различия между
floatиfloat*:floatработает как стандартное плавающее окружениеfloat*предназначен для:- Двухколоночных документов
- Использования с пакетами multicol/paracol
- Широких боксов (требует
width=\textwidth)
Отключение плавающего поведения:
- Используйте
nofloatдля возврата к обычному поведению
- Используйте
Особые случаи:
- Для разрываемых боксов (
breakable)every floatвыполняется перед каждой частью before floatиafter floatпозволяют вставить код до/после float-окружения
- Для разрываемых боксов (
Советы по использованию:
- Для изображений и широких таблиц лучше использовать
float* - Комбинация
every float=\centeringполезна для центрирования содержимого - При использовании в двухколоночном режиме не забывайте указывать
width=\textwidth - Для точного контроля размещения используйте комбинации параметров (например,
float=!bдля принудительного размещения внизу)
7.1.15 - Команды для встраивания объектов и боксов в боксы (embedding)
Управление встраиванием (Embedding) в tcolorbox
Основные параметры встраивания
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
before | /tcb/before=⟨code⟩ | Код, выполняемый перед боксом | before={\par\medskip} |
after | /tcb/after=⟨code⟩ | Код, выполняемый после бокса | after={\par\medskip} |
nobeforeafter | /tcb/nobeforeafter | Отключает пробелы до/после бокса | nobeforeafter |
force nobeforeafter | /tcb/force nobeforeafter | Принудительно отключает пробелы | force nobeforeafter |
Вертикальные отступы
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
before skip balanced | /tcb/before skip balanced=⟨glue⟩ | Вертикальный отступ с учетом базовой линии | before skip balanced=1cm |
after skip balanced | /tcb/after skip balanced=⟨glue⟩ | Вертикальный отступ после с базовой линией | after skip balanced=1cm |
beforeafter skip balanced | /tcb/beforeafter skip balanced=⟨glue⟩ | Отступы до/после с базовой линией | beforeafter skip balanced=0.5cm |
before skip | /tcb/before skip=⟨glue⟩ | Простой вертикальный отступ перед | before skip=10pt |
after skip | /tcb/after skip=⟨glue⟩ | Простой вертикальный отступ после | after skip=10pt |
beforeafter skip | /tcb/beforeafter skip=⟨glue⟩ | Простые отступы до/после | beforeafter skip=10pt |
Горизонтальные отступы
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
left skip | /tcb/left skip=⟨length⟩ | Горизонтальный отступ слева | left skip=1cm |
right skip | /tcb/right skip=⟨length⟩ | Горизонтальный отступ справа | right skip=1cm |
leftright skip | /tcb/leftright skip=⟨length⟩ | Отступы слева и справа | leftright skip=1cm |
Выравнивание и позиционирование
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
baseline | /tcb/baseline=⟨length⟩ | Установка базовой линии | baseline=3mm |
box align | /tcb/box align=⟨alignment⟩ | Выравнивание бокса (bottom, top, center, base) | box align=top |
Особые параметры
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
ignore nobreak | `/tcb/ignore nobreak=true | false` | Игнорировать запрет разрыва после заголовка |
before nobreak | /tcb/before nobreak=⟨code⟩ | Код перед боксом при запрете разрыва | before nobreak={\noindent} |
parfillskip restore | `/tcb/parfillskip restore=true | false` | Восстанавливать значение \parfillskip |
Примеры использования
1. Базовые вертикальные отступы
\begin{tcolorbox}[
before skip balanced=1cm,
after skip balanced=0.5cm,
colframe=blue
]
Бокс с кастомными отступами
\end{tcolorbox}
2. Горизонтальное позиционирование
\begin{tcolorbox}[
left skip=2cm,
right skip=1cm,
colframe=red
]
Бокс со смещением по горизонтали
\end{tcolorbox}
3. Выравнивание по базовой линии
Текст \begin{tcolorbox}[nobeforeafter, box align=base, colframe=green]
Выровнено по базовой линии
\end{tcolorbox} продолжение текста
4. Интеграция в поток текста
\begin{tcolorbox}[
nobeforeafter,
box align=base,
colback=yellow,
colframe=orange
]
Встроенный в текст бокс
\end{tcolorbox} продолжение текста.
Особенности работы:
- Параметры
*balancedучитывают базовую линию текста для более точного выравнивания nobeforeafterполностью убирает бокс из отдельного абзаца- Для точного контроля вертикального положения используйте комбинацию
baselineиbox align - Параметры с
skipизменяют bounding box, что может влиять на общий макет
Советы:
- Для встраивания в текст используйте
nobeforeafter+box align=base - Для сложных макетов предпочтительнее
*balancedверсии отступов - При работе с разрываемыми боксами учитывайте поведение
ignore nobreak - Для восстановления стандартного поведения
\parfillskipиспользуйтеparfillskip restore
7.1.16 - Управление ограничивающей рамкой (Bounding Box) в tcolorbox
Управление ограничивающей рамкой (Bounding Box) в tcolorbox
Смещение границ ограничивающей рамки
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
enlarge top initially by | /tcb/enlarge top initially by=⟨length⟩ | Расширение верхней границы (только для первого бокса) | enlarge top initially by=5mm |
enlarge bottom finally by | /tcb/enlarge bottom finally by=⟨length⟩ | Расширение нижней границы (только для последнего бокса) | enlarge bottom finally by=5mm |
enlarge top at break by | /tcb/enlarge top at break by=⟨length⟩ | Расширение верхней границы для разорванных частей | enlarge top at break by=3mm |
enlarge bottom at break by | /tcb/enlarge bottom at break by=⟨length⟩ | Расширение нижней границы для разорванных частей | enlarge bottom at break by=3mm |
enlarge top by | /tcb/enlarge top by=⟨length⟩ | Расширение верхней границы для всех случаев | enlarge top by=5mm |
enlarge bottom by | /tcb/enlarge bottom by=⟨length⟩ | Расширение нижней границы для всех случаев | enlarge bottom by=5mm |
enlarge left by | /tcb/enlarge left by=⟨length⟩ | Расширение левой границы | enlarge left by=2cm |
enlarge right by | /tcb/enlarge right by=⟨length⟩ | Расширение правой границы | enlarge right by=2cm |
enlarge by | /tcb/enlarge by=⟨length⟩ | Расширение всех границ | enlarge by=5mm |
Выравнивание бокса
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
grow to left by | /tcb/grow to left by=⟨length⟩ | Увеличение ширины влево | grow to left by=2cm |
grow to right by | /tcb/grow to right by=⟨length⟩ | Увеличение ширины вправо | grow to right by=2cm |
grow sidewards by | /tcb/grow sidewards by=⟨length⟩ | Увеличение ширины в обе стороны | grow sidewards by=2cm |
flush left | /tcb/flush left | Выравнивание влево | flush left |
flush right | /tcb/flush right | Выравнивание вправо | flush right |
center | /tcb/center | Центрирование | center |
Переключение расширений
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
toggle enlargement | /tcb/toggle enlargement=⟨toggle preset⟩ | Переключение расширений (none, forced, evenpage) | toggle enlargement=evenpage |
Растягивание до границ страницы
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
spread inwards | /tcb/spread inwards=⟨length⟩ | Растягивание к внутреннему краю страницы | spread inwards=5mm |
spread outwards | /tcb/spread outwards=⟨length⟩ | Растягивание к внешнему краю страницы | spread outwards=5mm |
move upwards | /tcb/move upwards=⟨length⟩ | Перемещение к верхнему краю (с новой страницы) | move upwards=5mm |
move upwards* | /tcb/move upwards*=⟨length⟩ | Перемещение к верхнему краю (без новой страницы) | move upwards*=5mm |
fill downwards | /tcb/fill downwards=⟨length⟩ | Заполнение до нижнего края | fill downwards=5mm |
spread upwards | /tcb/spread upwards=⟨length⟩ | Комбинация: вверх + внутрь + наружу | spread upwards=5mm |
spread upwards* | /tcb/spread upwards*=⟨length⟩ | То же без новой страницы | spread upwards*=5mm |
spread sidewards | /tcb/spread sidewards=⟨length⟩ | Растягивание в стороны | spread sidewards=5mm |
spread | /tcb/spread=⟨length⟩ | Заполнение всей страницы | spread=5mm |
spread downwards | /tcb/spread downwards=⟨length⟩ | Комбинация: вниз + внутрь + наружу | spread downwards=5mm |
Выступание бокса
| Параметр | Синтаксис | Описание | Пример |
|---|---|---|---|
shrink tight | /tcb/shrink tight | Плотное облегание содержимого | shrink tight |
extrude left by | /tcb/extrude left by=⟨length⟩ | Выступание влево | extrude left by=1cm |
extrude right by | /tcb/extrude right by=⟨length⟩ | Выступание вправо | extrude right by=1cm |
extrude top by | /tcb/extrude top by=⟨length⟩ | Выступание вверх | extrude top by=1cm |
extrude bottom by | /tcb/extrude bottom by=⟨length⟩ | Выступание вниз | extrude bottom by=1cm |
extrude by | /tcb/extrude by=⟨length⟩ | Выступание во все стороны | extrude by=5mm |
Примеры использования
1. Расширение границ
\begin{tcolorbox}[
enlarge left by=2cm,
enlarge top by=5mm,
enhanced,
show bounding box
]
Бокс с расширенными границами
\end{tcolorbox}
2. Растягивание до краев страницы
\begin{tcolorbox}[
spread sidewards,
spread upwards,
height=3cm,
colframe=blue,
sharp corners=north
]
Бокс, растянутый до краев страницы
\end{tcolorbox}
3. Выступающие элементы
Текст \tcbox[shrink tight, extrude right by=5mm]{с выступающим} элементом
Особенности работы:
- Параметры с
*не создают новую страницу - Для визуализации bounding box используйте
show bounding box - Комбинированные параметры (
spreadи др.) экономят время настройки - Выступающие элементы (
extrude) не изменяют bounding box
7.1.17 - Управление уровнями/слоями в пакете tcolorbox
1. Основные команды для управления слоями
| Команда / Стиль | Синтаксис | Описание |
|---|---|---|
every box | \tcbset{every box/.style={...}} | Стиль, применяемый ко всем tcolorbox (по умолчанию пуст). |
every box on layer n | \tcbset{every box on layer 1/.style={...}} | Стиль для конкретного слоя (1-4 по умолчанию). |
every box on higher layers | \tcbset{every box on higher layers/.style={...}} | Стиль для слоёв выше управляемых (по умолчанию reset,every box). |
\tcbsetmanagedlayers | \tcbsetmanagedlayers{<число>} | Устанавливает максимальный номер управляемого слоя (только в преамбуле). |
2. Примеры использования
Пример 1: Настройка стилей для всех слоёв
\usepackage{tcolorbox}
\tcbset{
every box/.style={enhanced, colframe=blue}, % Базовый стиль
every box on layer 2/.style={colback=yellow}, % Стиль для второго слоя
every box on higher layers/.style={colframe=red} % Стиль для вложенных
}
\begin{tcolorbox}[title=Layer 1]
Внешний блок.
\begin{tcolorbox}[title=Layer 2]
Вложенный блок (жёлтый фон).
\begin{tcolorbox}[title=Layer 3]
Ещё глубже (красная рамка).
\end{tcolorbox}
\end{tcolorbox}
\end{tcolorbox}
Пример 2: Сброс стилей (reset)
\tcbset{
every box/.style={fonttitle=\bfseries},
every box on layer 2/.style={reset, colback=green} % Сброс стилей перед применением
}
\begin{tcolorbox}[title=Layer 1]
Заголовок жирный.
\begin{tcolorbox}[title=Layer 2]
Заголовок НЕ жирный (сброшен), фон зелёный.
\end{tcolorbox}
\end{tcolorbox}
Пример 3: Увеличение числа управляемых слоёв
\usepackage{tcolorbox}
\tcbsetmanagedlayers{5} % В преамбуле
\tcbset{
every box on layer 5/.style={colframe=purple}
}
\begin{tcolorbox}[title=Layer 1]
\begin{tcolorbox}[title=Layer 2]
\begin{tcolorbox}[title=Layer 3]
\begin{tcolorbox}[title=Layer 4]
\begin{tcolorbox}[title=Layer 5]
Фиолетовая рамка (5-й слой).
\end{tcolorbox}
\end{tcolorbox}
\end{tcolorbox}
\end{tcolorbox}
\end{tcolorbox}
3. Важные примечания
- Команда
\tcbsetmanagedlayersработает только в преамбуле. - По умолчанию для вложенных блоков применяется
reset, что сбрасывает стили родительского блока. - Для глобального применения стиля используйте
\tcbsetforeverylayer{...}.
7.1.18 - Управление Capture mode в пакете tcolorbox
Capture Mode в tcolorbox
Capture Mode определяет, как содержимое tcolorbox обрабатывается и отображается.
Доступные режимы:
minipage(по умолчанию дляtcolorbox)hbox(по умолчанию для\tcbox)fitbox(требует библиотекуfitting)
1. Основные команды и стили
| Команда / Опция | Синтаксис | Описание |
|---|---|---|
capture=<mode> | \begin{tcolorbox}[capture=minipage] ... \end{tcolorbox} | Устанавливает режим обработки содержимого (minipage, hbox, fitbox). |
hbox (стиль) | \begin{tcolorbox}[hbox] ... \end{tcolorbox} | Короткая запись для capture=hbox. |
minipage (стиль) | \begin{tcolorbox}[minipage] ... \end{tcolorbox} | Короткая запись для capture=minipage. |
fitbox (стиль) | \begin{tcolorbox}[fitbox] ... \end{tcolorbox} | Короткая запись для capture=fitbox (требует \tcbuselibrary{fitting}). |
2. Примеры использования
2.1. Режим minipage (по умолчанию)
\begin{tcolorbox}[
capture=minipage, % можно опустить (стоит по умолчанию)
colframe=blue,
colback=white,
title=Minipage Mode
]
Этот блок ведёт себя как `minipage`.
Можно разбивать на части (`breakable`), добавлять верхнюю и нижнюю части.
\end{tcolorbox}
Особенности:
- Поддерживает
breakable(разрыв на страницах). - Можно использовать
upperиlowerчасти.
2.2. Режим hbox (как \tcbox)
\begin{tcolorbox}[
hbox, % короткая запись для capture=hbox
colframe=red,
colback=white,
title=HBox Mode
]
Этот блок ведёт себя как `\hbox` (аналогично `\tcbox`).
\end{tcolorbox}
Особенности:
- Нельзя разбивать (
breakableне работает). - Размер подстраивается под содержимое.
2.3. Режим fitbox (требует fitting)
\usepackage{tcolorbox}
\tcbuselibrary{fitting} % обязательно подключить
\begin{tcolorbox}[
fitbox, % короткая запись для capture=fitbox
height=2cm,
width=6cm,
colframe=green,
colback=white,
title=FitBox Mode
]
Содержимое масштабируется под размер блока.
\end{tcolorbox}
Особенности:
- Размер содержимого подгоняется под заданные размеры блока.
- Полезно для создания блоков фиксированного размера.
3. Сравнение режимов
| Режим | Разрыв (breakable) | Размер | Использование |
|---|---|---|---|
minipage | Да | Под содержимое | Основные блоки с текстом |
hbox | Нет | Под содержимое | Компактные блоки (\tcbox) |
fitbox | Нет | Фиксированный | Блоки с жёсткими размерами |
4. Полный пример с разными режимами
\documentclass{article}
\usepackage{tcolorbox}
\tcbuselibrary{fitting} % для fitbox
\begin{document}
\begin{tcolorbox}[
minipage, % или capture=minipage
colframe=blue,
title=Minipage Mode,
breakable % можно разрывать
]
Этот блок ведёт себя как `minipage`.
Можно разбивать на страницы и использовать `lower` и `upper` части.
\end{tcolorbox}
\begin{tcolorbox}[
hbox,
colframe=red,
title=HBox Mode
]
Это компактный блок (`\hbox`).
\end{tcolorbox}
\begin{tcolorbox}[
fitbox,
width=5cm,
height=3cm,
colframe=green,
title=FitBox Mode
]
Содержимое подгоняется под размер блока.
\end{tcolorbox}
\end{document}
Результат:
- Первый блок (
minipage) может быть разорван на страницы. - Второй блок (
hbox) компактный, без разрывов. - Третий блок (
fitbox) имеет фиксированный размер.
7.1.19 - Управление характеристиками текста в пакете tcolorbox
Text Characteristics в tcolorbox
Настройки оформления текста внутри tcolorbox позволяют управлять поведением абзацев, переносом слов и другими текстовыми характеристиками.
1. Основные команды и стили
| Опция | Синтаксис | Описание | Значение по умолчанию |
|---|---|---|---|
parbox | parbox=true / parbox=false | Определяет, будет ли текст обрабатываться как в minipage/parbox (влияет на форматирование абзацев). | true |
hyphenationfix | hyphenationfix=true / hyphenationfix=false | Включает исправление проблем с переносом длинных слов в узких блоках. | false |
2. Примеры использования
2.1. Опция parbox
Включает/отключает режим parbox (аналогично minipage).
Пример с parbox=true (по умолчанию)
\begin{tcolorbox}[
parbox=true, % можно не указывать (стоит по умолчанию)
width=0.45\linewidth,
colframe=blue,
title=parbox=true (стандартное поведение)
]
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
\end{tcolorbox}
Особенности:
- Абзацы форматируются как в
minipage. - Подходит для большинства случаев.
Пример с parbox=false
\begin{tcolorbox}[
parbox=false,
width=0.45\linewidth,
colframe=red,
title=parbox=false (обычный текст)
]
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
\end{tcolorbox}
Особенности:
- Текст ведёт себя как в основном документе (не как в
minipage). - Может вызывать неожиданные эффекты в сложных блоках.
2.2. Опция hyphenationfix
Исправляет проблемы с переносом длинных слов в узких блоках.
Пример без hyphenationfix (по умолчанию)
\begin{tcolorbox}[
width=3cm,
colframe=green,
title=Без hyphenationfix
]
Rechnungsadjunktentochter.\par
Statthaltereikonzipist.
\end{tcolorbox}
Проблема:
- Длинные слова не переносятся.
Пример с hyphenationfix=true
\begin{tcolorbox}[
hyphenationfix=true,
width=3cm,
colframe=green,
title=С hyphenationfix
]
Rechnungsadjunktentochter.\par
Statthaltereikonzipist.
\end{tcolorbox}
Результат:
- Длинные слова корректно переносятся.
3. Важные замечания
- Не используйте
parbox=falseиhyphenationfixвместе — они предназначены для разных типов блоков и могут конфликтовать. parbox=false— экспериментальная опция, применяйте её только при необходимости.hyphenationfixполезен в узких блоках, гдеpdflatexне справляется с переносом.
4. Полный пример
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tcolorbox}
\usepackage{lipsum} % для демонстрации текста
\begin{document}
\begin{tcolorbox}[
parbox=true,
width=0.45\linewidth,
colframe=blue,
title=parbox=true (стандартное поведение)
]
\lipsum[1][1-3] % Первые три предложения из lipsum
\end{tcolorbox}
\hfill
\begin{tcolorbox}[
parbox=false,
width=0.45\linewidth,
colframe=red,
title=parbox=false (обычный текст)
]
\lipsum[1][1-3]
\end{tcolorbox}
\vspace{1cm}
\begin{tcolorbox}[
width=3cm,
colframe=green,
title=Без hyphenationfix
]
Rechnungsadjunktentochter.\par
Statthaltereikonzipist.
\end{tcolorbox}
\hfill
\begin{tcolorbox}[
hyphenationfix=true,
width=3cm,
colframe=green,
title=С hyphenationfix
]
Rechnungsadjunktentochter.\par
Statthaltereikonzipist.
\end{tcolorbox}
\end{document}
Результат:
- Первые два блока показывают разницу между
parbox=trueиparbox=false. - Вторые два блока демонстрируют работу
hyphenationfix.
Вывод
parbox=true— стандартное поведение (рекомендуется).parbox=false— экспериментальная опция (используйте осторожно).hyphenationfix=true— решает проблемы с переносом длинных слов.
Если нужно что-то уточнить или добавить, дайте знать!
7.1.20 - Files - Работа с временными файлами в tcolorbox
Files - Работа с временными файлами в tcolorbox
В этом разделе рассматривается управление временными файлами, которые используются при работе с tcbwritetemp и \tcbusetemp.
1. Основные команды и параметры
| Опция / Команда | Синтаксис | Описание |
|---|---|---|
tempfile | tempfile=<имя_файла> | Устанавливает имя временного файла (по умолчанию: \jobname.tcbtemp). |
\tcbwritetemp | \tcbwritetemp{<содержимое>} | Записывает содержимое во временный файл. |
\tcbusetemp | \tcbusetemp | Вставляет содержимое временного файла в документ. |
2. Примеры использования
2.1. Изменение имени временного файла
\documentclass{article}
\usepackage{tcolorbox}
\begin{document}
\tcbset{tempfile=mytempfile.tmp} % меняем имя временного файла
\begin{tcolorbox}[title=Пример с временным файлом]
Содержимое блока будет записано в \texttt{mytempfile.tmp} вместо \texttt{\jobname.tcbtemp}.
\end{tcolorbox}
\end{document}
Результат:
Временный файл будет называться mytempfile.tmp вместо стандартного <имя_документа>.tcbtemp.
2.2. Запись и использование временного файла
\documentclass{article}
\usepackage{tcolorbox}
\begin{document}
% Записываем текст во временный файл
\tcbwritetemp{Этот текст будет сохранён во временный файл.}
% Вставляем содержимое временного файла в документ
\begin{tcolorbox}[title=Содержимое временного файла]
\tcbusetemp
\end{tcolorbox}
\end{document}
Результат:
В блоке tcolorbox отобразится текст, записанный через \tcbwritetemp.
3. Важные замечания
Имя файла по умолчанию
Если не указатьtempfile, будет использоваться<имя_документа>.tcbtemp(например,document.tcbtemp).Автоматическое управление
\tcbwritetempавтоматически записывает содержимое в указанный временный файл.\tcbusetempавтоматически вставляет его в документ.
Очистка временных файлов
LaTeX не удаляет временные файлы автоматически - их нужно удалять вручную или с помощью скриптов сборки.
4. Полный пример
\documentclass{article}
\usepackage{tcolorbox}
\begin{document}
% Устанавливаем кастомное имя файла
\tcbset{tempfile=my_custom_tempfile.tmp}
% Пишем текст во временный файл
\tcbwritetemp{
Этот текст был записан во временный файл \texttt{my\_custom\_tempfile.tmp}.
}
% Вставляем содержимое файла в бокс
\begin{tcolorbox}[
colframe=blue,
colback=white,
title=Пример работы с временными файлами,
fonttitle=\bfseries
]
Содержимое временного файла:\\
\tcbusetemp
\end{tcolorbox}
\end{document}
Результат:
- Создаётся временный файл
my_custom_tempfile.tmp - Его содержимое вставляется в цветную рамку
Вывод
Опция tempfile позволяет:
- Контролировать имена временных файлов
- Избегать конфликтов при использовании нескольких документов
- Организовать сложные схемы работы с содержимым
Команды \tcbwritetemp и \tcbusetemp предоставляют удобный способ:
- Сохранения промежуточного содержимого
- Повторного использования текста в документе
Для сложных документов рекомендуется явно указывать tempfile, чтобы избежать неожиданных перезаписей.
7.1.21 - cbox Specials - Специальные настройки для cbox и cboxmath
\tcbox Specials - Специальные настройки для \tcbox и \tcboxmath
В этом разделе рассматриваются специальные параметры, которые работают только с командами \tcbox и \tcboxmath.
1. Основные команды и параметры
1.1. Вертикальное выравнивание
| Опция / Стиль | Синтаксис | Описание |
|---|---|---|
tcbox raise | tcbox raise=<длина> | Поднимает \tcbox на указанную высоту (например, 5mm). |
tcbox raise base | tcbox raise base | Выравнивает \tcbox по базовой линии текста. |
on line | on line | Комбинация tcbox raise base + nobeforeafter (аналог \fbox). |
Пример:
\tcbset{colframe=blue!50!black, colback=white}
Test\tcbox[tcbox raise base]{Выровнено по базовой линии} и \tcbox[tcbox raise=2mm]{Приподнято на 2mm}.
1.2. Стиль verbatim
| Опция / Стиль | Синтаксис | Описание |
|---|---|---|
verbatim | verbatim | Уменьшает размеры \tcbox и включает nobeforeafter + tcbox raise base. |
Пример:
\DeclareTotalTCBox{\myverb}{ v }{verbatim, colframe=red!75!black}{#1}
Команда \myverb{\textbf} выделяет текст.
1.3. Управление шириной (tcbox width)
| Режим | Описание |
|---|---|
auto | Ширина определяется содержимым (по умолчанию). |
auto limited | Ширина как у содержимого, но не больше заданной (width). |
forced center | Фиксированная ширина (width), текст по центру (может выходить за границы). |
forced left | Фиксированная ширина, текст по левому краю. |
forced right | Фиксированная ширина, текст по правому краю. |
minimum center | Минимальная ширина (width), может увеличиваться. |
minimum left | Минимальная ширина, текст по левому краю. |
minimum right | Минимальная ширина, текст по правому краю. |
Пример:
\tcbset{width=3cm, colframe=blue!75!black}
\tcbox[tcbox width=auto]{auto} \\
\tcbox[tcbox width=forced center]{forced center} \\
\tcbox[tcbox width=minimum left]{minimum left}
2. Примеры использования
2.1. Выравнивание по базовой линии
Обычный текст \tcbox[tcbox raise base, colframe=green]{Выровнено} и \tcbox[colframe=red]{Не выровнено}.
Результат:
Первая рамка выровнена с текстом, вторая — смещена вниз.
2.2. Режимы ширины
\tcbset{width=4cm, colframe=blue!50!black}
\begin{itemize}
\item \tcbox[tcbox width=auto]{auto} — ширина по содержимому
\item \tcbox[tcbox width=forced center]{forced center} — фиксированная ширина
\item \tcbox[tcbox width=minimum right]{minimum right} — минимальная ширина
\end{itemize}
2.3. Verbatim-боксы
\DeclareTotalTCBox{\code}{ v }{verbatim, colframe=black}{#1}
Используйте \code{\textbackslash LaTeX} для красивого набора.
3. Полный пример
\documentclass{article}
\usepackage{tcolorbox}
\begin{document}
\section{Выравнивание}
Обычный текст \tcbox[on line, colframe=blue]{on line} и \tcbox[tcbox raise=3mm, colframe=red]{raise=3mm}.
\section{Управление шириной}
\tcbset{width=5cm, colframe=green!70!black}
\begin{tabular}{ll}
\textbf{Режим} & \textbf{Пример} \\
auto & \tcbox[tcbox width=auto]{Короткий текст} \\
forced center & \tcbox[tcbox width=forced center]{Очень длинный текст, который не помещается} \\
minimum left & \tcbox[tcbox width=minimum left]{Адаптивная ширина} \\
\end{tabular}
\section{Verbatim}
\DeclareTotalTCBox{\cmd}{ v }{verbatim, colframe=black}{#1}
Команда \cmd{\textbf} делает текст жирным.
\end{document}
4. Важные замечания
tcbox raiseработает только с\tcboxи\tcboxmath.verbatimстиль уменьшает отступы — используйте для коротких команд.forcedрежимы могут обрезать текст — применяйте осторожно.
Вывод
- Для встроенных в текст рамок используйте
on lineилиtcbox raise base. - Для управления шириной выбирайте подходящий
tcbox widthрежим. - Для оформления команд удобен
verbatimстиль.
Эти настройки дают полный контроль над встроенными цветными рамками в LaTeX!
7.1.22 - Counters, Labels, and References - Счётчики, метки и ссылки в tcolorbox
Counters, Labels, and References - Счётчики, метки и ссылки в tcolorbox
В этом разделе рассматриваются механизмы работы с нумерацией, перекрёстными ссылками и гиперссылками в рамках tcolorbox.
1. Основные команды и параметры
1.1. Основные опции для работы с метками
| Опция | Синтаксис | Описание |
|---|---|---|
phantom | phantom={\refstepcounter{mycounter}} | Выполняет код без видимого вывода (для счётчиков и меток) |
nophantom | nophantom | Отключает ранее заданный phantom код |
label | label=mylabel | Устанавливает метку для ссылок через \ref |
phantomlabel | phantomlabel=mylabel | Аналог label для ненумерованных боксов |
step | step=mycounter | Увеличивает счётчик (\refstepcounter) |
step and label | step and label={mycounter}{mylabel} | Комбинация step + label |
Пример базового использования:
\begin{tcolorbox}[
label=mybox,
title=Пример с меткой
]
Содержимое бокса. Ссылка: \ref{mybox}.
\end{tcolorbox}
1.2. Типы ссылок
| Опция | Синтаксис | Описание |
|---|---|---|
label is label | label is label | Использует стандартные \label/\ref (по умолчанию) |
label is zlabel | label is zlabel | Использует \zlabel из пакета zref |
label type | label type=theorem | Задаёт тип ссылки для cleveref/zref-clever |
no label type | no label type | Сбрасывает тип ссылки |
Пример с cleveref:
\usepackage{cleveref}
\begin{tcolorbox}[
label=mytheorem,
label type=theorem,
title=Теорема
]
Содержимое. Ссылка: \cref{mytheorem}.
\end{tcolorbox}
1.3. Дополнительные возможности
| Опция | Синтаксис | Описание |
|---|---|---|
nameref | nameref=Моё название | Текст для \nameref |
short title | short title=Краткое название | Устанавливает nameref и list entry |
hypertarget | hypertarget=mytarget | Создаёт якорь для гиперссылок |
bookmark | bookmark=Название | Добавляет закладку PDF |
index | index=Термин | Добавляет запись в индекс |
2. Примеры использования
2.1. Автоматическая нумерация
\newtcolorbox[auto counter]{mybox}[1][]{
colback=white,
title=Блок \thetcbcounter,
#1
}
\begin{mybox}[label=box1]
Первый блок. Ссылка: \ref{box1}.
\end{mybox}
2.2. Работа с гиперссылками
\usepackage{hyperref}
\begin{tcolorbox}[
hypertarget=target1,
title=Кликабельный блок
]
\hyperlink{target2}{Перейти к другому блоку}.
\end{tcolorbox}
\begin{tcolorbox}[
hypertarget=target2,
title=Целевой блок
]
Этот блок будет целью ссылки.
\end{tcolorbox}
2.3. Индексирование и закладки
\usepackage{imakeidx,bookmark}
\makeindex
\begin{tcolorbox}[
bookmark=Важная теорема,
index=Теоремы,
title=Теорема Пифагора
]
$a^2 + b^2 = c^2$
\end{tcolorbox}
3. Полный пример
\documentclass{article}
\usepackage{tcolorbox}
\usepackage{hyperref,cleveref,bookmark,imakeidx}
\makeindex
\newtcolorbox[auto counter]{theorem}[2][]{
colback=green!5,
title=Теорема \thetcbcounter: #2,
label type=theorem,
#1
}
\begin{document}
\section{Примеры}
\begin{theorem}[label=pyth]{Пифагора}
$a^2 + b^2 = c^2$
\end{theorem}
Ссылка на \cref{pyth}.
\begin{tcolorbox}[
bookmark=Демонстрация,
index=Примеры,
hypertarget=demo,
title=Демо-блок
]
Этот блок имеет:
\begin{itemize}
\item Закладку PDF
\item Запись в индексе
\item Якорь для ссылок
\end{itemize}
\end{tcolorbox}
\printindex
\end{document}
4. Важные замечания
- Для работы
zlabelтребуется пакетzref phantomкод выполняется в группе - используйте\globalдля глобальных изменений- Опции
bookmarkиindexтребуют соответствующих пакетов
Вывод
- Используйте
labelиphantomдля перекрёстных ссылок label typeулучшает работу сcleverefhypertargetиbookmarkдобавляют интерактивности PDFindexинтегрирует боксы в предметный указатель
7.1.23 - Even and Odd Pages - Разное оформление для чётных и нечётных страниц
Even and Odd Pages - Разное оформление для чётных и нечётных страниц
В этом разделе рассматриваются механизмы для различного оформления tcolorbox на чётных и нечётных страницах документа.
1. Основные команды и параметры
1.1. Основные опции
| Опция/Команда | Синтаксис | Описание |
|---|---|---|
check odd page | check odd page=true/false | Включает точную проверку чётности страницы (требует 2-х компиляций) |
if odd page | if odd page={нечётные}{чётные} | Разные стили для чётных/нечётных страниц |
if odd page or oneside | if odd page or oneside={нечётные}{чётные} | Для односторонней печати всегда применяет “нечётные” стили |
if odd page* | if odd page*={нечётные}{чётные} | Аналог if odd page для breakable-боксов (требует библиотеку breakable) |
\tcbifoddpage | \tcbifoddpage{нечётный код}{чётный код} | Условный оператор в коде |
\thetcolorboxnumber | \thetcolorboxnumber | Уникальный номер бокса (внутри бокса) |
\thetcolorboxpage | \thetcolorboxpage | Номер страницы бокса (требует check odd page=true) |
2. Примеры использования
2.1. Разные цвета для чётных/нечётных страниц
\begin{tcolorbox}[
if odd page={colback=yellow!30}{colback=blue!30},
title=Блок на \tcbifoddpage{нечётной}{чётной} странице
]
Этот блок будет жёлтым на нечётных и синим на чётных страницах.
Текущая страница: \thetcolorboxpage.
\end{tcolorbox}
2.2. Для breakable-боксов (с разрывом)
\usepackage{tcolorbox}
\tcbuselibrary{breakable}
\begin{tcolorbox}[
breakable,
if odd page*={colback=red!20}{colback=green!20},
title=Разрываемый блок
]
Длинный текст, который может занимать несколько страниц...
Каждая часть будет окрашена в зависимости от чётности страницы.
\end{tcolorbox}
2.3. Использование в водяных знаках
\begin{tcolorbox}[
enhanced,
check odd page,
watermark text={\tcbifoddpage{НЕЧЁТНАЯ}{ЧЁТНАЯ}},
title=Пример с водяным знаком
]
Содержимое блока. Водяной знак покажет чётность страницы.
\end{tcolorbox}
3. Важные особенности
Точность проверки:
- Для точного определения чётности страницы требуется:
- Установить
check odd page=true - Двойная компиляция документа
- Установить
- Без этой опции проверка может работать некорректно для первого блока на странице
- Для точного определения чётности страницы требуется:
Разрываемые боксы:
- Для breakable-боксов используйте
if odd page*вместоif odd page - Либо упакуйте
if odd pageвextras:
- Для breakable-боксов используйте
\begin{tcolorbox}[
breakable,
check odd page,
extras={if odd page={colback=yellow}{colback=blue}}
]
...
\end{tcolorbox}
- Односторонняя печать:
- Для документов с
onesideиспользуйтеif odd page or oneside - В этом случае всегда будут применяться “нечётные” стили
- Для документов с
4. Полный пример
\documentclass[twoside]{article}
\usepackage{tcolorbox}
\tcbuselibrary{breakable}
\usepackage{lipsum}
\newtcolorbox{smartbox}[1][]{
check odd page,
if odd page*={colback=yellow!10}{colback=blue!10},
colframe=black,
title=Блок на странице \thetcolorboxpage,
#1
}
\begin{document}
\section{Разное оформление для чётных/нечётных страниц}
\begin{smartbox}
Этот блок автоматически меняет цвет в зависимости от страницы.
\begin{itemize}
\item Номер бокса: \thetcolorboxnumber
\item Номер страницы: \thetcolorboxpage
\end{itemize}
\end{smartbox}
\begin{smartbox}[breakable]
\lipsum[1-4]
Длинное содержимое, которое может переноситься на несколько страниц.
Каждая часть будет окрашена соответствующим образом.
\end{smartbox}
\end{document}
5. Вывод
Для разного оформления на чётных/нечётных страницах:
- Используйте
if odd pageдля обычных боксов - Используйте
if odd page*для breakable-боксов - Для точности добавьте
check odd page=true
- Используйте
Специальные команды:
\tcbifoddpage- условный оператор в коде\thetcolorboxnumber- уникальный номер бокса\thetcolorboxpage- точный номер страницы
Для односторонней печати используйте варианты с
or oneside.
7.1.24 - Externalization - Интеграция с внешними файлами TikZ
Externalization - Интеграция с внешними файлами TikZ
В этом разделе рассматривается взаимодействие tcolorbox с системой внешних файлов (externalization) пакета TikZ.
1. Основные команды и параметры
| Опция/Команда | Синтаксис | Описание |
|---|---|---|
shield externalize | shield externalize=true/false | Защищает tcolorbox от внешнего экспорта (по умолчанию false) |
external | external=имя_файла | Устанавливает имя файла для экспорта TikZ-рисунков внутри бокса |
remake | remake=true/false | Форсирует пересоздание внешнего файла для TikZ-рисунка |
2. Примеры использования
2.1. Базовое использование
\documentclass{article}
\usepackage{tcolorbox}
\usetikzlibrary{external}
\tikzexternalize % Включаем систему внешних файлов
\begin{document}
\begin{tcolorbox}[
shield externalize, % Защищаем сам бокс от экспорта
title=Защищённый бокс
]
Этот tcolorbox не будет экспортирован как внешний файл.
\begin{tikzpicture}
\draw (0,0) circle (1cm); % Этот рисунок БУДЕТ экспортирован
\end{tikzpicture}
\end{tcolorbox}
\end{document}
2.2. Управление экспортом отдельных рисунков
\begin{tcolorbox}[
external=myplot, % Устанавливаем имя файла для экспорта
remake=true, % Форсируем пересоздание
title=Бокс с управляемым экспортом
]
\begin{tikzpicture}
\draw[red] (0,0) rectangle (2,2); % Экспортируется в myplot.pdf
\end{tikzpicture}
\end{tcolorbox}
3. Важные особенности
Автоматическое отключение в TikZ-окружении:
- Внутри
tikzpictureопцияshield externalizeавтоматически отключается - Не используйте
\tikzexternaldisableперед tcolorbox в этом случае
- Внутри
Рекомендуемые паттерны использования:
\tikzexternalenable % Рисунки для экспорта \tikzexternaldisable % Обычные tcolorboxТребования:
- Для работы необходимо подключить библиотеку TikZ:
\usetikzlibrary{external} \tikzexternalize
- Для работы необходимо подключить библиотеку TikZ:
Ограничения:
- Рисунки, созданные через
tikz upperи аналогичные опции, не экспортируются - Для сложных документов может потребоваться несколько компиляций
- Рисунки, созданные через
4. Полный пример
\documentclass{article}
\usepackage{tcolorbox}
\usetikzlibrary{external}
\tikzexternalize % Активируем систему внешних файлов
\tcbset{shield externalize} % Глобально защищаем все tcolorbox
\begin{document}
\section{Пример интеграции с внешними файлами}
\begin{tcolorbox}[title=Обычный защищённый бокс]
Этот блок не будет экспортирован как внешний файл.
\end{tcolorbox}
\begin{tcolorbox}[
external=mycircle,
title=Бокс с экспортируемым рисунком
]
\begin{tikzpicture}
\draw[blue, thick] (0,0) circle (1.5cm);
\node at (0,0) {Экспортируется};
\end{tikzpicture}
\end{tcolorbox}
\tikzexternaldisable % Временно отключаем экспорт
\begin{tcolorbox}[title=Временный незащищённый бокс]
Этот блок создан при отключённом экспорте.
\end{tcolorbox}
\tikzexternalenable % Возобновляем экспорт
\end{document}
5. Вывод
Защита боксов:
- Используйте
shield externalizeдля предотвращения экспорта tcolorbox - Устанавливайте глобально через
\tcbset, если не нужен экспорт
- Используйте
Управление экспортом:
- Для экспорта отдельных рисунков используйте
external=имя_файла - Для принудительного обновления -
remake=true
- Для экспорта отдельных рисунков используйте
Лучшие практики:
- Чётко разделяйте код, требующий экспорта и не требующий
- Используйте
\tikzexternalenable/disableдля группировки экспортируемых элементов
Эти механизмы позволяют эффективно комбинировать tcolorbox с системой внешних файлов TikZ, оптимизируя процесс сборки сложных документов.
7.1.25 - Miscellaneous - Разные дополнительные возможности
4.24 Miscellaneous - Разные дополнительные возможности
В этом разделе рассматриваются различные дополнительные функции tcolorbox, которые не вошли в предыдущие категории.
1. Основные команды и параметры
1.1. Сброс настроек
| Опция | Синтаксис | Описание |
|---|---|---|
reset | reset | Сбрасывает все настройки tcolorbox к значениям по умолчанию |
Пример:
\begin{tcolorbox}[reset, title=Блок со сброшенными настройками]
Этот блок игнорирует все предыдущие \tcbset{}
\end{tcolorbox}
1.2. Условные операторы
| Опция | Синтаксис | Описание |
|---|---|---|
IfBlankTF | IfBlankTF={текст}{опции если пусто}{опции если не пусто} | Проверяет на пустоту (пробелы считаются пустотой) |
IfEmptyTF | IfEmptyTF={текст}{опции если пусто}{опции если не пусто} | Проверяет на полную пустоту |
IfNoValueTF | IfNoValueTF={аргумент}{опции если нет значения}{опции если есть} | Для обработки необязательных аргументов |
IfValueTF | IfValueTF={аргумент}{опции если есть значение}{опции если нет} | Обратная версия IfNoValueTF |
IfBooleanTF | IfBooleanTF={аргумент}{опции если true}{опции если false} | Для булевых значений |
Пример с IfValueTF:
\DeclareTColorBox{mybox}{o}{%
IfValueTF={#1}{title=#1}{title=Без названия},
colframe=blue
}
\begin{mybox}
Блок без названия
\end{mybox}
\begin{mybox}[Мой заголовок]
Блок с названием
\end{mybox}
1.3. Специальные режимы
| Опция | Синтаксис | Описание |
|---|---|---|
void | void | Полностью удаляет бокс (как комментарий) |
nirvana | nirvana | Обрабатывает содержимое, но не отображает бокс |
Пример:
Текст до
\begin{tcolorbox}[void]
Этот блок полностью исчезнет
\end{tcolorbox}
Текст после
2. Примеры использования
2.1. Условное форматирование
\newtcolorbox{smartbox}[1][]{
IfBlankTF={#1}{colback=red!10}{colback=green!10},
title=Умный бокс
}
\begin{smartbox}[]
Будет красным (аргумент пуст)
\end{smartbox}
\begin{smartbox}[X]
Будет зелёным (аргумент не пуст)
\end{smartbox}
2.2. Обработка необязательных аргументов
\DeclareTColorBox{mybox}{o}{
IfNoValueTF={#1}{title=Стандартный}{title=#1},
colframe=black
}
\begin{mybox}
Стандартный заголовок
\end{mybox}
\begin{mybox}[Кастомный]
Специальный заголовок
\end{mybox}
2.3. Временное отключение боксов
Текст до
\begin{tcolorbox}[nirvana]
Этот блок обработается, но не будет виден
\begin{tcolorbox}
Вложенный блок (будет виден)
\end{tcolorbox}
\end{tcolorbox}
Текст после
3. Важные особенности
reset:- Не сбрасывает
capture,shield externalizeи настройки raster - Автоматически применяется для вложенных боксов (начиная с v2.40)
- Не сбрасывает
Условные операторы:
- Основаны на функциях
expl3иxparse - Полезны для создания гибких шаблонов боксов
- Основаны на функциях
voidvsnirvana:voidполностью удаляет бокс (как если бы его закомментировали)nirvanaобрабатывает содержимое (счётчики и пр.), но не отображает
Ограничения:
voidнельзя использовать для вложенных боксов с одинаковыми именамиvoidне работает с\tcolorboxenvironment
4. Полный пример
\documentclass{article}
\usepackage{tcolorbox}
\usepackage{xcolor}
% Бокс с условным форматированием
\newtcolorbox{condbox}[1][]{
IfBlankTF={#1}{colback=gray!20}{colback=#1!20},
title=Условный бокс
}
\begin{document}
\section{Примеры разных возможностей}
\begin{condbox}[]
Стандартный серый фон (аргумент пуст)
\end{condbox}
\begin{condbox}[red]
Красный фон (аргумент указан)
\end{condbox}
% Пример с void
Текст до \begin{tcolorbox}[void]Невидимый блок\end{tcolorbox} текст после
% Пример с nirvana
Текст до \begin{tcolorbox}[nirvana]
Невидимый но обработанный блок
\begin{tcolorbox}[colback=yellow]
Вложенный видимый блок
\end{tcolorbox}
\end{tcolorbox} текст после
\end{document}
5. Вывод
- Для сброса настроек используйте
reset - Для условного форматирования применяйте:
IfBlankTF/IfEmptyTF- проверка на пустотуIfNoValueTF/IfValueTF- работа с аргументамиIfBooleanTF- для булевых флагов
- Для скрытия блоков:
void- полное удалениеnirvana- скрытие с обработкой содержимого
7.2 - Справочник основных пакетов LaTeX
1. Кодировка и языки
fontenc
Назначение: Выбор кодировки шрифтов.
T1– для западноевропейских языков.T2A– для кириллицы (русский текст).
Пример:
\usepackage[T1,T2A]{fontenc}
inputenc
Назначение: Указывает кодировку исходного файла.
utf8x– поддержка UTF-8.
Пример:
\usepackage[utf8x]{inputenc}
babel
Назначение: Поддержка многоязычных документов (переносы, автоимена разделов).
russian– активирует русскую локализацию.english– резервный язык.
Пример:
\usepackage[english, russian]{babel}
2. Разметка страницы
geometry
Назначение: Настройка полей и размеров страницы.
Основные параметры:
tmargin,bmargin,lmargin,rmargin– отступы.headsep,headheight– расстояние до верхнего колонтитула.
Пример:
\usepackage{geometry}
\geometry{tmargin=25mm, bmargin=20mm, lmargin=20mm, rmargin=20mm}
fancyhdr
Назначение: Настройка колонтитулов.
\pagestyle{fancy}– активирует стиль.\lhead,\chead,\rhead– левый/центральный/правый верхний колонтитул.\lfoot,\cfoot,\rfoot– нижний колонтитул.
Пример:
\usepackage{fancyhdr}
\pagestyle{fancy}
\lhead{Левый заголовок}
\rfoot{Страница \thepage}
3. Математика
amsmath, amsthm, amssymb
Назначение: Расширенная математическая вёрстка.
amsmath– улучшенные уравнения (align,gather).amssymb– дополнительные символы (\mathbb,\mathcal).amsthm– теоремы (\newtheorem).
Пример:
\begin{align}
a &= b + c \\
E &= mc^2
\end{align}
wasysym
Назначение: Дополнительные символы (например, \diameter для диаметра).
4. Графика и таблицы
graphicx
Назначение: Вставка изображений.
\includegraphics[width=5cm]{image.png}– вставка с масштабированием.
Пример:
\usepackage{graphicx}
\graphicspath{{images/}} % путь к изображениям
float
Назначение: Улучшенное управление позиционированием плавающих объектов (рисунков, таблиц).
subcaption
Назначение: Подписи к нескольким изображениям в одной фигуре.
Пример:
\begin{figure}
\begin{subfigure}{0.5\textwidth}
\includegraphics{img1.png}
\caption{Первое изображение}
\end{subfigure}
\begin{subfigure}{0.5\textwidth}
\includegraphics{img2.png}
\caption{Второе изображение}
\end{subfigure}
\caption{Два изображения}
\end{figure}
multirow, colortbl, hhline
Назначение: Сложные таблицы.
\multirow– объединение строк.\colortbl– цветные ячейки.\hhline– двойные линии.
Пример:
\begin{tabular}{|c|c|}
\hline
\multirow{2}{*}{Объединённые строки} & Текст \\ \cline{2-2}
& Ещё текст \\ \hline
\end{tabular}
5. Гиперссылки и оглавление
hyperref
Назначение: Интерактивные ссылки в PDF.
\href{url}{текст}– гиперссылка.\autoref{label}– автоматические подписи (“Рисунок 1”).
Пример:
\usepackage{hyperref}
\hypersetup{colorlinks=true, linkcolor=blue}
varioref
Назначение: Умные ссылки (“на стр. 5”).
imakeidx
Назначение: Создание индекса.
\makeindex– активация.\index{ключ}– добавление записи.
Пример:
\usepackage{imakeidx}
\makeindex
...
\printindex
6. Текст и форматирование
ulem
Назначение: Дополнительное оформление текста.
\sout{текст}– зачёркивание.\uline{текст}– подчёркивание.
indentfirst
Назначение: Автоматический отступ у первого абзаца.
multicol
Назначение: Многоколоночная вёрстка.
Пример:
\begin{multicols}{2}
Текст в две колонки...
\end{multicols}
7. Разное
tikz
Назначение: Создание векторной графики прямо в LaTeX.
Пример:
\begin{tikzpicture}
\draw (0,0) -- (1,1);
\end{tikzpicture}
xcolor
Назначение: Работа с цветами.
\textcolor{red}{текст}– цвет текста.
7.3 - Latex для авторов
Введение
LaTeX 2ε был выпущен в 1994 году и добавил ряд новых концепций, которые на тот момент были актуальны. Эти концепции описаны в документе usrguide-historic, который в значительной степени остался неизменным. С тех пор команда LaTeX работала над рядом идей, в первую очередь над языком программирования для LaTeX (expl3), а затем над рядом инструментов для авторов документов, которые основываются на этом языке. Здесь мы описываем стабильные и широко используемые концепции, которые стали результатом этой работы. Эти «новые» идеи были перенесены из пакетов разработки в ядро LaTeX 2ε. Таким образом, они теперь доступны всем пользователям LaTeX и имеют такую же стабильность, как и любая другая часть ядра. Тот факт, что «за кулисами» они построены на основе expl3, полезен для команды разработчиков, но не имеет прямого значения для пользователей.
2 Создание команд и окружений документа
2.1 Обзор
Создание команд и окружений документа с использованием инструментария LaTeX3 основано на идее, что общий набор описаний может быть использован для охвата почти всех типов аргументов, используемых в реальных документах. Таким образом, парсинг сводится к простому описанию того, какие аргументы принимает команда: это описание обеспечивает «связь» между синтаксисом документа и реализацией команды.
Сначала мы опишем типы аргументов, затем перейдем к объяснению того, как их можно использовать для создания как команд документа, так и окружений. Затем будут описаны различные более специализированные функции, которые позволяют еще более богатое применение простого интерфейса.
Детали, приведенные здесь, предназначены для помощи пользователям в создании команд документа в общем. Более технические детали, подходящие для программистов TeX, включены в раздел interface3.
2.2 Описание типов аргументов
Для того чтобы каждый аргумент можно было определить независимо, парсеру необходимо знать не только количество аргументов для функции, но и природу каждого из них. Это достигается путем построения спецификации аргумента, которая определяет количество аргументов, тип каждого аргумента и любую дополнительную информацию, необходимую парсеру для чтения пользовательского ввода и правильной передачи его во внутренние функции.
Основная форма спецификатора аргумента — это список букв, где каждая буква определяет тип аргумента. Как будет описано ниже, некоторые типы требуют дополнительной информации, такой как значения по умолчанию. Типы аргументов можно разделить на две категории: те, которые определяют обязательные аргументы (возможно, вызывая ошибку, если они не найдены), и те, которые определяют необязательные аргументы.
Обязательные типы
m
Стандартный обязательный аргумент, который может быть либо единственным токеном, либо несколькими токенами, заключенными в фигурные скобки {}. Независимо от ввода, аргумент будет передан во внутренний код без внешних скобок. Это спецификатор типа для обычного аргумента TeX.r
Указывается как r⟨token1⟩⟨token2⟩, это обозначает «обязательный» аргумент с разделителями, где разделителями являются ⟨token1⟩ и ⟨token2⟩. Если открывающий разделитель ⟨token1⟩ отсутствует, будет вставлен маркер по умолчанию -NoValue- после соответствующей ошибки.R
Указывается как R⟨token1⟩⟨token2⟩{⟨default⟩}, это «обязательный» аргумент с разделителями, как и r, но он имеет определяемое пользователем значение по умолчанию ⟨default⟩ вместо -NoValue-.v
Читает аргумент «дословно» между следующим символом и его следующим вхождением, аналогично аргументу команды LaTeX 2ε \verb. Таким образом, аргумент типа v читается между двумя одинаковыми символами, которые не могут быть %, , #, {, } или ␣. Дословный аргумент также может быть заключен в фигурные скобки { и }. Команда с дословным аргументом вызовет ошибку, если она появится внутри аргумента другой команды.b
Подходит только в спецификации аргумента окружения, обозначает тело окружения, между \begin{⟨environment⟩} и \end{⟨environment⟩}. См. раздел 2.11 для подробностей.
Типы, которые определяют необязательные аргументы, следующие:
o
Стандартный необязательный аргумент LaTeX, заключенный в квадратные скобки, который будет предоставлять специальный маркер -NoValue-, если не указан (как будет описано позже).d
Указывается как d⟨token1⟩⟨token2⟩, необязательный аргумент, который ограничен ⟨token1⟩ и ⟨token2⟩. Как и в случае с o, если значение не указано, возвращается специальный маркер -NoValue-.O
Указывается как O{⟨default⟩}, аналогично o, но возвращает ⟨default⟩, если значение не указано.D
Указывается как D⟨token1⟩⟨token2⟩{⟨default⟩}, аналогично d, но возвращает ⟨default⟩, если значение не указано. Внутренне типы o, d и O являются сокращениями для соответствующим образом сконструированного аргумента типа D.s
Необязательная звезда(*), которая приведет к значению \BooleanTrue, если звезда присутствует, и \BooleanFalse в противном случае (как будет описано позже).t
Необязательный ⟨token⟩, который приведет к значению \BooleanTrue, если ⟨token⟩ присутствует, и \BooleanFalse в противном случае. Указывается как t⟨token⟩.e
Указывается как e{⟨tokens⟩}, набор необязательных украшений, каждое из которых требует значения. Если украшение отсутствует, возвращается -NoValue-. Каждое украшение дает один аргумент, упорядоченный в соответствии со списком ⟨tokens⟩ в спецификации аргумента. Все ⟨tokens⟩ должны быть различными.E
Аналогично e, но возвращает одно или несколько ⟨defaults⟩, если значения не указаны: E{⟨tokens⟩}{⟨defaults⟩}. См. раздел 2.7 для получения дополнительных деталей.
2.3 Модификация описаний аргументов
В дополнение к типам аргументов, обсужденным выше, описание аргументов также придает специальное значение трем другим символам.
Во-первых, + используется для того, чтобы сделать аргумент длинным (принимать параграфные токены). В отличие от \newcommand, это применяется на основе каждого отдельного аргумента. Таким образом, модификация примера на «s o o +m O{default}» означает, что обязательный аргумент теперь является \long, в то время как необязательные аргументы таковыми не являются.
Во-вторых, ! используется для управления тем, разрешены ли пробелы перед необязательными аргументами. Здесь есть некоторые тонкости, так как сам TeX имеет ограничения на то, где пробелы могут быть «обнаружены»: более подробная информация приведена в разделе 2.6.
В-третьих, = используется для объявления того, что следующий аргумент должен интерпретироваться как серия ключевых значений (keyvals). См. раздел 2.9 для получения дополнительных деталей.
Наконец, символ > используется для объявления так называемых «процессоров аргументов», которые могут быть использованы для модификации содержимого аргумента перед его передачей в определение макроса. Использование процессоров аргументов является несколько продвинутой темой (или, по крайней мере, менее часто используемой функцией) и рассматривается в разделе 2.10.
Вот перевод раздела 2.4 “Создание команд и окружений документа”:
2.4 Создание команд и окружений документа
\NewDocumentCommand {⟨cmd⟩} {⟨arg spec⟩} {⟨code⟩}
\RenewDocumentCommand {⟨cmd⟩} {⟨arg spec⟩} {⟨code⟩}
\ProvideDocumentCommand {⟨cmd⟩} {⟨arg spec⟩} {⟨code⟩}
\DeclareDocumentCommand {⟨cmd⟩} {⟨arg spec⟩} {⟨code⟩}
Эта группа команд используется для создания команды ⟨cmd⟩. Спецификация аргумента для функции задается с помощью ⟨arg spec⟩, а команда использует ⟨code⟩, где #1, #2 и т. д. заменяются на аргументы, найденные парсером.
Пример:
\NewDocumentCommand\chapter{s o m} {
\IfBooleanTF{#1}
{\typesetstarchapter{#3}}
{\typesetnormalchapter{#2}{#3}}
}
Это способ определения команды \chapter, которая будет вести себя аналогично текущей команде LaTeX 2ε (за исключением того, что она будет принимать необязательный аргумент, даже когда был распарсен символ *). Команда \typesetnormalchapter может проверить свой первый аргумент на наличие значения -NoValue-, чтобы определить, присутствует ли необязательный аргумент. (См. раздел 2.8 для деталей о \IfBooleanTF и проверке на -NoValue-.)
Разница между версиями \New…, \Renew…, \Provide… и \Declare… заключается в поведении, если ⟨cmd⟩ уже определена.
- \NewDocumentCommand выдаст ошибку, если ⟨cmd⟩ уже была определена.
- \RenewDocumentCommand выдаст ошибку, если ⟨cmd⟩ ранее не была определена.
- \ProvideDocumentCommand создаст новое определение для ⟨cmd⟩ только в том случае, если оно еще не было дано.
- \DeclareDocumentCommand всегда создаст новое определение, независимо от существующей ⟨cmd⟩ с тем же именем. Это следует использовать с осторожностью.
Если ⟨cmd⟩ не может быть предоставлена как единый токен, но требует «конструирования», вы можете использовать \ExpandArgs, как объясняется в разделе 4, который также дает пример, в котором это необходимо.
\NewDocumentEnvironment {⟨env⟩} {⟨arg spec⟩} {⟨beg-code⟩} {⟨end-code⟩}
\RenewDocumentEnvironment {⟨env⟩} {⟨arg spec⟩} {⟨beg-code⟩} {⟨end-code⟩}
\ProvideDocumentEnvironment {⟨env⟩} {⟨arg spec⟩} {⟨beg-code⟩} {⟨end-code⟩}
\DeclareDocumentEnvironment {⟨env⟩} {⟨arg spec⟩} {⟨beg-code⟩} {⟨end-code⟩}
Эти команды работают так же, как \NewDocumentCommand и т. д., но создают окружения (\begin{⟨env⟩} … \end{⟨env⟩}). Как ⟨beg-code⟩, так и ⟨end-code⟩ могут получать доступ к аргументам, как определено в ⟨arg spec⟩. Аргументы будут переданы после \begin{⟨env⟩}. Все пробелы в начале и в конце {⟨env⟩} удаляются перед определением, таким образом:
\NewDocumentEnvironment{foo}
и
\NewDocumentEnvironment{ foo }
оба создают одно и то же окружение «foo».
2.5 Необязательные аргументы
В отличие от команд, созданных с помощью \newcommand в LaTeX 2ε, необязательные аргументы, созданные с помощью \NewDocumentCommand, могут безопасно вкладываться. Таким образом, например, после
\NewDocumentCommand\foo{om}{I grabbed ‘#1’ and ‘#2’}
\NewDocumentCommand\baz{o}{#1-#1}
использование команды как
\foo[\baz[stuff]]{more stuff}
выведет
I grabbed ‘stuff-stuff’ and ‘more stuff’
Это особенно полезно, когда команда с необязательным аргументом помещается внутри необязательного аргумента второй команды.
Когда необязательный аргумент следует за обязательным аргументом с тем же разделителем, парсер выдает предупреждение, поскольку необязательный аргумент не может быть опущен пользователем, тем самым фактически становясь обязательным. Это может касаться аргументов типов o, d, O, D, s, t, e и E, за которыми следуют обязательные аргументы типа r или R.
Значение по умолчанию для аргументов O, D и E может быть результатом захвата другого аргумента. Таким образом, например,
\NewDocumentCommand\foo{O{#2} m}
будет использовать обязательный аргумент в качестве значения по умолчанию для ведущего необязательного аргумента.
2.6 Пробелы и необязательные аргументы
TeX найдет первый аргумент после имени функции независимо от любых промежуточных пробелов. Это верно как для обязательных, так и для необязательных аргументов. Таким образом, \foo[arg] и \foo␣[arg] эквивалентны. Пробелы также игнорируются при сборе аргументов до последнего обязательного аргумента, который должен существовать. Поэтому после
\NewDocumentCommand\foo{m o m}{ ... }
ввод пользователя \foo{arg1}[arg2]{arg3} и \foo{arg1}␣[arg2]␣{arg3} будут парситься одинаково.
Поведение необязательных аргументов после любых обязательных аргументов можно настроить. Стандартные настройки позволят пробелы здесь, и таким образом, с
\NewDocumentCommand\foobar{m o}{ ... }
как \foobar{arg1}[arg2], так и \foobar{arg1}␣[arg2] найдут необязательный аргумент. Это можно изменить, добавив модификатор ! в спецификацию аргументов:
\NewDocumentCommand\foobar{m !o}{ ... }
где \foobar{arg1}␣[arg2] не найдет необязательный аргумент.
Существует одна тонкость, связанная с различием в обработке TeX «управляющих символов», когда имя команды состоит из одного символа, например, ‘\’. Пробелы здесь не игнорируются TeX, и, таким образом, возможно, чтобы необязательный аргумент следовал непосредственно за такой командой. Наиболее распространенный пример — использование \ в окружениях amsmath, которое в терминах здесь будет определено как
\NewDocumentCommand\\{!s !o}{ ... }
Также стоит отметить, что при использовании необязательных аргументов в последней позиции TeX обязательно будет заглядывать вперед для открытия токена аргумента. Это означает, что значение \inputlineno будет «сдвинуто на один», если такой завершающий необязательный аргумент отсутствует и команда заканчивает строку; оно будет на единицу больше, чем номер строки, содержащей последний обязательный аргумент.
2.7 «Украшения»
Аргумент типа E позволяет задавать одно значение по умолчанию для каждого тестового токена. Это достигается путем указания списка значений по умолчанию для каждой записи в списке, например:
E{^_}{{UP}{DOWN}}
Если список значений по умолчанию короче списка тестовых токенов, будет возвращен специальный маркер -NoValue- (как и для аргумента типа e). Таким образом, например:
E{^_}{{UP}}
имеет значение по умолчанию UP для тестового символа ^, но вернет маркер -NoValue- в качестве значения по умолчанию для _. Это позволяет смешивать явные значения по умолчанию с проверкой на отсутствие значений.
2.8 Проверка специальных значений
Необязательные аргументы используют специальные переменные для возврата информации о природе полученного аргумента.
\IfNoValueTF {⟨arg⟩} {⟨true code⟩} {⟨false code⟩}
\IfNoValueT {⟨arg⟩} {⟨true code⟩}
\IfNoValueF {⟨arg⟩} {⟨false code⟩}
Команды \IfNoValue(TF) используются для проверки, является ли ⟨argument⟩ (#1, #2 и т. д.) специальным маркером -NoValue-. Например:
\NewDocumentCommand\foo{o m} {
\IfNoValueTF {#1}
{\DoSomethingJustWithMandatoryArgument{#2}}
{\DoSomethingWithBothArguments{#1}{#2}}
}
будет использовать другую внутреннюю функцию, если необязательный аргумент задан, чем если он отсутствует.
Обратите внимание, что доступны три теста, в зависимости от того, какие ветви результата требуются: \IfNoValueTF, \IfNoValueT и \IfNoValueF. Поскольку тесты \IfNoValue(TF) являются расширяемыми, возможно проверять эти значения позже, например, в момент верстки или в контексте расширения.
Важно отметить, что -NoValue- сконструирован таким образом, что он не будет соответствовать простому текстовому вводу -NoValue-, т.е.
\IfNoValueTF{-NoValue-}
будет логически ложным. Когда два необязательных аргумента следуют друг за другом (синтаксис, который мы обычно не рекомендуем), может иметь смысл позволить пользователям команды указывать только второй аргумент, предоставив пустой первый аргумент. Вместо того чтобы отдельно проверять на пустоту и на -NoValue-, лучше использовать тип аргумента O с пустым значением по умолчанию, а затем проверять на пустоту, используя условие \IfBlankTF (описанное ниже).
\IfValueTF {⟨arg⟩} {⟨true code⟩} {⟨false code⟩}
\IfValueT {⟨arg⟩} {⟨true code⟩}
\IfValueF {⟨arg⟩} {⟨false code⟩}
Обратная форма тестов \IfNoValue(TF) также доступна как \IfValue(TF). Контекст определит, какая логическая форма имеет наибольший смысл для данного сценария кода.
\IfBlankTF {⟨arg⟩} {⟨true code⟩} {⟨false code⟩}
\IfBlankT {⟨arg⟩} {⟨true code⟩}
\IfBlankF {⟨arg⟩} {⟨false code⟩}
Команда \IfNoValueTF выбирает ⟨true code⟩, если необязательный аргумент вообще не использовался (и возвращает специальный маркер -NoValue-), но не если ему было дано пустое значение. В отличие от этого, \IfBlankTF возвращает true, если его аргумент либо действительно пуст, либо содержит один или несколько обычных пробелов. Например:
\NewDocumentCommand\foo{m!o}{\par #1:
\IfNoValueTF{#2}
{No optional}%
{%
\IfBlankTF{#2}
{Blanks in or empty}%
{Real content in}%
}%
\space argument!}
\foo{1}[bar] \foo{2}[ ] \foo{3}[] \foo{4}[\space] \foo{5}[x]
результирует в следующем выводе:
1: Real content in argument!
2: Blanks in or empty argument!
3: Blanks in or empty argument!
4: Real content in argument!
5: No optional argument! [x]
Обратите внимание, что \space в (4) считается реальным содержимым — потому что это команда, а не символ «пробел» — даже если это приводит к созданию пробела. Вы также можете наблюдать в (5) эффект спецификатора !, предотвращающего последнюю \foo от интерпретации [x] как своего необязательного аргумента.
\BooleanFalse
\BooleanTrue
Флаги истинности и ложности, устанавливаемые при поиске необязательного символа (с использованием s или t⟨char⟩), имеют имена, которые доступны вне блоков кода.
\IfBooleanTF {⟨arg⟩} {⟨true code⟩} {⟨false code⟩}
\IfBooleanT {⟨arg⟩} {⟨true code⟩}
\IfBooleanF {⟨arg⟩} {⟨false code⟩}
Эти команды используются для проверки, является ли ⟨argument⟩ (#1, #2 и т. д.) равным \BooleanTrue или \BooleanFalse. Например:
\NewDocumentCommand\foo{sm} {
\IfBooleanTF {#1}
{\DoSomethingWithStar{#2}}
{\DoSomethingWithoutStar{#2}}
}
Этот код проверяет наличие звезды в качестве первого аргумента, а затем выбирает действие на основе этой информации.
2.9 Автоматическое преобразование в формат ключ-значение
Некоторые команды документа имеют долгую историю принятия необязательного аргумента в виде «свободного текста», например, \caption и команды секционирования \section и т.д. Введение более сложных (keyval) опций для этих команд требует метода интерпретации необязательного аргумента как свободного текста или как серии ключевых значений. Это должно происходить во время захвата аргумента, так как необходимо аккуратно обрабатывать фигурные скобки для получения правильного результата.
Модификатор = доступен для того, чтобы позволить ltcmd правильно реализовать этот процесс. Модификатор гарантирует, что аргумент будет передан в дальнейший код как серия ключевых значений. Для этого = должен быть за ним, за которым следует аргумент, содержащий имя ключа по умолчанию. Это используется как ключ в паре ключ-значение, если «сырой» аргумент не имеет правильной формы для интерпретации как набора ключевых значений.
Пример с \caption
Рассмотрим \caption в качестве примера с демонстрационной реализацией:
\DeclareDocumentCommand \caption {s ={short-text} +O{#3} +m} {%
\showtokens{Grabbed arguments:^^J(#2)^^Jand^^J(#3)}%
}
Имя ключа по умолчанию — short-text. Когда команда \caption используется, если необязательный аргумент является свободным текстом, например:
\caption[Некоторый короткий текст]{Длинный и более детализированный текст для демонстрационных целей}
то вывод будет:
Grabbed arguments: (short-text={Некоторый короткий текст}) and (Длинный и более детализированный текст для демонстрационных целей)
С другой стороны, если заголовок задан с аргументом в формате ключ-значение:
\caption[label = cap:demo]{Длинный и более детализированный текст для демонстрационных целей}
то это будет учтено:
Grabbed arguments: (label = cap:demo) and (Длинный и более детализированный текст для демонстрационных целей)
Интерпретация в формате ключ-значение
Интерпретация как ключ-значение определяется наличием символов = в аргументе. Символы в режиме встроенной математики (включенные в $...$ или \(...\)) игнорируются. Аргумент можно заставить быть прочитанным как ключ-значение, включив пустую запись в начале:
\caption[=,Это теперь ключ-значение]%
\caption[Это не $=$ ключ-значение]%
Эта пустая запись не передается в основной код, поэтому не приведет к проблемам с парсерами ключ-значение, которые не допускают пустое имя ключа. Любые знаки = в текстовом режиме необходимо обрамлять фигурными скобками, чтобы избежать неправильной интерпретации: это, вероятно, наиболее удобно обрабатывать, обрамляя весь аргумент:
\caption[{Не = ключ-значение!}]%
что будет правильно передано как:
Grabbed arguments: (short-text = {Не = ключ-значение!})
2.10 Процессоры аргументов
Процессоры аргументов применяются к аргументу после его захвата основной системой, но перед передачей в ⟨код⟩. Таким образом, процессор аргументов может использоваться для нормализации ввода на ранней стадии, позволяя внутренним функциям быть полностью независимыми от формы ввода. Процессоры применяются к пользовательскому вводу и к значениям по умолчанию для необязательных аргументов, но не к специальному маркеру -NoValue-.
Каждый процессор аргументов указывается синтаксисом >{⟨процессор⟩} в спецификации аргумента. Процессоры применяются справа налево, так что >{\ProcessorB} >{\ProcessorA} m применит \ProcessorA, а затем \ProcessorB к токенам, захваченным аргументом m.
\SplitArgument {⟨number⟩} {⟨token(s)⟩}
Этот процессор разделяет аргумент, заданный при каждом вхождении ⟨tokens⟩, до максимума ⟨number⟩ токенов (тем самым деля ввод на ⟨number⟩ + 1 частей). Ошибка будет выдана, если в вводе присутствует слишком много ⟨токенов⟩. Обработанный ввод помещается внутри ⟨number⟩ + 1 наборов фигурных скобок для дальнейшего использования. Если в аргументе меньше, чем ⟨number⟩, то в конце обработанного аргумента добавляются маркеры -NoValue-.
\NewDocumentCommand \foo {>{\SplitArgument{2}{;}} m} {\InternalFunctionOfThreeArguments#1}
Если для разделения используется только один символ ⟨токен⟩, любой символ с кодом категории 13 (активный) совпадающий с ⟨токеном⟩ будет заменен до того, как произойдет разделение. Пробелы обрезаются в начале и в конце каждого элемента, который разбирается.
Тип аргумента E несколько особенный, потому что с одним E в объявлении команды вы можете получить несколько аргументов в команде (по одному формальному аргументу на каждый токен украшения). Поэтому, когда процессор аргументов применяется к аргументу типа e/E, все аргументы проходят через этот процессор перед тем, как быть переданными в ⟨код⟩. Например, эта команда:
\NewDocumentCommand \foo { >{\TrimSpaces} e{_^} } { [#1](#2) }
применяет \TrimSpaces к обоим аргументам.
\SplitList {⟨токены⟩}
Этот процессор разделяет аргумент, заданный при каждом вхождении ⟨токенов⟩, где количество элементов не фиксировано. Каждый элемент затем оборачивается в фигурные скобки внутри #1. Результат заключается в том, что обработанный аргумент может быть дополнительно обработан с использованием функции отображения (см. ниже).
\NewDocumentCommand \foo {>{\SplitList{;}} m} {\MappingFunction#1}
Если для разделения используется только один символ ⟨токен⟩, он учтет возможность того, что ⟨токен⟩ был активирован (код категории 13) и будет разделять по таким токенам. Пробелы обрезаются в начале и в конце каждого элемента, который разбирается. Точно один набор фигурных скобок будет удален, если весь элемент окружен ими, т.е. следующие вводы и выводы приводят к результату (каждый отдельный элемент как группа фигурных скобок):
a ==> {a}
{a} ==> {a}
{a}b ==> {{a}b}
a,b ==> {a}{b}
{a},b ==> {a}{b}
a,{b} ==> {a}{b}
a,{b}c ==> {a}{{b}c}
\ProcessList {⟨список⟩} {⟨токены⟩}
Чтобы поддержать \SplitList, доступна функция \ProcessList, которая применяет ⟨токены⟩ ко всем элементам в ⟨списке⟩. ⟨Токены⟩ могут содержать произвольные данные, которые ожидают один аргумент после них: элемент списка. Например:
\NewDocumentCommand \foo {>{\SplitList{;}} m}
{\ProcessList{#1}{\SomeDocumentCommand}}
или
\NewDocumentCommand \foo {>{\SplitList{;}} m}
{\ProcessList{#1}{Abc \SomeDocumentCommand}}
\ReverseBoolean
Этот процессор изменяет логику \BooleanTrue и \BooleanFalse, так что пример из предыдущего раздела будет выглядеть следующим образом:
\NewDocumentCommand\foo{>{\ReverseBoolean} s m} {%
\IfBooleanTF#1%
{\DoSomethingWithoutStar{#2}}%
{\DoSomethingWithStar{#2}}%
}
\TrimSpaces
Удаляет любые ведущие и завершающие пробелы (токены с кодом символа 32 и кодом категории 10) на концах аргумента. Таким образом, например, объявление функции:
\NewDocumentCommand\foo {>{\TrimSpaces} m}
{\showtokens{#1}}
и использование ее в документе как:
\foo{␣hello␣world␣}
покажет «hello␣world» в терминале, при этом пробелы в начале и в конце будут удалены. \TrimSpaces удалит множественные пробелы с концов ввода в случаях, когда они были включены так, что стандартное преобразование TEX, которое сводит множественные пробелы к одному, не применяется.
2.11 Тело окружения
Хотя окружения \begin{⟨окружение⟩} ... \end{⟨окружение⟩} обычно используются в случаях, когда код, реализующий ⟨окружение⟩, не нуждается в доступе к содержимому окружения (его «телу»), иногда полезно иметь тело в качестве стандартного аргумента. Это достигается путем завершения спецификации аргумента с помощью b, который является специальным типом аргумента для этой ситуации. Например:
\NewDocumentEnvironment{twice} {O{\ttfamily} +b} {#2#1#2} {}
\begin{twice}[\itshape]
Hello world!
\end{twice}
выводит «Hello world!Hello world!».
Префикс + используется для разрешения нескольких абзацев в теле окружения. Процессоры аргументов также могут применяться к аргументам типа b. По умолчанию пробелы обрезаются в начале и в конце тела: в приведенном примере в противном случае будут пробелы, исходящие из концов строк после [\itshape] и world!. Добавление префикса ! перед b подавляет обрезку пробелов.
Когда b используется в спецификации аргумента, последний аргумент объявления окружения (например, \NewDocumentEnvironment), который состоит из ⟨кода завершения⟩ для вставки в \end{⟨окружение⟩}, является избыточным, так как можно просто поместить этот код в конец ⟨кода начала⟩. Тем не менее, этот (пустой) ⟨код завершения⟩ должен быть предоставлен.
Окружения, использующие эту функцию, могут быть вложенными.
2.12 Полностью расширяемые команды документа
Команды документа, созданные с помощью \NewDocumentCommand и т.д., обычно создаются так, чтобы они не расширялись неожиданно. Это достигается с использованием возможностей движка, поэтому это более мощно, чем механизм \protect в LATEX 2ε. Существуют очень редкие случаи, когда может быть полезно создать функции с использованием захватчика, который работает только на расширении. Это накладывает ряд ограничений на природу аргументов, принимаемых функцией, и на код, который она реализует. Эта возможность должна использоваться только в случае необходимости.
Команды для создания полностью расширяемых команд
\NewExpandableDocumentCommand {⟨cmd⟩} {⟨arg spec⟩} {⟨code⟩}
\RenewExpandableDocumentCommand {⟨cmd⟩} {⟨arg spec⟩} {⟨code⟩}
\ProvideExpandableDocumentCommand {⟨cmd⟩} {⟨arg spec⟩} {⟨code⟩}
\DeclareExpandableDocumentCommand {⟨cmd⟩} {⟨arg spec⟩} {⟨code⟩}
Эта группа команд используется для создания команды документа уровня ⟨cmd⟩, которая будет захватывать свои аргументы в полностью расширяемом режиме. Спецификация аргументов для функции задается с помощью ⟨arg spec⟩, а ⟨cmd⟩ будет выполнять ⟨code⟩. В общем, ⟨code⟩ также будет полностью расширяемым, хотя возможно, что это не так (например, функция для использования в таблице может расширяться так, что \omit будет первым нерасширяемым не-пробельным токеном).
Ограничения при парсинге аргументов
Парсинг аргументов с помощью чистого расширения накладывает ряд ограничений как на типы аргументов, которые могут быть прочитаны, так и на доступную проверку ошибок:
- Последний аргумент (если таковой имеется) должен быть одним из обязательных типов
m,rилиR. - Аргумент типа «вербатим»
vнедоступен. - Процессоры аргументов (с использованием
>) недоступны. - Невозможно различить, например,
\foo[и\foo{[}: в обоих случаях[будет интерпретироваться как начало необязательного аргумента. В результате проверка на необязательные аргументы менее надежна, чем в стандартной версии.
2.13 Команды в начале ячеек таблицы
Создание команд, которые используются в начале ячеек таблицы, накладывает некоторые ограничения на основную реализацию. Стандартные окружения LATEX для таблиц (такие как tabular и т.д.) используют механизм, который требует, чтобы любая команда, оборачивающая \multicolumn или подобные команды, была «расширяемой». Это не относится к командам, созданным с помощью \NewDocumentCommand и т.д., которые, как описано в разделе 2.12, используют функцию движка, предотвращающую такое «расширение».
Поэтому, чтобы создать такие обертки для использования в начале ячеек таблицы, необходимо использовать \NewExpandableDocumentCommand. Например:
\NewExpandableDocumentCommand\MyMultiCol{m}{\multicolumn{3}{c}{#1}}
\begin{tabular}{lcr}
a & b & c \\
\MyMultiCol{stuff} \\
\end{tabular}
В этом примере команда \MyMultiCol позволяет использовать \multicolumn в ячейках таблицы, обеспечивая необходимую расширяемость.
2.14 Использование аргументов типа verbatim
Как описано выше, аргумент типа v можно рассматривать как аналог команды \verb. Прежде чем рассмотреть, что это именно означает, важно выделить некоторые ключевые различия. Прежде всего, захват аргумента, подобного verbatim, отделен от его наборки: последнее будет рассмотрено в следующем разделе.
При захвате аргумента типа v LATEX сначала использует команду ядра \dospecials, чтобы отключить «специальный» характер символов. Затем он делает как пробелы, так и табуляции «активными», чтобы им можно было задать пользовательское определение. Все остальные символы захватываются как есть: это означает, что если какие-либо символы были сделаны «специальными» и не перечислены в \dospecials, возникнет ошибка (см. ниже).
Символы, которые захватываются как аргумент, — это все те, что находятся между двумя одинаковыми символами: в отличие от \verb, символы \,, {, } и % не могут использоваться в качестве разделителей. Если любой из захваченных токенов имеет «специальное» значение, будет выдана ошибка.
Для аргумента типа +v, который позволяет переносить строки внутри аргумента, символы новой строки преобразуются в команды \obeyedline. Стандартное определение \obeyedline — это простая команда \par, что позволяет захваченным токенам использоваться непосредственно в наборе. Локальное переопределение \obeyedline может быть использовано для достижения других результатов. Например, чтобы сохранить пустые строки при наборе, можно использовать:
\renewcommand*\obeyedline{\mbox{}\par}
Дополнительная информация о использовании этих аргументов в наборе представлена в следующем подразделе.
Некоторые дополнительные детали, которые могут быть полезны для тех, кто имеет больше знаний о TEX: не беспокойтесь, если это не имеет смысла для вас! Пробелы и табуляции хранятся как активные символы. В 8-битных движках не-ASCII символы являются «активными», в то время как все символы ASCII, кроме букв a–zA–Z, являются «другими». В Юникодных движках не-ASCII кодовые точки будут либо буквами, либо «другими», в зависимости от стандартных настроек LATEX, основанных на данных Юникода. Для сравнений на основе токенов, вероятно, активные пробелы и табуляции должны быть заменены: это можно удобно сделать с помощью расширения.
2.15 Набор материала, подобного verbatim
В отличие от \verb, аргумент типа (+)v касается только захвата аргумента, а не его набора. Таким образом, функции, которые пользователи часто ассоциируют с «verbatim», не активируются автоматически, например, выбор моноширинного шрифта. Материал, захваченный аргументом типа v, не подавляет автоматически лигатуры: с современными движками TEX это в значительной степени можно сделать без манипуляций с токенами, которые использует \verb. (В \verb лигатуры подавляются путем активации символов и вставки нулевой ширины керна перед самим символом.)
Команда \verb также выбирает моноширинный шрифт: это не является внутренним для verbatim-материала, поэтому его нужно настраивать, например, с помощью \ttfamily. Аналогично, окружение verbatim настраивает значение \par, подходящее для переноса строк.
2.16 Окружения verbatim
В некоторых случаях, когда вы захватываете тело окружения, вы захотите, чтобы содержимое обрабатывалось как verbatim. Это доступно с использованием спецификации аргумента c. Как и спецификация b, это должно быть последним. Таким образом, например:
\NewDocumentEnvironment{MyVerbatim}{!O{\ttfamily} c} {\begin{center} #1 #2\end{center}} {}
\begin{MyVerbatim}[\ttfamily\itshape]
% Some code is shown here
$y = mx + c$
\end{MyVerbatim}
будет выводить содержимое verbatim, таким образом:
␣␣%␣Some␣code␣is␣shown␣here
␣␣$y␣=␣mx␣+␣c$
Поскольку захват всего содержимого verbatim приведет к отсутствию токенов \par, новые строки всегда разрешены: здесь нет необходимости в модификаторе +. Как и в спецификации v, новые строки хранятся как \obeyedline. Аналогично спецификации b, по умолчанию новые строки обрезаются в начале и в конце тела. Добавление префикса ! перед c подавляет эту обрезку.
Сбор тела происходит построчно: содержимое собирается до конца строки в исходном коде, затем проверяется перед хранением. Это означает, что строка, завершающая окружение (содержащая в приведенном выше примере \end{MyVerbatim}), не может содержать текст после конца окружения. Текст перед концом окружения обрабатывается нормально, но обратите внимание, что если здесь есть текст, то не добавляется завершающий \obeyedline. Кроме необязательных аргументов, текст не допускается на открывающей строке окружения.
Специальная обработка применяется к аргументам с спецификацией o, O, d или D, которые идут сразу перед спецификацией c. Это означает, что когда необязательный аргумент отсутствует, первый символ следующей строки будет прочитан с правильно примененным кодом категории verbatim. Проблемы могут возникнуть, если несколько необязательных аргументов используются перед спецификацией c: это будет работать надежно только в тех случаях, когда необязательные токены являются «другими» символами.
По техническим причинам мы рекомендуем не игнорировать пробелы при поиске необязательного аргумента перед спецификацией c: это можно сделать, добавив модификатор !, как показано в примере. Однако это оставлено на усмотрение пользователя.
2.17 Производительность
Для команд документа, где спецификация аргументов полностью состоит из записей m или +m (или полностью пуста), внутренняя структура, создаваемая с помощью \NewDocumentCommand, по сути, так же эффективна, как и предоставляемая \newcommand(*). Таким образом, команды документа могут заменять конструкции, возникающие из \newcommand и т.д., без необходимости беспокоиться о производительности. Следует отметить, что \newcommand(*) производит расширяемые результаты, поэтому прямой заменой является \NewExpandableDocumentCommand; однако в большинстве случаев лучше использовать \NewDocumentCommand, чтобы обеспечить более надежные структуры.
2.18 Подробности о разделителях аргументов
В обычных (нерасширяемых) командах делимитированные типы ищут начальный разделитель, заглядывая вперед (с использованием функций \peek_... из expl3), ища токен-разделитель. Токен должен иметь то же значение и «форму», что и токен, определенный как разделитель. Существует три возможных случая разделителей: символы, управляющие последовательности и активные символы. Для всех практических целей этого описания активные символы будут вести себя точно так же, как управляющие последовательности.
2.18.1 Символьные токены
Символьный токен характеризуется своим кодом символа, а его значение — кодом категории (\catcode). Когда команда определяется, значение символьного токена фиксируется в определении команды и не может изменяться. Команда правильно увидит разделитель аргумента, если открывающий разделитель имеет те же коды символа и категории, что и в момент определения. Например:
\NewDocumentCommand { \foobar } { D<>{default} } {(#1)}
\foobar <hello> \par
\char_set_catcode_letter:N <
\foobar <hello>
вывод будет:
(hello)
(default)<hello>
так как открывающий разделитель < изменил свое значение между двумя вызовами \foobar, поэтому второй вызов не видит < как допустимый разделитель. Команды предполагают, что если был найден допустимый открывающий разделитель, то также будет соответствующий закрывающий разделитель. Если его нет (либо из-за пропуска, либо из-за изменения значения), возникает ошибка низкого уровня TEX, и вызов команды прерывается.
2.18.2 Токены управляющих последовательностей
Токен управляющей последовательности (или управляющего символа) характеризуется своим именем, а его значение — это его определение. Токен не может иметь два разных значения одновременно. Когда управляющая последовательность определяется как разделитель в команде, она будет обнаружена как разделитель всякий раз, когда имя управляющей последовательности встречается в документе, независимо от ее текущего определения. Например:
\cs_set:Npn \x { abc }
\NewDocumentCommand { \foobar } { D\x\y{default} } {(#1)}
\foobar \x hello\y \par
\cs_set:Npn \x { def }
\foobar \x hello\y
вывод будет:
(hello)
(hello)
при этом оба вызова команды видят разделитель \x.
2.19 Создание новых процессоров аргументов
\ProcessedArgument
Процессоры аргументов позволяют манипулировать захваченным аргументом перед его передачей в основной код. Новые реализации процессоров могут быть созданы в виде функций, которые принимают один завершающий аргумент и оставляют свой результат в переменной \ProcessedArgument.
Например, \ReverseBoolean определяется следующим образом:
\ExplSyntaxOn
\cs_new_protected:Npn \ReverseBoolean #1 {
\bool_if:NTF #1 {
\tl_set:Nn \ProcessedArgument { \c_false_bool }
} {
\tl_set:Nn \ProcessedArgument { \c_true_bool }
}
}
\ExplSyntaxOff
Примечание: Код написан на языке expl3, поэтому нам не нужно беспокоиться о том, что пробелы могут попасть в определение.
3 Копирование и отображение (робустных) команд и окружений
Если вы хотите (слегка) изменить существующую команду, вам может понадобиться сохранить текущее определение под новым именем, а затем использовать его в новом определении. Если существующая команда является робустной, то старый трюк с использованием низкоуровневой команды \let не сработает, потому что он копирует только верхнее определение, но не ту часть, которая фактически выполняет работу. Поскольку большинство команд LATEX в настоящее время являются робустными, LATEX предлагает некоторые высокоуровневые объявления для этого.
Однако, пожалуйста, обратите внимание, что обычно лучше использовать доступные хуки (например, хуки для общих команд или окружений), вместо того чтобы копировать текущее определение и тем самым замораживать его; смотрите документацию по управлению хуками lthooks-doc.pdf для получения подробной информации.
\NewCommandCopy {⟨cmd⟩} {⟨existing-cmd⟩}
\RenewCommandCopy {⟨cmd⟩} {⟨existing-cmd⟩}
\DeclareCommandCopy {⟨cmd⟩} {⟨existing-cmd⟩}
Эти команды копируют определение ⟨existing-cmd⟩ в ⟨cmd⟩. После этого ⟨existing-cmd⟩ может быть переопределен, и ⟨cmd⟩ все еще будет работать! Это позволяет вам предоставить новое определение для ⟨existing-cmd⟩, которое использует ⟨cmd⟩ (т.е. его старое определение). Например, после
\NewCommandCopy\LaTeXorig\LaTeX
\RenewDocumentCommand\LaTeX{}{\textcolor{blue}{\LaTeXorig}}
все логотипы LATEX, сгенерированные с помощью \LaTeX, будут отображаться синим цветом (при условии, что у вас загружен пакет цвета).
Различия между \New... и \Renew... такие же, как и в других случаях: вы получите ошибку в зависимости от того, существует ли уже ⟨cmd⟩, или в случае \Declare... оно будет скопировано независимо от этого. Обратите внимание, что нет объявления \Provide..., потому что это было бы ограниченной ценностью.
Если ⟨cmd⟩ или ⟨existing-cmd⟩ не могут быть предоставлены как единый токен, а требуют “конструирования”, вы можете использовать \ExpandArgs, как объясняется в разделе 4.
\ShowCommand {⟨cmd⟩}
Эта команда отображает значение ⟨cmd⟩ в терминале и затем останавливается (так же, как и примитивная \show). Разница в том, что она правильно показывает значение более сложных команд, например, в случае робустных команд она отображает не только верхнее определение, но и фактический код нагрузки, а в случае команд, объявленных с помощью \NewDocumentCommand и т.д., она также предоставляет подробную информацию о сигнатуре аргументов.
\NewEnvironmentCopy {⟨env⟩} {⟨existing-env⟩}
\RenewEnvironmentCopy {⟨env⟩} {⟨existing-env⟩}
\DeclareEnvironmentCopy {⟨env⟩} {⟨existing-env⟩}
Эти команды копируют определение окружения ⟨existing-env⟩ в ⟨env⟩ (как начальный, так и конечный код), т.е. это просто применение \NewCommandCopy дважды к внутренним командам, которые определяют окружение, т.е. \⟨env⟩ и \end⟨env⟩. Различия между \New..., \Renew... и \Declare... являются обычными.
\ShowEnvironment {⟨env⟩}
Эта команда отображает значение начального и конечного кода для окружения ⟨env⟩.
4 Предварительное построение имен команд (или иное расширение аргументов)
При объявлении новых команд с помощью \NewDocumentCommand, \NewCommandCopy или аналогичных команд иногда необходимо “построить” имя команды. В качестве общего механизма L3 программный уровень предлагает \exp_args:N... для этой цели, но нет механизма для этого, если \ExplSyntaxOn не активен (и смешивание команд программного и пользовательского уровней не является хорошим подходом). Поэтому мы предлагаем механизм для доступа к этой возможности с использованием именования в стиле CamelCase.
\UseName {⟨string⟩}
\ExpandArgs {⟨spec⟩} {⟨cmd⟩} {⟨arg1⟩} . . .
\UseName преобразует ⟨string⟩ непосредственно в имя команды и затем выполняет его: это эквивалентно давно существующей внутренней команде LATEX 2ε \@nameuse или эквиваленту L3 программирования \use:c. \ExpandArgs принимает ⟨spec⟩, который описывает, как расширять ⟨arguments⟩, выполняет эти операции, а затем выполняет ⟨cmd⟩. ⟨spec⟩ использует описания, предлагаемые L3 программным уровнем, и соответствующая функция \exp_args:N... должна существовать. Общие случаи будут иметь ⟨spec⟩ в виде c, cc или Nc: см. ниже.
В качестве примера, следующее объявление предоставляет метод для генерации команд редактирования:
\NewDocumentCommand\newcopyedit{mO{red}} {
\newcounter{todo#1}%
\ExpandArgs{c}\NewDocumentCommand{#1}{s m} {
\stepcounter{todo#1}%
\IfBooleanTF {##1} {
\todo[color=#2!10]{\UseName{thetodo#1}: ##2}%
} {
\todo[inline,color=#2!10]{\UseName{thetodo#1}: ##2}%
}%
}%
}
С учетом этого объявления вы можете написать \newcopyedit{note}[blue], что определит команду \note и соответствующий счетчик для вас.
Второй пример — это копирование команды по строковому имени с использованием \NewCommandCopy: здесь нам может понадобиться построить оба имени команд.
\NewDocumentCommand\savebyname{m} {
\ExpandArgs{cc}\NewCommandCopy{saved#1}{#1}
}
В ⟨spec⟩ каждая c обозначает один аргумент, который преобразуется в команду. n представляет собой “нормальный” аргумент, который не изменяется, а N обозначает “нормальный” аргумент, который также остается неизменным, но состоит только из одного токена (и обычно не заключен в фигурные скобки). Таким образом, чтобы построить команду из строки только для второго аргумента \NewCommandCopy, вы бы написали:
\ExpandArgs{Nc}\NewCommandCopy\mysectionctr{c@section}
Существует несколько других одиночных букв, поддерживаемых в L3 программном уровне, которые могут быть использованы в ⟨spec⟩ для манипуляции аргументами другими способами. Если вас это интересует, ознакомьтесь с разделом “Расширение аргументов” в документации L3 программного уровня в файле interface3.pdf.
5 Расширяемые вычисления с плавающей точкой (и другие)
Программный уровень LATEX3, который является частью формата, предлагает богатый интерфейс для манипуляции переменными и значениями с плавающей точкой. Чтобы позволить (более простым) приложениям использовать это на уровне документа или в пакетах, которые иначе не используют L3 программный уровень, предоставляется несколько интерфейсных команд.
\fpeval {⟨floating point expression⟩}
Расширяемая команда \fpeval принимает в качестве аргумента выражение с плавающей точкой и производит результат, используя обычные правила математики. Поскольку эта команда является расширяемой, ее можно использовать там, где TEX требует числа, например, в низкоуровневой операции \edef, чтобы получить чисто числовой результат.
Кратко, выражения с плавающей точкой могут включать:
- Основные арифметические операции: сложение
x + y, вычитаниеx - y, умножениеx * y, делениеx / y, квадратный кореньsqrt xи скобки. - Операторы сравнения:
x < y,x <= y,x > y,x != yи т.д. Отношениеx ? yистинно, если один или оба операнда являются NaN или являются кортежем, если только они не равны кортежам. Каждое ⟨отношение⟩ может быть любой (непустой) комбинацией<,=,>, и?, плюс необязательный ведущий!(который отрицает ⟨отношение⟩), с ограничением, что отрицательное ⟨отношение⟩ не может начинаться с?. - Булева логика: знак
sign x, отрицание! x, конъюнкцияx && y, дизъюнкцияx || y, тернарный операторx ? y : z. - Экспоненты:
exp x,ln x,xˆy. - Целочисленный факториал:
fact x. - Тригонометрия:
sin x,cos x,tan x,cot x,sec x,csc x, ожидая, что их аргументы будут в радианах, иsind x,cosd x,tand x,cotd x,secd x,cscd x, ожидая, что их аргументы будут в градусах. - Обратные тригонометрические функции:
asin x,acos x,atan x,acot x,asec x,acsc x, дающие результат в радианах, иasind x,acosd x,atand x,acotd x,asecd x,acscd x, дающие результат в градусах. - Экстремумы:
max(x1, x2, ...),min(x1, x2, ...),abs(x). - Функции округления, управляемые двумя необязательными значениями,
n(количество знаков, по умолчанию 0) иt(поведение при равенстве, по умолчанию NaN):trunc(x, n)округляет к нулю,floor(x, n)округляет к −∞,ceil(x, n)округляет к +∞,round(x, n, t)округляет к ближайшему значению, при равенстве округляя к четному значению по умолчанию, к нулю, еслиt = 0, к +∞, еслиt > 0, и к −∞, еслиt < 0.
- Случайные числа:
rand(),randint(m, n). - Константы:
pi,deg(один градус в радианах). - Размерности, автоматически выраженные в пунктах, например,
pcравен 12. - Автоматическое преобразование (нет необходимости в
\number) целочисленных, размерных и пропускных переменных в числа с плавающей точкой, выражая размерности в пунктах и игнорируя компоненты растяжения и сжатия пропусков. - Кортежи:
(x1, ..., xn), которые могут быть сложены, умножены или разделены на число с плавающей точкой, а также могут быть вложенными. Пример использования может быть следующим:
\LaTeX{} может теперь вычислить: $ \frac{\sin (3.5)}{2} + 2\cdot 10^{-3} = \fpeval{sin(3.5)/2 + 2e-3} $.
Это приводит к следующему результату:
LATEX может теперь вычислить: sin(3.5) / 2 + 2 · 10−3 = −0.1733916138448099.
\inteval {⟨integer expression⟩}
Расширяемая команда \inteval принимает в качестве аргумента целочисленное выражение и производит результат, используя обычные правила математики с некоторыми ограничениями, см. ниже. Признаваемые операции: +, -, * и /, а также скобки. Поскольку эта команда является расширяемой, ее можно использовать там, где TEX требует числа, например, в низкоуровневой операции \edef, чтобы получить чисто числовой результат.
Это, по сути, тонкая оболочка для примитивной команды \numexpr, и поэтому имеет некоторые синтаксические ограничения. Эти ограничения следующие:
/обозначает деление, округленное до ближайшего целого числа, при этом при равенстве округление происходит от нуля;- возникает ошибка, и общее выражение оценивается в ноль, когда абсолютное значение любого промежуточного результата превышает (2^{31} - 1), за исключением случаев операций масштабирования (ab/c), для которых (ab) может быть произвольно большим;
- скобки не могут появляться после унарных
+или-, а именно, размещение+(или-(в начале выражения или после+,-,*,/или(приводит к ошибке.
Пример использования может быть следующим:
\LaTeX{} может теперь вычислить: Сумма чисел равна $\inteval{1 + 2 + 3}$.
Это приводит к результату:
LATEX может теперь вычислить: Сумма чисел равна 6.
\dimeval {⟨dimen expression⟩}
\skipeval {⟨skip expression⟩}
Эти команды аналогичны \inteval, но вычисляют длину (dimen) или значение резинки (skip). Обе команды являются тонкими оболочками вокруг соответствующих примитивов движка, что делает их быстрыми, но, следовательно, они имеют те же синтаксические особенности, как обсуждалось выше. Тем не менее, на практике они обычно достаточно эффективны. Например:
\NewDocumentCommand\calculateheight{m}{%
\setlength\textheight{\dimeval{\topskip+\baselineskip*\inteval{#1-1}}}
}
Эта команда устанавливает \textheight на соответствующее значение, если страница должна содержать определенное количество строк текста. Таким образом, после вызова \calculateheight{40} значение будет установлено на 478.0pt, учитывая значения \topskip (10.0pt) и \baselineskip (12.0pt) в текущем документе.
6 Расширяемый эквивалент \input
\expandableinput {⟨filename⟩}
Определение \input в LATEX не может быть использовано в местах, где TEX выполняет расширение: классический пример — в начале ячейки таблицы. Существует несколько причин для этого: ключевыми являются то, что \input фиксирует, какие файлы были прочитаны, и предоставляет хуки до и после чтения файла.
Чтобы поддержать необходимость выполнения ввода файла в контекстах расширения, доступна команда \expandableinput: она пропускает запись имени файла и не применяет никакие хуки для файлов, но в остальном ведет себя как \input. В частности, она по-прежнему использует \input@path при выполнении поиска файла.
7 Изменение регистра
\MakeUppercase [⟨keyvals⟩] {⟨text⟩}
\MakeLowercase [⟨keyvals⟩] {⟨text⟩}
\MakeTitlecase [⟨keyvals⟩] {⟨text⟩}
TEX предоставляет две примитивные команды \uppercase и \lowercase для изменения регистра текста. Однако у них есть ряд ограничений: они изменяют регистр только явных символов, не учитывают окружающий контекст, не поддерживают ввод UTF-8 с 8-битными движками и т.д. Чтобы преодолеть эту проблему, LATEX предоставляет команды \MakeUppercase, \MakeLowercase и \MakeTitlecase: они предлагают значительное улучшение по сравнению с примитивами TEX. Эти команды являются робустными (\protected) и могут использоваться в движущихся аргументах.
Изменение регистра в общем смысле хорошо понимается в разговорной речи. Заглавный регистр здесь следует определению, данному Консорциумом Unicode: первый символ входных данных будет преобразован в (широком смысле) заглавный регистр, а остальные символы — в строчный. Полный диапазон ввода Unicode UTF-8 может быть поддержан.
\MakeUppercase{hello WORLD ßüé} % HELLO WORLD SSÜÉ
\MakeLowercase{hello WORLD ßüé} % hello world ßüé
\MakeTitlecase{hello WORLD ßüé} % Hello WORLD ßüé
Команды изменения регистра принимают необязательный аргумент, который можно использовать для настройки вывода. Этот необязательный аргумент принимает ключ locale, также доступный под псевдонимом lang, который можно использовать для указания идентификатора языка в формате BCP-47. Это затем применяется для выбора языковых особенностей при изменении регистра.
Для заглавного регистра также могут использоваться ключевые слова: это выбор между first или all. Стандартная настройка — first, что означает, что только самый первый “буквенный” символ будет (широком смысле) преобразован в заглавный регистр. Альтернатива, all, означает, что входные данные делятся по каждому пробелу, и для каждого полученного слова первый символ будет преобразован в заглавный регистр. Например:
\MakeTitlecase[words=first]{some words} % Some words
\MakeTitlecase[words=all]{some words} % Some Words
Входные данные, переданные этим командам, “расширяются” перед применением изменения регистра. Это означает, что любые команды внутри входных данных, которые преобразуются в чистый текст, будут изменены по регистру. Математическое содержимое автоматически исключается, как и аргументы команд \label, \ref, \cite, \begin и \end. Дополнительные исключения могут быть добавлены с помощью команды \AddToNoCaseChangeList. Входные данные могут быть исключены из изменения регистра с помощью команды \NoCaseChange.
\MakeUppercase{Some text $y = mx + c$} % SOME TEXT y = mx + c
\MakeUppercase{\NoCaseChange{iPhone}} % iPhone
Чтобы позволить использовать робустные команды внутри изменения регистра и получить ожидаемый вывод, доступны две дополнительные управляющие команды. \CaseSwitch позволяет пользователю указать результат для четырех возможных случаев:
- Без изменения регистра
- Преобразование в заглавный регистр
- Преобразование в строчный регистр
- Заглавный регистр (применяется только к началу входных данных)
Команда \DeclareCaseChangeEquivalent предоставляет способ заменить команду альтернативной версией, когда она встречается внутри ситуации изменения регистра. Существуют три команды для настройки изменения регистра кодовых точек:
\DeclareLowercaseMapping [⟨locale⟩] {⟨codepoint⟩} {⟨output⟩}
\DeclareTitlecaseMapping [⟨locale⟩] {⟨codepoint⟩} {⟨output⟩}
\DeclareUppercaseMapping [⟨locale⟩] {⟨codepoint⟩} {⟨output⟩}
Все три принимают ⟨codepoint⟩ (в виде целочисленного выражения) и приводят к тому, что
8 Поддержка решения проблем
\listfiles [⟨options⟩]
Если эта команда помещена в преамбулу, то в конце выполнения документа на терминале (и в лог-файле) будет отображен список прочитанных файлов (в результате обработки документа). При возможности также будет предоставлено краткое описание. Эти описания, надеемся, будут включать описания, даты и номера версий для файлов пакетов и классов.
Иногда может случиться так, что в файл пакета или класса (или, скорее, в его копию) были внесены локальные изменения. Чтобы позволить идентифицировать такие случаи, \listfiles принимает необязательный аргумент, который позволяет настроить выводимую информацию с использованием подхода ключ-значение:
hashes— добавляет MD5-хеш для каждого файла в выводимую информацию.sizes— добавляет размер файла для каждого файла в выводимую информацию.
Обратите внимание, что так как Windows и Unix используют разные окончания строк (LF против LF CR), хеши и размеры файлов из двух систем не будут одинаковыми. Поэтому следует сравнивать эти значения между операционными системами одного типа.
Предупреждение: эта команда будет перечислять только файлы, которые были прочитаны с использованием команд LATEX, таких как \input{⟨file⟩} или \include{⟨file⟩}. Если файл был прочитан с использованием примитивного синтаксиса TEX \input file (без фигурных скобок вокруг имени файла), то он не будет перечислен; несоблюдение формата LATEX с фигурными скобками может вызвать более серьезные проблемы, возможно, приведя к перезаписи важных файлов, поэтому всегда используйте фигурные скобки.
7.3.1 - Памятка по командам Latex 3
Краткая таблица с основными типами аргументов и их описанием:
| Ключ | Краткое описание |
|------|----------------------------------------------------------------------------------|
| **m** | Обычный обязательный аргумент (один токен или `{...}`). |
| **r** | Обязательный аргумент с разделителями (формат: `r⟨t1⟩⟨t2⟩`). |
| **R** | Как `r`, но с значением по умолчанию (формат: `R⟨t1⟩⟨t2⟩{⟨default⟩}`). |
| **v** | Дословный аргумент (аналог `\verb` в LaTeX). |
| **b** | Тело окружения (только для `\begin{...}...\end{...}`). |
| **o** | Необязательный аргумент в `[...]`, возвращает `-NoValue-` если отсутствует. |
| **d** | Необязательный аргумент с разделителями (формат: `d⟨t1⟩⟨t2⟩`). |
| **O** | Как `o`, но с значением по умолчанию (формат: `O{⟨default⟩}`). |
| **D** | Как `d`, но с значением по умолчанию (формат: `D⟨t1⟩⟨t2⟩{⟨default⟩}`). |
| **s** | Необязательная звезда (`*`), возвращает `\BooleanTrue`/`\BooleanFalse`. |
| **t** | Необязательный токен (формат: `t⟨token⟩`), возвращает `\BooleanTrue`/`False`. |
| **e** | Необязательные "украшения" (формат: `e{⟨tokens⟩}`), возвращает `-NoValue-`. |
| **E** | Как `e`, но с значениями по умолчанию (формат: `E{⟨tokens⟩}{⟨defaults⟩}`). |
| **+** | Модификатор: делает аргумент "длинным" (параграфным). |
| **!** | Модификатор: управляет пробелами перед необязательными аргументами. |
| **=** | Модификатор: аргумент интерпретируется как ключ-значение (keyvals). |
| **>** | Модификатор: применяет "процессор аргументов" для преобразования ввода. |
Создание команд документа
\NewDocumentCommand {⟨cmd⟩} {⟨arg spec⟩} {⟨code⟩}
\RenewDocumentCommand {⟨cmd⟩} {⟨arg spec⟩} {⟨code⟩}
\ProvideDocumentCommand {⟨cmd⟩} {⟨arg spec⟩} {⟨code⟩}
\DeclareDocumentCommand {⟨cmd⟩} {⟨arg spec⟩} {⟨code⟩}
Эта группа команд используется для создания команды ⟨cmd⟩. Спецификация аргумента для функции задается с помощью ⟨arg spec⟩, а команда использует ⟨code⟩, где #1, #2 и т. д. заменяются на аргументы, найденные парсером.
Пример:
\NewDocumentCommand\chapter{s o m} {
\IfBooleanTF{#1}
{\typesetstarchapter{#3}}
{\typesetnormalchapter{#2}{#3}}
}
Создание окружений документа
\NewDocumentEnvironment {⟨env⟩} {⟨arg spec⟩} {⟨beg-code⟩} {⟨end-code⟩}
\RenewDocumentEnvironment {⟨env⟩} {⟨arg spec⟩} {⟨beg-code⟩} {⟨end-code⟩}
\ProvideDocumentEnvironment {⟨env⟩} {⟨arg spec⟩} {⟨beg-code⟩} {⟨end-code⟩}
\DeclareDocumentEnvironment {⟨env⟩} {⟨arg spec⟩} {⟨beg-code⟩} {⟨end-code⟩}
Эти команды работают так же, как \NewDocumentCommand и т. д., но создают окружения (\begin{⟨env⟩} … \end{⟨env⟩}). Как ⟨beg-code⟩, так и ⟨end-code⟩ могут получать доступ к аргументам, как определено в ⟨arg spec⟩. Аргументы будут переданы после \begin{⟨env⟩}. Все пробелы в начале и в конце {⟨env⟩} удаляются перед определением, таким образом:
Проверка специальных значений
\IfNoValueTF {⟨arg⟩} {⟨true code⟩} {⟨false code⟩}
\IfNoValueT {⟨arg⟩} {⟨true code⟩}
\IfNoValueF {⟨arg⟩} {⟨false code⟩}
Команды \IfNoValue(TF) используются для проверки, является ли ⟨argument⟩ (#1, #2 и т. д.) специальным маркером -NoValue-. Например:
\NewDocumentCommand\foo{o m} {
\IfNoValueTF {#1}
{\DoSomethingJustWithMandatoryArgument{#2}}
{\DoSomethingWithBothArguments{#1}{#2}}
}
\IfValueTF {⟨arg⟩} {⟨true code⟩} {⟨false code⟩}
\IfValueT {⟨arg⟩} {⟨true code⟩}
\IfValueF {⟨arg⟩} {⟨false code⟩}
Обратная форма тестов \IfNoValue(TF) также доступна как \IfValue(TF). Контекст определит, какая логическая форма имеет наибольший смысл для данного сценария кода.
\IfBlankTF {⟨arg⟩} {⟨true code⟩} {⟨false code⟩}
\IfBlankT {⟨arg⟩} {⟨true code⟩}
\IfBlankF {⟨arg⟩} {⟨false code⟩}
Таблица описывающая команды проверки специальных значений:
| Команда | Краткое описание |
|-----------------------------|----------------------------------------------------------------------------------|
| `\BooleanFalse` | Логическое значение "ложь" (используется с аргументами `s`/`t`). |
| `\BooleanTrue` | Логическое значение "истина" (используется с аргументами `s`/`t`). |
| `\IfBooleanTF{arg}{true}{false}` | Проверяет, является ли `arg` булевым значением (`\BooleanTrue`/`\BooleanFalse`). |
| `\IfBooleanT{arg}{true}` | Выполняет `true` код, если `arg` равно `\BooleanTrue`. |
| `\IfBooleanF{arg}{false}` | Выполняет `false` код, если `arg` равно `\BooleanFalse`. |
| `\IfNoValueTF{arg}{true}{false}` | Проверяет, равен ли `arg` маркеру `-NoValue-`. |
| `\IfNoValueT{arg}{true}` | Выполняет `true` код, если `arg` равен `-NoValue-`. |
| `\IfNoValueF{arg}{false}` | Выполняет `false` код, если `arg` **не** равен `-NoValue-`. |
| `\IfValueTF{arg}{true}{false}` | Обратная логика: `true` если `arg` **имеет** значение. |
| `\IfValueT{arg}{true}` | Выполняет `true` код, если `arg` **имеет** значение. |
| `\IfValueF{arg}{false}` | Выполняет `false` код, если `arg` **не имеет** значения. |
| `\IfBlankTF{arg}{true}{false}` | Проверяет, является ли `arg` пустым или содержит только пробелы. |
| `\IfBlankT{arg}{true}` | Выполняет `true` код, если `arg` пустой/пробельный. |
| `\IfBlankF{arg}{false}` | Выполняет `false` код, если `arg` **не** пустой. |
Пример использования:
\NewDocumentCommand\foo{o m}{
\IfNoValueTF{#1}
{Команда без опции: #2}
{Команда с опцией [#1] и аргументом #2}
}
Таблица с описанием процессоров аргументов и примерами их использования:
| Процессор | Описание | Пример использования |
|--------------------------------|--------------------------------------------------------------------------|--------------------------------------------------------------------------------------|
| **`\SplitArgument{n}{sep}`** | Разделяет аргумент по `sep` на `n+1` частей, оборачивая в `{}`. | `\NewDocumentCommand\foo{>{\SplitArgument{2}{;}}m}{#1}` → `\foo{a;b;c}` → `{a}{b}{c}` |
| **`\SplitList{sep}`** | Разделяет аргумент по `sep` на неограниченное число частей. | `\NewDocumentCommand\foo{>{\SplitList{,}}m}{\ProcessList{#1}{\textbf}}` → `\foo{a,b}` → **a** **b** |
| **`\ProcessList{list}{cmd}`** | Применяет `cmd` к каждому элементу `list` (используется с `\SplitList`). | `\ProcessList{{a}{b}}{\textbf}` → **a****b** |
| **`\ReverseBoolean`** | Инвертирует булевы значения (`\BooleanTrue` ↔ `\BooleanFalse`). | `\NewDocumentCommand\foo{>{\ReverseBoolean}s}{Star: \IfBooleanT{#1}{YES}}` → `\foo*` выведет "Star: NO" |
| **`\TrimSpaces`** | Удаляет пробелы в начале/конце аргумента. | `\NewDocumentCommand\foo{>{\TrimSpaces}m}{[#1]}` → `\foo{ text }` → `[text]` |
| **Комбинация процессоров** | Процессоры применяются справа налево. | `>{\TrimSpaces} >{\SplitList{,}} m` → сначала разделит запятыми, затем обрежет пробелы. |
Примеры использования
Разделение аргументов с обработкой:
\NewDocumentCommand\formatlist{>{\SplitList{,}}m}{ \ProcessList{#1}{\textbf} } \formatlist{a, b, c} % → **a** **b** **c**Обработка ключевых значений:
\NewDocumentCommand\setoptions{>{\TrimSpaces}m}{ \keys_set:nn {my-module} {#1} } \setoptions{ key1 = value1 , key2 = value2 }Инверсия логики звездочки:
\NewDocumentCommand\checkstar{>{\ReverseBoolean}s}{ \IfBooleanT{#1}{Звезды НЕТ} \IfBooleanF{#1}{Звезда ЕСТЬ} } \checkstar* % Выведет "Звезда ЕСТЬ"Многоэтапная обработка:
\NewDocumentCommand\process{>{\TrimSpaces} >{\SplitList{;}} m}{ \ProcessList{#1}{\SomeCommand} } \process{ a; b; c } % → обработает как `{a}{b}{c}`
7.4 - Пакеты для работы с таблицами в LaTeX
Пакет longtable
Назначение
Пакет longtable позволяет создавать таблицы, которые могут разбиваться на несколько страниц. Это особенно полезно для длинных таблиц, которые не помещаются на одной странице.
Основные возможности
- Автоматический разрыв таблицы на страницы
- Повторение заголовков на каждой странице
- Настройка оформления разрывов
Пример использования
\usepackage{longtable}
% Настройка отступов в таблицах
\renewcommand{\tabcolsep}{0.05cm} % Горизонтальный отступ между колонками
\renewcommand{\arraystretch}{1.7} % Вертикальное растяжение строк
\begin{center}
% Настройка цветов таблицы
\rowcolors{2}{gray!10}{white} % Чередование цветов строк (начиная со 2-й)
\arrayrulecolor{gray!20} % Цвет линий таблицы
% Начало длинной таблицы (может переноситься на несколько страниц)
% Формат колонок: B{2} - жирная шириной 2cm, L{8} и L{5} - обычные шириной 8cm и 5cm
\begin{longtable}{B{2}|L{8}|L{5}}
%%% ЗАГОЛОВОК НА ПЕРВОЙ СТРАНИЦЕ %%%
\caption[Технические характеристики]{Основные характеристики \label{tab:tech-character}}\\
\rowcolor{black!90} % Цвет фона заголовка
% Названия колонок (белый текст на темном фоне)
\multicolumn{1}{c}{\color{white}{№}} &
\multicolumn{1}{c}{\color{white}{Характеристика}} &
\multicolumn{1}{c}{\color{white}{Значение}} \\
\endfirsthead % Конец заголовка для первой страницы
%%% ЗАГОЛОВОК НА СЛЕДУЮЩИХ СТРАНИЦАХ %%%
\caption[]{Продолжение таблицы}\\
\rowcolor{black!90}
\multicolumn{1}{c}{№} &
\multicolumn{1}{c}{Характеристика} &
\multicolumn{1}{c}{Значение} \\
\endhead % Конец заголовка для последующих страниц
%%% ТЕЛО ТАБЛИЦЫ %%%
1 & Вес: & 80кг \\
2 & Габаритные размеры: & 730мм * 530мм * 850мм \\
3 & Напряжение управляющего питания (низковольтное): & 9-30 Вольт \\
\end{longtable}
\end{center}
Пояснение ключевых команд:
Настройка внешнего вида таблицы:
\tabcolsep- расстояние между колонками\arraystretch- коэффициент растяжения строк по вертикали\rowcolors- чередование цветов строк\arrayrulecolor- цвет линий таблицы
Структура таблицы:
\begin{longtable}{формат_колонок}- начало длинной таблицы- Формат колонок:
B{2}|L{8}|L{5}- три колонки с заданной шириной и выравниванием
Заголовки:
\caption- название таблицы (в квадратных скобках - для списка таблиц)\endfirsthead- заголовок только для первой страницы\endhead- заголовок для последующих страниц
Форматирование содержимого:
\rowcolor- цвет фона строки\multicolumn- объединение ячеек по горизонтали\color- цвет текста
Специальные символы:
\diameter- символ диаметра (из пакета wasysym)
Этот пример создает профессионально оформленную таблицу с:
- автоматическим переносом на несколько страниц
- повторяющимися заголовками
- чередованием цветов строк
- настраиваемыми отступами и выравниванием
Пользовательские типы колонок
\newcolumntype{C}[1]{>{\columncolor{white}\ttfamily\centering\arraybackslash}p{#1cm}}
\newcolumntype{R}[1]{>{\columncolor{white}\ttfamily\raggedleft\arraybackslash}p{#1cm}}
\newcolumntype{L}[1]{>{\columncolor{white}\ttfamily\raggedright\arraybackslash}p{#1cm}}
\newcolumntype{B}[1]{>{\columncolor{white}\ttfamily\bfseries\raggedright\arraybackslash}p{#1cm}}
Эти определения создают новые типы колонок:
C- центрированное содержимоеR- выравнивание по правому краюL- выравнивание по левому краюB- полужирное содержимое с выравниванием по левому краю
Пакет tabbing
Назначение
Среда tabbing предоставляет простой способ создания таблиц с выравниванием по табуляции. Полезен для простых таблиц без рамок.
Пример использования
\begin{tabbing}
Первая колонка \= Вторая колонка \= Третья колонка \kill
Заголовок 1 \> Заголовок 2 \> Заголовок 3 \\
Данные 1 \> Данные 2 \> Данные 3 \\
Выровнено \> по \> табуляторам \\
\end{tabbing}
Основные команды
\=- установка табулятора\>- переход к следующему табулятору\kill- строка используется для установки табуляторов, но не печатается
Пакет array
Назначение
Пакет array расширяет возможности работы с таблицами, предоставляя дополнительные функции для форматирования колонок и строк.
Основные возможности
- Дополнительные спецификаторы колонок
- Улучшенное выравнивание
- Возможность вставки команд перед/после элементов
Примеры использования
- Математическое выравнивание:
\begin{tabular}{>{$}l<{$} >{\centering\arraybackslash}m{2cm}}
\alpha & Буква альфа \\
\beta & Буква бета \\
\end{tabular}
- Условное форматирование:
\begin{tabular}{|>{\ifnum\value{rownum}=1 \bfseries\fi}l|l|}
\hline
Строка 1 & Данные 1 \\
Строка 2 & Данные 2 \\
\hline
\end{tabular}
- Использование пользовательских колонок:
\newcolumntype{M}[1]{>{\centering\arraybackslash}m{#1}}
\begin{tabular}{|M{2cm}|M{3cm}|}
Центрированная & колонка \\
ячейка & с заданной шириной \\
\end{tabular}
Полезные команды
\extrarowheight- добавление дополнительного пространства в строках\newcolumntype- определение новых типов колонок\multicolumn- объединение колонок (также доступно без array)
Эти пакеты предоставляют мощные инструменты для создания профессионально оформленных таблиц в LaTeX, от простых до самых сложных.
7.5 - Описание пакетов fancyhdr и fancybox
fancyhdr и fancybox, включая ваши настройки и дополнительные примеры.Пакеты fancyhdr и fancybox
Назначение: Оформление колонтитулов (fancyhdr) и декоративных рамок (fancybox).
1. fancyhdr
Основные возможности
- Настройка верхних (
head) и нижних (foot) колонтитулов. - Разные стили для чётных/нечётных страниц (
twoside). - Автоматическая подстановка номеров страниц, названий разделов.
Команды и параметры
Инициализация
\usepackage[twoside,headings]{fancyhdr} % twoside — разные колонтитулы для чётных/нечётных страниц
\pagestyle{fancy} % Активирует стиль fancy
\fancyhf{} % Очистка текущих настроек
Настройка колонтитулов
\fancyhead[позиция]{содержимое}– верхний колонтитул.\fancyfoot[позиция]{содержимое}– нижний колонтитул.
Позиции:
L– слева,C– центр,R– справа.E– чётная страница,O– нечётная.- Комбинации:
LE,RO,CEи т.д.
Пример:
\fancyhead[LE,RO]{\leftmark} % Название раздела (для чётных и нечётных)
\fancyfoot[C]{\thepage} % Номер страницы по центру
Ваш пример с tikz для фона
\AddEverypageHook{
\begin{tikzpicture}[remember picture,overlay]
\fill[black!90] (current page.north west) rectangle ($(current page.north east)+(0,-22mm)$);
\fill[black!90] (current page.south west) rectangle ($(current page.south east)+(0,15mm)$);
\end{tikzpicture}
}
\fancyhead[LE,RO]{\raisebox{1.2em}{\color{white}{\Large\leftmark}}}
\fancyfoot[LE,RO]{\color{white}{\textbf{\thepage}}}
Удаление разделительных линий
\renewcommand{\headrulewidth}{0pt} % Убирает линию под верхним колонтитулом
\renewcommand{\footrulewidth}{0pt} % Убирает линию над нижним колонтитулом
2. fancybox
Назначение: Создание декоративных рамок вокруг текста.
Основные команды
\shadowbox{текст}– рамка с тенью.\doublebox{текст}– двойная рамка.\ovalbox{текст}– овальная рамка.
Пример:
\usepackage{fancybox}
...
\shadowbox{\parbox{10cm}{Это текст в рамке с тенью.}}
\doublebox{\parbox{10cm}{Это текст в двойной рамке.}}
Кастомизация
\setlength{\shadowrule}{1pt} % Толщина тени
\setlength{\shadowsize}{4pt} % Размер тени
Примеры использования
1. Разные колонтитулы для глав и страниц
\fancyhead[LE]{\color{white}Глава \thechapter}
\fancyhead[RO]{\color{white}\nouppercase{\rightmark}}
\fancyfoot[CO,CE]{\color{white}\thepage}
2. Логотип и номер страницы
\fancyhead[L]{\includegraphics[width=2cm]{logo}}
\fancyfoot[R]{\thepage}
3. Рамки для выделения текста
\ovalbox{
\begin{minipage}{0.9\linewidth}
Важное замечание: этот текст выделен овальной рамкой.
\end{minipage}
}
Заключение
fancyhdrидеален для сложных колонтитулов с графикой и динамическим содержимым.fancyboxполезен для визуального выделения блоков текста.
7.6 - TEX издательская система
Я от части пожалел, что сначала изучил Latex, а потом взялся за TeX.
Установка TeX
https://tug.org/texlive/doc/texlive-ru/texlive-ru.html
Установите Tex Live для полного удовлетворения своих запросов в издательской системе TeX и LaTeX.
На этой странице полная инструкция по установке https://tug.org/texlive/acquire-netinstall.html
или набрать в командной строке:
sudo pacman -S texlive
#manjaro
или
pkg install texlive
#freebsd
7.6.1 - TEX команды
Символы
Специальные символы
- \# pound sign #
- \$ dollar sign $
- \% percent sign %
- \& ampersand &
- \_ underscore _
- \lq left quote ‘
- \rq right quote ’
- \lbrack left bracket [
- \rbrack right bracket ]
- \dag dagger symbol †
- \ddag double dagger symbol ‡
- \copyright copyright symbol c©
- \P paragraph symbol ¶
- \S section symbol §
Произвольные символы
{\char65} {\char `A} {\char `\A}
Акценты
| наименование | Tex input | Tex output | Compose |
|---|---|---|---|
| grave | \`o | ò | cmp+` o |
| acute | \’o | ó | cmp+’ o |
| circumflex | \^o | ô | cmp+^ o |
| umlaut/dieresis/tr ́emat | \“o | ö | cmp+” o |
| tilde | \~o | õ | cmp+~ o |
| macron | \=o | ő | cmp+= o |
| dot | \.o | ȯ | cmp+. o |
Продолжение для символов требующих пробела
| наименование | Tex input | Tex output | Compose |
|---|---|---|---|
| cedilla | \c o | ǫ | cmp+, o |
| underdot | \d o | ọ | cmp+! o |
| underbar | \b o | o᤻ | o C-x 8 RET 193b |
| h ́acˇek | \v o | ǒ | cmp+v o |
| breve | \u o | ŏ | cmp+u o |
| tie | \t oo | o͡o | o C-x 8 RET 0361 o |
| Hungarian umlaut | \H o | ő | cmp+= o |
| ơ | cmp++ o | ||
| ° | cmp+o o | ||
| § | cmp+s o | ||
| ø | cmp+? o |
или команда \accent94 или номер в таблице шрифта
Встроенные шрифты
| имя | описание |
|---|---|
| \fivebf | use 5-point bold font |
| \fivei | use 5-point math italic font |
| \fiverm | use 5-point roman font |
| \fivesy | use 5-point math symbol font |
| \sevenbf | use 7-point bold font |
| \seveni | use 7-point math italic font |
| \sevenrm | use 7-point roman font |
| \sevensy | use 7-point math symbol font |
| \tenbf | use 10-point bold text font |
| \tenex | use 10-point math extension font |
| \teni | use 10-point math italic font |
| \tenrm | use 10-point roman text font |
| \tensl | use 10-point slanted roman font |
| \tensy | use 10-point math symbol font |
| \tenit | use 10-point italic font |
| \tentt | use 10-point typewriter font |
\nullfont — отменить шрифты (пусто)
В Tex по умолчанию доступны 16 шрифтов
| Наименование | команда |
|---|---|
| Roman | \rm |
| Boldface | \bf |
| Italic | \it |
| Slanted | \sl |
| Typewriter | \tt |
| Math symbol5 | \cal |
Верхний и нижний регистр
\lccode 〈charcode〉 [ 〈number〉 table entry ]\uccode 〈charcode〉 [ 〈number〉 table entry ]
\char\uccode`s \char\lccode`a \char\lccode`M — выдаст Sam
Строка в верхний или нижний регистр
\lowercase { 〈token list〉 }
\uppercase { 〈token list〉 }
Пробелы
\— вставит пробел после команды~— неразрывный пробел\/— курсивный пробел\obeyspaces— не сжимает пробелы, а сохраняет их как есть- \spacefactor [ 〈number〉 parameter ] — 1000 норма, <1000 больше сжимается между словами, >1000 больше растягивается.
- \spaceskip [ 〈glue〉 parameter ] — применяет клей при SF < 2000
- \xspaceskip [ 〈glue〉 parameter ] — применяет клей для SF > 2000
- \sfcode 〈charcode〉 [ 〈number〉 table entry ] — устанавливает spacefactor для отдельного символа (для . он 3000)
Выравнивание строк
\centerline 〈argument〉\leftline 〈argument〉\rightline 〈argument〉\line{}— выровняет по левому и правому краю\llap{}— печатает влево от курсора\rlap{}— печатает вправо от курсора
\noindent
\llap{off left }
\line{\vrule $\Leftarrow$ left margin of examples\hfil right margin of examples $\Rightarrow$\vrule}
\rlap{ off right}
Параграф
\par— новый абзац\parskip=\parindent=\endgraf— синоним\par\parfillskip [ 〈glue〉 parameter ]— \parfillskip = 0pt plus 1fil по умолчанию, определяет последнюю строку в абзаце.\indent— Если TEX находится в вертикальном режиме, как это происходит после окончания абзаца, эта команда вставляет межабзацную связку \parskip, переводит TEX в горизонтальный режим, начинает абзац и делает отступ в этом абзаце на \parindent. Если TEX уже находится в горизонтальном режиме, эта команда просто создает пробел шириной \parindent. Два \indent подряд создают два отступа.\noindent— запрещает отступ в начале абзаца\textindent 〈argument〉— используется для печатания сносок и пунктов списков\everypar [ 〈token list〉 parameter ]— назначает команды для выполнения перед началом нового абзаца
\everypar = {$\Longrightarrow$\enspace}
Now pay attention!\par I said,
"Pay attention!".\par
I'll say it again! Pay attention!
на выходе получим:
⇒ Now pay attention!
⇒ I said, “Pay attention!”.
⇒ I’ll say it again! Pay attention!
\hsize— ширина печатной области
\leftline{\raggedright\vtop{\hsize = 2.5in Here is some text that we put into a paragraph that is an inch and a half wide.}\qquad \vtop{\hsize = 1.5in Here is some more text that we put into another paragraph that is an inch and a half wide.}}
шикарный пример как печатать в 2 колонки без мути в Latex
\narrower— сужает абзац слева и справа на\parindent\leftskip [ 〈glue〉 parameter ]— отступ слева\rightskip [ 〈glue〉 parameter ]— отступ справа\raggedright— убирает выравнивание справа\ttraggedright— тоже для мониширинного текста\hang— Эта команда устанавливает отступ во второй и последующих строках абзаца на \parindent, отступ абзаца\hangafter [ 〈number〉 parameter ]— определяет, какие строки имеют отступ: Если n < 0, первые −n строк абзаца будут иметь отступ. Если n ≥ 0, все строки абзаца, кроме первых n, будут иметь отступ.\hangindent [ 〈dimen〉 parameter ]— определяет величину отступа и то, находится ли он слева или справа: Если x ≥ 0, строки будут иметь отступ x слева. Если x < 0, строки будут иметь отступ -x справа.\prevgraf [ 〈number〉 parameter ]— количество строк в абзаце\vadjust { 〈vertical mode material〉 }— Эта команда вставляет указанный 〈материал вертикального режима〉 сразу после выходной строки, содержащей позицию, в которой встречается команда. Вы можете использовать его, например, чтобы вызвать выброс страницы или вставить дополнительное пространство после определенной строки.
Полезная штука для вставки указателей и линий:
Some of these words are \vadjust{\kern8pt\hrule} to be found above the line and others are to be found below it.
Выдаст линиюпод строкой:
Some of these words are to be found above the line and others are to be found
below it.
\parshape n i1l1 i2l2 . . . inln
Эта команда определяет форму первых n строк абзаца, следующего абзаца, если вы находитесь в вертикальном режиме, и текущего абзаца, если вы находитесь в горизонтальном режиме. «i» — это отступ слева и справа, а «l» — это длина строки, n — это количество строк, на которые будет выполнено воздействие.
Line breaks
\break— просто прервет строку\nobreak\allowbreak— для математики полезен\penalty 〈number〉— штраф 10000 или -10000 управляет разрывом строк\obeylines— концу строки присваивает значение конец абзаца (полезно для стихов и программного кода)\slash— поставит /, но$\backslash$работает в математической моде\pretolerance [ 〈number〉 parameter ]— (по умолчанию 100)\tolerance [ 〈number〉 parameter ]— (200) это как штрафы \penalty определяют плохость для абзацев, чтобы их разрывать на странице.\emergencystretch [ 〈dimen〉 parameter ]— Если TEX не может набрать абзац, не превысив \tolerance, он попытается еще раз, добавив \emergencystretch к растягиванию каждой строки.\looseness [ 〈number〉 parameter ]— Этот параметр дает вам возможность изменить общее количество строк в абзаце по сравнению с оптимальным.\linepenalty [ 〈number〉 parameter ]— Этот параметр определяет штраф, который TEX начисляет за каждый перенос строки при разбиении абзаца на строки.\adjdemerits [ 〈number〉 parameter ]— Этот параметр определяет дополнительные недостатки, которые TEX прикрепляет к точке останова между двумя соседними строками, которые «визуально несовместимы».\exhyphenpenalty [ 〈number〉 parameter ]— Увеличение этого параметра препятствует тому, чтобы TEX заканчивал строку явным дефисом. Обычный TEX устанавливает \exhyphenpenalty равным 50.\hyphenpenalty [ 〈number〉 parameter ]— Увеличение этого параметра препятствует использованию в TEX переноса слов. Обычный TEX устанавливает \hyphenpenalty равным 50.\doublehyphendemerits [ 〈number〉 parameter ]— Увеличение значения этого параметра препятствует TEXу расставлять переносы в двух строках подряд.\finalhyphendemerits [ 〈number〉 parameter ]— Увеличение значения этого параметра препятствует тому, чтобы TEX заканчивал предпоследнюю строку дефисом.
Переносы слов Hyphenation
\-— расставить в тех местах слов, где допускается перенос.\discretionary { 〈pre-break text〉 } { 〈post-break text〉 } { 〈no-break text〉 }— Эта команда определяет «дискреционный разрыв», а именно место, где TEX может разорвать строку. Он также сообщает TEXу, какой текст поместить по обе стороны от разрыва.
% Accounts for German usage: ‘flicken’, but ‘flik% ken’: German
"fli\discretionary{k-}{k}{ck}en"
\hyphenation { 〈word〉 . . . 〈word〉 }— TEX хранит словарь исключений из своих правил расстановки переносов. В каждой словарной статье указано, как следует писать через дефис то или иное слово.
\hyphenation{Gry-phon my-co-phagy}
\hyphenation{man-u-script man-u-scripts piz-za}
\uchyph [ 〈number〉 parameter ]— разрешает перенос в верхнем регистре\language [ 〈number〉 parameter ]— устанавливает язык для переносов в абзаце\setlanguage 〈number〉— установит текущий язык\lefthyphenmin [ 〈number〉 parameter ] \righthyphenmin [ 〈number〉 parameter ]— левое и правое количество слогов при переносе\hyphenchar 〈font〉 [ 〈number〉 parameter ]— установит символ переноса
\hyphenchar\tenrm = ‘% Set hyphenation for tenrm font to ‘-’.
\hyphenchar\tentt = -1 % Don’t hyphenate words in font tentt.% нет переноса
Секции и заголовки
- `\beginsection 〈argument〉 \par` --- заголовок секции
- `\item 〈argument〉 \itemitem 〈argument〉` --- отступ для списков
- `\proclaim 〈argument〉. 〈general text〉 \par` --- теоремы
\proclaim Theorem 1.
What I say is not to be believed.
\proclaim Corollary 1. Theorem 1 is false.\par
Команды для создания страниц
Межстрочный клей
\baselineskip [ 〈glue〉 parameter ]— расстояние от базовой линии одного блока до другой\lineskiplimit [ 〈dimen〉 parameter ]— минимальное значение межстрочного клея\lineskip [ 〈glue〉 parameter ]— расстояние между низом верхнего блока и верхом нижнего блока\prevdepth [ 〈dimen〉 parameter ]— глубина блока\normalbaselineskip [ 〈glue〉 parameter ]— хранит значение baselineskip\normallineskiplimit [ 〈dimen〉 parameter ]— хранит значение lineskiplimit\normallineskip [ 〈glue〉 parameter ]— хранит значение lineskip\normalbaselines— устанавливает значатения, хранящиеся в параметрах normal…\offinterlineskip— отключает вставку межстрочного клея\nointerlineskip— Эта команда сообщает TEXу не вставлять межстрочный клей перед следующей строкой. На последующие строки это не влияет.\openup 〈dimen〉— Эта команда увеличивает \baselineskip на 〈dimen〉.
Разрыв страниц
\break—\nobreak—\allowbreak—\penalty 〈number〉—\goodbreak— Эта команда завершает абзац, а также указывает TEXу, что это подходящее место для разрыва страницы.\smallbreak \medbreak \bigbreak—\eject \supereject— Эти команды вызывают разрыв страницы в текущей позиции и завершают текущий абзац. Если нет vfill будет пытаться сам растянуть страницу.\filbreak— Эта команда обеспечивает своего рода условный разрыв страницы. Он сообщает TEXу разбить страницу, но не в том случае, если текст до более позднего \filbreak также помещается на той же странице.\raggedbottom \normalbottom— сообщает TEXу, что нужно разрешить некоторую вариативность нижних полей на разных страницах.
Параметры разрыва страницы
\interlinepenalty [ 〈number〉 parameter ]— Этот параметр определяет штраф за разрыв страницы между строками абзаца.\clubpenalty [ 〈number〉 parameter ]— Этот параметр определяет штраф за разрыв страницы сразу после первой строки абзаца.\widowpenalty [ 〈number〉 parameter ]— Этот параметр определяет штраф за разрыв страницы непосредственно перед последней строкой абзаца.\displaywidowpenalty [ 〈number〉 parameter ]— Этот параметр определяет штраф за разрыв страницы непосредственно перед последней строкой частичного абзаца, который непосредственно предшествует математическому отображению.\predisplaypenalty [ 〈number〉 parameter ]— Этот параметр определяет штраф за разрыв страницы непосредственно перед математическим отображением. Обычный TEX устанавливает \predisplaypenalty равным 10000.\postdisplaypenalty [ 〈number〉 parameter ]— Этот параметр определяет штраф за разрыв страницы сразу после математического отображения.\brokenpenalty [ 〈number〉 parameter ]— Этот параметр определяет штраф за разрыв страницы сразу после строки, которая заканчивается произвольным элементом (обычно дефисом).\insertpenalties [ 〈number〉 parameter ]— Этот параметр содержит сумму определенных штрафов, которые накапливает TEX при размещении вставок на текущей странице.\floatingpenalty [ 〈number〉 parameter ]— Этот параметр определяет штраф, который TEX добавляет к \insertpenalties, когда построитель страниц добавляет вставку на текущую страницу и обнаруживает, что предыдущая вставка того же типа на этой странице была разделена, оставив ее часть для последующих страниц.\pagegoal [ 〈dimen〉 parameter ]— Этот параметр определяет желаемую высоту текущей страницы. TEX устанавливает \pagegoal в текущее значение \vsize, когда он впервые помещает блок или вставку на текущую страницу.\pagetotal [ 〈dimen〉 parameter ]— Этот параметр определяет накопленную естественную высоту текущей страницы. TEX обновляет \pagetotal по мере добавления элементов в основной вертикальный список.\pagedepth [ 〈dimen〉 parameter ]— Этот параметр определяет глубину текущей страницы.\pageshrink [ 〈dimen〉 parameter ]— Этот параметр определяет степень сжатия накопленного клея на текущей странице.\pagestretch [ 〈dimen〉 parameter ] \pagefilstretch [ 〈dimen〉 parameter ] \pagefillstretch [ 〈dimen〉 parameter ] \pagefilllstretch [ 〈dimen〉 parameter ]— Эти четыре параметра вместе определяют степень растяжения клея на текущей странице. n0 + n1fil + n2fill + n3filll
Макет страницы
\hsize [ 〈dimen〉 parameter ]— горизонтальный размер текста\vsize [ 〈dimen〉 parameter ]— вертикальный размер текста\hoffset [ 〈dimen〉 parameter ] \voffset [ 〈dimen〉 parameter ]— отступ слева и сверху\topskip [ 〈glue〉 parameter ]— TEX вставляет клей вверху каждой страницы, чтобы гарантировать, что базовая линия первого блока на странице всегда находится на одинаковом расстоянии d от верха страницы.\parskip [ 〈glue〉 parameter ]— Этот параметр определяет «пропуск абзаца», то есть вертикальную склейку, которую TEX вставляет в начало абзаца.\maxdepth [ 〈dimen〉 parameter ]— Этот параметр определяет максимальную глубину нижнего поля на странице.
Номер страницы
\pageno [ 〈number〉 parameter ]— Этот параметр содержит номер текущей страницы в виде целого числа. Номер страницы обычно является отрицательным для страниц титульной страницы, которые нумеруются маленькими римскими цифрами, а не арабскими цифрами.
\pageno = 30 % Number the next page as 30. Don’t look for this explanation on page \number\pageno.
\advancepageno— Эта команда добавляет 1 к номеру страницы n в \pageno, если n ≥ 0, и вычитает из него 1, если n < 0.\nopagenumbers— создает пустой нижний колонтитул\folio— Эта команда создает номер текущей страницы, значением которого является число n, содержащееся в \pageno. Если n ≥ 0, TEX выдает n как десятичное число, а если n < 0, TEX выдает −n в виде строчных римских цифр.
Header и Footer
\headline [ 〈token list〉 parameter ]— заголовок\footline [ 〈token list〉 parameter ]— подвал
Метки Marks
\mark { 〈text〉 }— Эта команда заставляет TEX добавлять метку, содержащую 〈текст метки〉, к любому списку, который он в данный момент создает.\firstmark \botmark \topmark— Эти команды расширяются до текста метки в элементе, созданном предыдущей командой \mark.\splitfirstmark \splitbotmark— Эти команды расширяются до текста метки, сгенерированного более ранней командой \mark, которая создала элемент в списке элементов vbox V .
Сноски footnotes
\footnote 〈argument1 〉 〈argument2 〉—
To quote the mathematician P\’olya is a ploy.\footnote *{This is an example of an anagram, but not a strict one.}
\vfootnote 〈argument1 〉 〈argument2 〉— \footnote, и \vfootnote вставляют знак ссылки перед самой сноской, но \vfootnote не вставляет знак ссылки в текст.
Вставки
\topinsert 〈vertical mode material〉 \endinsert— пытается разместить материал вверху текущей страницы.\midinsert 〈vertical mode material〉 \endinsert— пытается поместить материал в текущую позицию.\pageinsert 〈vertical mode material〉 \endinsert— помещает материал отдельно на следующую страницу.\insert 〈number〉 { 〈vertical mode material〉 }— Эта примитивная команда обеспечивает базовый механизм создания вставок, но она почти никогда не используется за пределами определения макроса. Необходимо три элемента для insert- \box n — это место, где TEX накапливает материал для вставок с кодом n. Когда TEX разбивает страницу, он помещает в \box n столько вставочного материала, сколько поместится на странице. Ваша процедура вывода должна затем переместить этот материал на реальную страницу. Вы можете использовать \ifvoid (стр. 238), чтобы проверить, есть ли какой-либо материал в \box n. Если не весь материал помещается, TEX сохраняет остатки для следующей страницы.
- \count n — коэффициент увеличения f. Когда TEX вычисляет вертикальное пространство, занимаемое на странице вставкой n материала, он умножает вертикальную протяженность этого материала на f/1000. Таким образом, вы обычно устанавливаете f равным 500 для вставки двух столбцов и 0 для примечания на полях.
- \dimen n определяет максимальное количество вставок n материала, которые TEX поместит на одну страницу.
- \skip n указывает дополнительное пространство, которое TEX выделяет на странице, если страница содержит какой-либо материал вставки n. Это место дополнительное пространство, занимаемое самой вставкой.
Изменение процедуры вывода
\output [ 〈token list〉 parameter ]— Этот параметр содержит текущую процедуру вывода, т. е. список токенов, который TEX расширяет, когда находит разрыв страницы.\plainoutput— Эта команда вызывает обычную процедуру вывода TEXа.\shipout 〈box〉— Эта команда инструктирует TEX отправить 〈box〉 в файл .dvi.\deadcycles [ 〈number〉 parameter ]— Этот параметр содержит количество раз, когда TEX инициировал процедуру вывода с момента последнего выполнения команды \shipout.\maxdeadcycles [ 〈number〉 parameter ]— Если значение \deadcycles превышает значение \maxdeadcycles, TEX предполагает, что процедура вывода зациклилась.\outputpenalty [ 〈number〉 parameter ]— TEX устанавливает этот параметр, когда разрывает страницу.\holdinginserts [ 〈number〉 parameter ]— Если этот параметр больше 0, когда TEX обрабатывает разрыв страницы, TEX воздержится от обработки вставок.
Разрыв вертикальных списков
\vsplit 〈number〉 to 〈dimen〉— Эта команда заставляет TEX разделить блок с номером 〈number〉, который мы назовем B2, на две части.\splitmaxdepth [ 〈dimen〉 parameter ]— Этот параметр определяет максимально допустимую глубину поля, полученного в результате \vsplit.\splittopskip [ 〈glue〉 parameter ]— Этот параметр определяет клей, который TEX вставляет в верхнюю часть блока, полученного в результате \vsplit.
Горизонтальная и вертикальная мода
\thinspace— Эта команда создает положительный керн, ширина которого составляет одну шестую em, т.е. она заставляет TEX смещать свою позицию вправо на эту величину. Полезно при использовании одиночных и двойных ковычек.\negthinspace— Эта команда создает отрицательный керн, ширина которого составляет одну шестую em, т. е. заставляет TEX смещать свою позицию влево на эту величину.\enspace— Эта команда создает керн, ширина которого равна 1em.\enskip \quad \qquad— Каждая из этих команд создает шарик горизонтального клея, который не может ни растягиваться, ни сжиматься. 1/2em, 1em, 2em.\smallskip \medskip \bigskip— вертикальный отступ.\smallskipamount [ 〈glue〉 parameter ]— Эти параметры определяют количество клея, производимого командами \smallskip, \medskip и \bigskip.\medskipamount [ 〈glue〉 parameter ]\bigskipamount [ 〈glue〉 parameter ]
Вертикальные и горизонтальные отступы (клей)
\hskip 〈dimen1 〉 plus 〈dimen2 〉 minus 〈dimen3 〉— горизонтальная\vskip 〈dimen1 〉 plus 〈dimen2 〉 minus 〈dimen3 〉— вертикальная
\hbox to 2in{one\hskip 0pt plus .5in two}
\hglue 〈glue〉— Команда \hglue создает горизонтальное склеивание, которое не исчезает при разрыве строки\vglue 〈glue〉— команда \vglue создает вертикальную склейку, которая не исчезает при разрыве страницы.\topglue 〈glue〉— Эта команда заставляет пространство от верха страницы до верха первого поля на странице быть склеенным.\kern 〈dimen〉— В горизонтальном режиме TEX перемещает свое положение вправо (при положительном керне) или влево (при отрицательном керне). В вертикальном режиме TEX перемещает свою позицию вниз по странице (при положительном керне) или вверх (при отрицательном керне).
\centerline{$\Downarrow$}\kern 3pt % a vertical kern
\centerline{$\Longrightarrow$\kern 6pt % a horizontal kern
{\bf Heed my warning!}\kern 6pt % another horizontal kern
$\Longleftarrow$}
\kern 3pt % another vertical kern
\centerline{$\Uparrow$}
\hfil \hfill— Эти команды создают бесконечно растягиваемый горизонтальный и вертикальный клей, который подавляет любое конечное растяжение, которое может присутствовать.\vfil \vfill\hss \vss— Эти команды создают горизонтальный и вертикальный клей, который одновременно бесконечно растягивается и бесконечно сжимается.\hfilneg \vfilneg— Эти команды отменяют эффект предыдущего \hfil или \vfil. В то время как \hfil и \vfil производят бесконечно растягиваемый позитивный клей, \hfilneg и \vfilneg производят бесконечно растягиваемый негативный клей.
Управление Box-ами
\hbox { 〈horizontal mode material〉 }
\hbox to 〈dimen〉 { 〈horizontal mode material〉 }
\hbox spread 〈dimen〉 { 〈horizontal mode material〉 }
Эта команда создает hbox (горизонтальный прямоугольник), содержащий 〈материал горизонтального режима〉.
\vtop 〈vertical mode material〉
\vtop to 〈dimen〉 { 〈vertical mode material〉 }
\vtop spread 〈dimen〉 { 〈vertical mode material〉 }
\vbox { 〈vertical mode material〉 }
\vbox to 〈dimen〉 { 〈vertical mode material〉 }
\vbox spread 〈dimen〉 { 〈vertical mode material〉 }
Эти команды создают vbox (вертикальный блок), содержащий 〈материал вертикального режима〉.
\boxmaxdepth [ 〈dimen〉 parameter ]— Этот параметр содержит размер D. TEX не будет создавать блок, глубина которого превышает D.\underbar 〈argument〉— Эта команда помещает 〈аргумент〉 в hbox и подчеркивает его, не обращая внимания на все, что выступает за базовую линию блока.\everyhbox [ 〈token list〉 parameter ]— Эти параметры содержат списки токенов, которые TEX расширяет в начале каждого создаваемого им hbox или vbox.\everyvbox [ 〈token list〉 parameter ]
Создание box-ов для многократного использования
\setbox 〈register〉 = 〈box〉— команда устанавливают содержимое регистра, номер которого равен 〈register〉.\box 〈register〉— команда выводит содержимое регистра
\setbox0 = \hbox{mushroom}
\setbox1 = \vbox{\copy0\box0\box0}
\box1 %выведет box1 и забудет его содержимое
\copy 〈register〉— копирует содержимое box n не стирая его содержимого\unhbox 〈register〉— Эти команды создают список, содержащийся в регистре ящика 〈register〉, и делают этот регистр ящика недействительным.\unvbox 〈register〉— эти команды освобождают память и очищают box с выбранным номером\unhcopy 〈register〉 \unvcopy 〈register〉— Эти команды создают список, содержащийся в блочном регистре 〈register〉, и оставляют содержимое регистра нетронутым.
Смещение Box-ов
\moveleft 〈dimen〉 〈box〉 \moveright 〈dimen〉 〈box〉— сдвинуть влево, сдвинуть вправо\lower 〈dimen〉 〈box〉 \raise 〈dimen〉 〈box〉— сдвинуть вниз, сдвинуть вниз.
Размеры Box-ов
\ht 〈register〉 [ 〈dimen〉 parameter ]— высота\dp 〈register〉 [ 〈dimen〉 parameter ]— глубина\wd 〈register〉 [ 〈dimen〉 parameter ]— ширина
Эти команды хранят размеры box-ов
\setbox0 = \vtop{\hbox{a}\hbox{beige}\hbox{bunny}}%
The box has width \the\wd0, height \the\ht0, and depth \the\dp0.
Struts и фантомы
\strut— Эта команда создает блок, ширина которого равна нулю, а высота (8,5 пт) и глубина (3,5 пт) соответствуют более или менее типичной строке текста в cmr10, простом шрифте TEX по умолчанию.\mathstrut— Эта команда создает фантомную формулу, ширина которой равна нулю, а высота и глубина такие же, как у левой круглой скобки.\phantom 〈argument〉— Эта команда создает пустое поле того же размера и размещения, что и 〈аргумент〉, если бы он был набран.\hphantom 〈argument〉—hphantom создает блок той же ширины, что и 〈аргумент〉, но с нулевой высотой и глубиной.\vphantom 〈argument〉— vphantom создает блок той же высоты и глубины, что и 〈аргумент〉, но нулевой ширины.\smash 〈argument〉— Эта команда вводит 〈аргумент〉, но заставляет высоту и глубину содержащего его поля равняться нулю.\null— Эта команда создает пустой hbox.\setbox0 = \null
Неправильные поля (ошибки формирования документа)
\overfullrule [ 〈dimen〉 parameter ]— Этот параметр определяет ширину правила, которое TEX добавляет к переполненному hbox. Plain TEX устанавливает значение 5pt.\hbadness [ 〈number〉 parameter ] \vbadness [ 〈number〉 parameter ]— Эти параметры определяют пороговые значения горизонтальной и вертикальной неисправности для сообщения о недостаточном или переполненном ящиках.\badness— Эта команда возвращает числовое значение дефектности блока (горизонтального или вертикального), созданного TEX в последний раз.\hfuzz [ 〈dimen〉 parameter ] \vfuzz [ 〈dimen〉 parameter ]— Эти параметры определяют величину, на которую ящик может превысить свой естественный размер, прежде чем TEX сочтет его переполненным.
\hfuzz = .5in \hbox to 2in{This box is longer than two inches.}
Получение последнего элемента из списка
- \lastkern
- \lastskip
- \lastpenalty
- \lastbox
Эти управляющие последовательности возвращают значение последнего элемента в текущем списке. Это не настоящие команды, поскольку они могут появляться только как часть аргумента.
Эти управляющие последовательности наиболее полезны после вызовов макросов, в которые могли быть вставлены объекты указанных типов.
- \unkern
- \unskip
- \unpenalty
Если последний элемент в текущем списке имеет тип керн, клей или пенальти соответственно, эти команды удаляют его из этого списка. Если элемент не того типа, эти команды не имеют никакого эффекта.
Rules and leaders
\hrule
\hrule height 〈dimen〉 width 〈dimen〉 depth 〈dimen〉
\vrule
\vrule width 〈dimen〉 height 〈dimen〉 depth 〈dimen〉
Команда \hrule создает горизонтальную линию; команда \vrule создает вертикальное линию.
По умолчанию \hrule будет расширено по горизонтали до границ самого внутреннего поля или выравнивания. Высота 0,4 пт; Глубина 0pt.
Leaders
\leaders 〈box or rule〉 〈skip command〉
\cleaders 〈box or rule〉 〈skip command〉
\xleaders 〈box or rule〉 〈skip command〉
заполняют горизонтальное или вертикальное пространство копиями узора
〈box or rule〉— указывает шаблон〈skip command— указывает команду для заполнения, т.е. пространство
\def\pattern{\hbox to 15pt{\hfil.\hfil}}
\line{Down the Rabbit-Hole {\leaders\pattern\hfil} 1}
\line{The Pool of Tears {\leaders\pattern\hfil} 9}
\line{A Caucus-Race and a Long Tale {\cleaders\pattern \hfil} 19}
\line{Pig and Pepper {\xleaders\pattern\hfil} 27}
\dotfill \hrulefill— Эти команды соответственно заполняют окружающее горизонтальное пространство рядом точек на базовой линии и горизонтальной линией на базовой линии.
\hbox to 3in{Start {\dotfill} Finish}
\hbox to 3in{Swedish {\hrulefill} Finnish}
\leftarrowfill \rightarrowfill— Эти команды заполняют окружающее горизонтальное пространство стрелками, указывающими влево или вправо.
\hbox to 3in{\vrule \rightarrowfill \ 3 in \leftarrowfill\vrule}
Выравнивание
+ 〈text〉 & 〈text〉 & · · · \cr
\+ 〈text〉 & 〈text〉 & · · · \cr\tabalign— Эти команды начинаются с одной строки с выравниванием по вкладкам.
\cleartabs % обнуляет установки предыдущих settabs
\+ {\bf if }$a[i] < a[i+1]$ &{\bf then}&\cr
\+&&$a[i] := a[i+1]$;\cr
\+&&{\it found }$:=$ {\bf true};\cr
\+&{\bf else}\cr
\+&&{\it found }$:=$ {\bf false};\cr
\+&{\bf end if};\cr
\settabs 〈number〉 \columns— задает одинаковый размер колонкам\settabs \+ 〈sample line〉 \cr— задает шаблон с образцом\cleartabs— очищает предыдущие settabs
Общие выравнивания
\halign { 〈preamble〉 \cr 〈row〉 \cr . . . 〈row〉 \cr }
\halign to 〈dimen〉{ 〈preamble〉 \cr 〈row〉 \cr . . . 〈row〉 \cr }
\halign spread 〈dimen〉{ 〈preamble〉 \cr 〈row〉 \cr . . . 〈row〉 \cr }
Эта команда создает горизонтальное выравнивание, состоящее из последовательности строк, где каждая строка, в свою очередь, содержит последовательность записей столбцов. TEX регулирует ширину записей столбца, чтобы разместить самую широкую запись в каждом столбце.
\valign { 〈preamble〉\cr 〈column〉\cr . . . 〈column〉\cr }
\valign to 〈dimen〉{ 〈preamble〉\cr 〈column〉\cr . . . 〈column〉\cr }
\valign spread 〈dimen〉{ 〈preamble〉\cr 〈column〉\cr . . . 〈column〉\cr }
делает вертикальную таблицу
\ialign— Эта команда ведет себя так же, как \halign, за исключением того, что она сначала устанавливает клей \tabskip равным нулю, а \everycr — пустым.\cr— Эта команда завершает преамбулу горизонтального или вертикального выравнивания.\endline— Эта команда является синонимом команды \cr.\crcr— Эта команда ведет себя так же, как \cr, за исключением того, что TEX игнорирует ее, если она идет сразу после \cr или \noalign.\omit— Эта команда сообщает TEX игнорировать шаблон при горизонтальном или вертикальном выравнивании\span— Значение этой команды зависит от того, появляется ли она в преамбуле или в записи выравнивания. Помещение \span перед токеном в преамбуле приводит к немедленному расширению этого токена в соответствии с обычными правилами расширения макросов TEXа. Размещение \span вместо «&» между двумя записями столбца или строки приводит к объединению этих столбцов или строк.\multispan 〈number〉— Эта команда сообщает TEX, что следующие столбцы 〈number〉 в строке с горизонтальным выравниванием или строки 〈number〉 в столбце с вертикальным выравниванием должны быть объединены в один столбец или строку.\noalign { 〈vertical mode material〉 } \noalign { 〈horizontal mode material〉 }— Чаще всего \noalign используется для добавления дополнительного пробела после строки или столбца.\tabskip [ 〈glue〉 parameter ]— Этот параметр определяет количество горизонтального или вертикального клея, который TEX накладывает между столбцами горизонтального выравнивания или между строками вертикального выравнивания.\hidewidth— Эта команда сообщает TEX игнорировать ширину следующей записи столбца при горизонтальном выравнивании.\everycr [ 〈token list〉 parameter ]— TEX расширяет 〈список токенов〉 всякий раз, когда он выполняет \cr — в конце каждой преамбулы. Т.е. выполняет список команд после \cr.
Математическая мода
Скобки
\lbrace { \{
} \rbrace } \}
[ \lbrack
] \rbrack
〈 \langle
〉 \rangle
Стрелки
← \leftarrow
← \gets
⇐ \Leftarrow
→ \rightarrow
→ \to
⇒ \Rightarrow
↔ \leftrightarrow
⇔ \Leftrightarrow
←− \longleftarrow
⇐= \Longleftarrow
−→ \longrightarrow
=⇒ \Longrightarrow
←→ \longleftrightarrow
⇐⇒ \Longleftrightarrow
⇐⇒ \iff
←↩ \hookleftarrow
↪→ \hookrightarrow
↽ \leftharpoondown
⇁ \rightharpoondown
↼ \leftharpoonup
⇀ \rightharpoonup
⇀↽ \rightleftharpoons
7→ \mapsto
7−→ \longmapsto
↓ \downarrow
⇓ \Downarrow
↑ \uparrow
⇑ \Uparrow
l \updownarrow
m \Updownarrow
↗ \nearrow
↘ \searrow
↖ \nwarrow
↙ \swarrow
Основные команды
Шрифты
\font
\font 〈control sequence〉 = 〈fontname〉
\font 〈control sequence〉 = 〈fontname〉 scaled 〈number〉
\font 〈control sequence〉 = 〈fontname〉 at 〈dimen〉
Это заставляет TEX загружать файл метрик шрифта (файл .tfm) для 〈fontname〉.
Если ни масштабированный 〈number〉, ни 〈dimen〉 отсутствуют, шрифт используется в его дизайнерском размере — размере, в котором он обычно выглядит лучше всего. В противном случае загружается увеличенная версия шрифта.
Scaled — 〈number〉, шрифт увеличивается в 〈number〉/1000.
Если присутствует 〈dimen〉, шрифт масштабируется до 〈dimen〉
\font\tentt = cmtt10
\font\bigttfont = cmtt10 scaled \magstep2
\font\eleventtfont = cmtt10 at 11pt
\fontdimen 〈number〉 〈font〉 [ 〈dimen〉 parameter ]— изменяет различные параметры шрифта
| номер | значение |
|---|---|
| 1 | slant per point |
| 2 | interword space |
| 3 | interword stretch |
| 4 | interword shrink |
| 5 | x-height (size of 1ex) |
| 6 | quad width (size of 1em) |
| 7 | extra space |
Here’s a line printed normally.\par
\dimen0=\fontdimen2\font %сохранить значение пробела в dimen0
\fontdimen2\font=3\fontdimen2\font % увеличить пробел в 3 раза
\noindent Here’s a really spaced-out line.
\fontdimen2\font=\dimen0 %восстановить первоначальные значения
\magnification = 〈number〉— масштабирование\mag [ 〈number〉 parameter ]— лучше использовать первое\magstep 〈number〉— Эта команда расширяется до коэффициента увеличения, необходимого для увеличения всего документа (кроме истинных размеров) на 1,2r, где r — значение 〈number〉. 〈число〉 должно быть от 0 до 5.\magstephalf— маштабирование в полразмера
Конвертирование информации в токене
\number 〈number〉— Эта команда создает представление числа в виде последовательности токенов символов.
\number 24 \quad \count13 = -10000 \number\count13
выдаст: 24 -10000
\romannumeral 〈number〉— Эта команда создает представление числа римскими цифрами в виде последовательности токенов символов.\time [ 〈number〉 parameter ]— TEX устанавливает этот параметр равным количеству минут, прошедших с полуночи (текущего дня).\day [ 〈number〉 parameter ]— TEX устанавливает этот параметр на текущий день месяца. Это число от 1 до 31.\month [ 〈number〉 parameter ]— TEX устанавливает для этого параметра текущий месяц. Это число от 1 до 12.\year [ 〈number〉 parameter ]— TEX устанавливает для этого параметра текущий год\fmtname \fmtversion— Эти команды создают имя и номер версии формата TEX, например, обычного TEX или LATEX, который вы используете.\jobname— Эта команда создает базовое имя файла, с которым был вызван TEX.
Значение переменных
\meaning 〈token〉— Эта команда определяет значение 〈токена〉.
[{\tt \meaning\eject}] [\meaning\tenrm] [\meaning Y]
вернет:
[macro:->\par \break ] [select font cmr10] [the letter Y]
\string 〈control sequence〉— Эта команда создает символы, составляющие имя control sequence\escapechar [ 〈number〉 parameter ]— Этот параметр определяет код ASCII символа, который TEX использует для представления escape-символа\fontname 〈font〉— Эта команда создает имя файла для 〈font〉. Имя файла — это 〈имя шрифта〉, которое использовалось для определения 〈font〉.
\font\myfive=cmr5
[\fontname\myfive]
вернет [cmr5]
Grouping
\begingroup \endgroup— Эти две команды начинают и завершают группу.\global— Эта команда делает следующее определение или назначение глобальным\globaldefs [ 〈number〉 parameter ]— тоже, что\global\def\aftergroup 〈token〉— Когда TEX встречает эту команду во время ввода, он сохраняет 〈токен〉. После окончания текущей группы он вставляет 〈token〉 обратно во входные данные и расширяет их.\afterassignment 〈token〉— Когда TEX встречает эту команду, он сохраняет 〈token〉 в специальном месте. После следующего выполнения присваивания он вставляет 〈token〉 во входные данные и расширяет их.
Macros
\def 〈control sequence〉 〈parameter text〉 { 〈replacement text〉 }— Эта команда определяет 〈последовательность управления〉 как макрос с указанным 〈текстом параметра〉 и 〈текстом замены〉.\edef 〈control sequence〉 〈parameter text〉 { 〈replacement text〉 }— Эта команда определяет макрос таким же общим способом, как и \def. Разница в том, что TEX немедленно расширяет 〈текст замены〉 \edef (но при этом ничего не выполняя).
Вы можете запретить расширение управляющей последовательности, которая в противном случае была бы расширена, используя \noexpand или можете отложить раскрытие управляющей последовательности, используя команду \expandafter.
Команды \write, \message, \errmessage, \wlog и \csname расширяют свои списки токенов, используя те же правила, которые \edef использует для расширения замещающего текста.
\gdef 〈control sequence〉 〈parameter text〉 { 〈replacement text〉 }— эквивалентно\global\def.\xdef 〈control sequence〉 〈parameter text〉 { 〈replacement text〉 }— эквивалентно\global\edef\long— Эта команда используется как префикс к определению макроса. Он сообщает TEX, что аргументы макроса могут включать токены \par
\long\def\aa#1{\par\hrule\smallskip#1\par\smallskip\hrule}
\aa{This is the first line.\par
This is the second line.} % without \long, TeX would complain
\outer— Эта команда используется как префикс к определению макроса. Он сообщает TEX, что макрос является внешним (стр. 83) и не может использоваться в определенных контекстах.
\outer\def\chapterhead#1{%
\eject\topglue 2in \centerline{\bf #1}\bigskip}
% Using \chapterhead in a forbidden context causes an
% error message.
\chardef 〈control sequence〉=〈charcode〉— Эта команда определяет 〈последовательность управления〉 как 〈символьный код〉. Хотя \chardef чаще всего используется для определения символов, его также можно использовать для присвоения имени числу в диапазоне 0–255, даже если вы не используете это число в качестве кода символа.
\chardef\percent = ‘\%
21\percent, {\it 19\percent}
% Get the percent character in roman and in italic
выдаст: 21%, 19%
\mathchardef 〈control sequence〉=〈mathcode〉— определит математический символ\let 〈control sequence〉 = 〈token〉— определит синоним команды\futurelet 〈control sequence〉 〈token1 〉 〈token2 〉—\csname 〈token list〉 \endcsname— Эта команда создает управляющую последовательность из 〈списка токенов〉. Он обеспечивает способ синтеза управляющих последовательностей, в том числе тех, которые вы обычно не можете написать. 〈список токенов〉 сам может включать в себя управляющие последовательности; он расширяется так же, как заменяющий текст определения \edef
\def\capTe{Te} This book purports to be about \csname\capTe X\endcsname.
\expandafter 〈token1 〉 〈token2 〉— Эта команда сообщает TEXу расширить 〈token1〉 в соответствии со своими правилами расширения макросов после расширения 〈token2〉 на один уровень.
\def\aa{xyz}
\tt % Use this font so ‘\’ prints that way.
[\string\aa] [\expandafter\string\aa] [\expandafter\string\csname TeX\endcsname]
%выводит: [\aa] [xyz] [\TeX]
\noexpand 〈token〉— Эта команда сообщает TEX о подавлении расширения 〈token〉, если 〈token〉 является управляющей последовательностью, которую можно расширить.\the 〈token〉— Эта команда обычно расширяется до списка токенов символов, представляющих 〈токен〉. Это могут быть регистры, переменные и т.д.\parindent \deadcycles \count0 \catcode \fontdimen3\sevenbf \hyphenchar \skewchar \skewchar\teni \lastpenalty, \lastskip, \lastkern \chardef \mathchardef
Кроме того, \the может расширяться до несимвольных токенов в следующих двух случаях:
- \the 〈font〉, который расширяется до последней определенной управляющей последовательности, которая выбирает тот же шрифт, что и управляющая последовательность 〈font〉
- \the 〈переменная токена〉, которая расширяется до копии значения переменной, например, \the \everypar
Сравнения Conditional
\if 〈token1 〉 〈token2 〉— Эта команда проверяет, имеют ли 〈token1 〉 и 〈token2 〉 одинаковый код символа, независимо от кодов их категорий.\ifcat 〈token1 〉 〈token2 〉— Эта команда проверяет, имеют ли 〈token1〉 и 〈token2〉 одинаковый код категории.\ifx 〈token1 〉 〈token2 〉— Эта команда проверяет, совпадают ли 〈token1〉 и 〈token2〉. В отличие от \if и \ifcat, \ifx не расширяет токены, следующие за \ifx, поэтому 〈token1 〉 и 〈token2 〉 — это два токена сразу после \ifx.\ifnum 〈number1 〉 〈relation〉 〈number2 〉— Эта команда проверяет, удовлетворяют ли 〈номер1〉 и 〈номер2〉 〈отношению〉, которое должно быть либо «<», «=» или «>».\ifodd 〈number〉— Эта команда проверяет, является ли 〈число〉 нечетным.\ifdim 〈dimen1 〉 〈relation〉 〈dimen2 〉— Эта команда проверяет, удовлетворяют ли 〈dimen1 〉 и 〈dimen2 〉 〈отношению〉, которое должно быть либо «<», «=» или «>».\ifhmode \ifvmode \ifmmode \ifinner— определяет в какой моде находится Tex\ifhbox 〈register〉 \ifvbox 〈register〉 \ifvoid 〈register〉— Эти команды проверяют содержимое ящика-регистра с номером 〈register〉.\ifeof 〈number〉— Эта команда проверяет входной поток на конец файла.\ifcase 〈number〉〈case0 text〉 \or 〈case1 text〉 \or . . . \or 〈casen text〉 \else 〈otherwise text〉 \fi— Эта команда представляет тест с пронумерованными несколькими случаями. Если 〈number〉 имеет значение k, TEX расширит 〈casek text〉, если он существует, и 〈иначе text〉, если его нет.\iftrue \iffalse— Эти команды эквивалентны тестам, которые всегда верны или всегда ложны.\else— Эта команда представляет «ложную» альтернативу условной проверки.\fi— Эта команда завершает текст условной проверки.\newif \if〈test name〉— Эта команда называет три управляющих последовательности именами \alphatrue, \alphafalse и \ifalpha, где alpha — это 〈имя теста〉
Циклы и повторы
\loop α \ifΩ β \repeat— Эти команды предоставляют конструкцию цикла для TEXа. Здесь α и β — произвольные последовательности команд, а \ifΩ — любой из условных тестов. \repeat заменяет \fi, соответствующий тесту, поэтому вам не нужно явно писать \fi для завершения теста.
\count255 = 6
\loop
\number\count255\
\ifnum\count255 > 0
\advance\count255 by -1
\repeat
Пустота
\relax— Эта команда сообщает TEXу ничего не делать.\empty— Эта команда вообще не требует токенов. Он отличается от \relax тем, что исчезает после раскрытия макроса.
Регистры
\count 〈register〉 = 〈number〉
\dimen 〈register〉 = 〈dimen〉
\skip 〈register〉 = 〈glue〉
\muskip 〈register〉 = 〈muglue〉
\toks 〈register〉 = 〈token variable〉
\toks 〈register〉 = { 〈token list〉 }
%Регистру \toks можно назначить либо переменную токена (регистр или параметр),
%либо список токенов. Когда вы назначаете список токенов регистру токенов,
%токены в списке токенов не расширяются.
\count 〈register〉
\dimen 〈register〉
\skip 〈register〉
\muskip 〈register〉
\toks 〈register>
Первые шесть команд, перечисленных здесь, присваивают что-то регистру. Остальные пять управляющих последовательностей не являются настоящими командами, поскольку могут появляться только как часть аргумента. Они возвращают содержимое указанного регистра. Хотя вы не можете использовать эти управляющие последовательности сами по себе в качестве текстовых команд, вы можете использовать \the для преобразования их в текст и набора их значений.
\newcount— Резервирование регистров\maxdimen— Эта последовательность управления дает 〈размер〉, который является наибольшим размером, приемлемым для TEX
Операции над регистрами: \advance, \multiply, \divide, \setbox, \box.
Объявление регистров
\newcount %каждый резервирует регистр указанного типа.
\newdimen
\newskip
\newmuskip
\newtoks
\newbox
\newread %зарезервируйте входной поток и выходной поток соответственно.
\newwrite
\newfam %резервирует семейство математических шрифтов.
\newinsert %резервирует тип вставки.
\newlanguage %резервирует набор шаблонов расстановки переносов.
\countdef 〈control sequence〉 = 〈register〉
\dimendef 〈control sequence〉 = 〈register〉
\skipdef 〈control sequence〉 = 〈register〉
\muskipdef 〈control sequence〉 = 〈register〉
\toksdef 〈control sequence〉 = 〈register〉
Эти команды определяют 〈последовательность управления〉 для ссылки на регистр указанной категории, номер которого равен 〈register〉.
Операции над регистрами
\advance 〈count register〉 by 〈number〉
\advance 〈dimen register〉 by 〈dimen〉
\advance 〈skip register〉 by 〈glue〉
\advance 〈muskip register〉 by 〈muglue〉
Эта команда добавляет совместимое количество в регистр.
\multiply 〈register〉 by 〈number〉
\divide 〈register〉 by 〈number〉
Эти команды умножают и делят значение в 〈register〉 на 〈number〉 (которое может быть отрицательным).
Завершение работы
\bye— заканчивается документ\end— Эта команда сообщает TEX создать последнюю страницу и завершить задание. Однако он не заполняет страницу, поэтому обычно лучше использовать \bye, а не \end.
Input и Output
Input
\input 〈filename〉— Эта команда сообщает TEX прочитать входные данные из файла 〈имя файла〉. Когда этот файл исчерпан, TEX возвращается к чтению из предыдущего источника ввода.\endinput— Эта команда сообщает TEXу прекратить чтение ввода из текущего файла, когда он в следующий раз достигнет конца строки.\inputlineno— Эта команда возвращает число (не строку), задающее номер текущей строки, определенный как номер, который будет отображаться в сообщении об ошибке, если ошибка произойдет в этот момент.\openin 〈number〉 = 〈filename〉— Эта команда сообщает TEXу открыть файл с именем 〈имя файла〉 и сделать его доступным для чтения через входной поток, обозначенный 〈number〉 . Number от 0 до 15. Чтение из файла выполняется командой\read. Номера потоков определяются с помощью команды\newread.\closein 〈number〉— Эта команда сообщает TEXу закрыть входной поток с номером 〈number〉, т. е. прекратить связь между входным потоком и его файлом.\read 〈number〉 to 〈control sequence〉— Эта команда сообщает TEX прочитать строку из файла, связанного с входным потоком, обозначенным 〈номером〉, и назначить токены в этой строке 〈управляющей последовательности〉.
Output
\openout 〈number〉 = 〈filename〉— Эта команда сообщает TEXу открыть файл с именем 〈имя файла〉 и сделать его доступным для записи через выходной поток, обозначенный 〈номер〉. 〈число〉 должно быть от 0 до 15.\closeout 〈number〉— Эта команда сообщает TEXу закрыть выходной поток с номером 〈number〉.\write 〈number〉 { 〈token list〉 }— Эта команда сообщает TEX записать 〈список токенов〉 в файл, связанный с выходным потоком, обозначенным 〈номер〉.\immediate— Эта команда должна предшествовать командам \openout, \closeout или \write. Он сообщает TEXу выполнить указанную операцию с файлом без задержки.\special { 〈token list〉 }— Эта команда сообщает TEX записать 〈список токенов〉 непосредственно в файл .dvi при следующей отправке страницы.\newlinechar [ 〈number〉 parameter ]— Этот параметр содержит символ, обозначающий новую строку на выходе. Когда TEX встречает этот символ при чтении аргумента команды \write, \message или \errmessage, он начинает новую строку.
Интерпретация входных символов
\catcode 〈charcode〉 [ 〈number〉 table entry ]— Эта запись таблицы содержит код категории символа, код ASCII которого равен 〈charcode〉.\active— Эта команда содержит код категории для активного символа, а именно цифру 13.\mathcode 〈charcode〉 [ 〈number〉 table entry ]— Эта запись таблицы содержит математический код символа, ASCII-код которого равен 〈charcode〉\delcode 〈charcode〉 [ 〈number〉 table entry ]— Эта запись таблицы определяет код-разделитель для входного символа, код ASCII которого равен 〈charcode〉.\endlinechar [ 〈number〉 parameter ]— Этот параметр содержит код символа, который TEX добавляет в конец каждой входной строки.\ignorespaces— Эта команда сообщает TEXу читать и расширять токены, пока не найдет тот, который не является токеном пространства, игнорируя любые токены пространства, которые он находит на своем пути.
Отладка кода Tex’s
\show 〈token〉 \showthe 〈argument〉 \showbox 〈number〉 \showlists— Эти команды записывают информацию в журнал вашего запуска TEXа\tracingonline [ 〈number〉 parameter ]— Если этот параметр больше нуля, TEX будет отображать результаты трассировки (включая \showbox и \showlists) на вашем терминале в дополнение к записи их в файл журнала.\message { 〈token list〉 } \errmessage { 〈token list〉 }— Эти команды отображают сообщение, заданное 〈списком токенов〉, на вашем терминале, а также записывают его в журнал. Все макросы в сообщении раскрываются, но команды не выполняются.\wlog { 〈token list〉 }— Эта команда записывает 〈список токенов〉 в файл журнала.\errhelp [ 〈token list〉 parameter ]— Этот параметр содержит список токенов, который TEX отображает, когда вы запрашиваете помощь в ответ на команду \errmessage.\newhelp 〈control sequence〉 { 〈help text〉 }— Эта команда назначает справочное сообщение, заданное 〈текстом помощи〉, 〈последовательности управления〉.
Инициализация TEX
\dump— Эта команда, которая не должна появляться внутри группы, сбрасывает содержимое памяти TEXа в файл формата (стр. 65). Используя virtex, специальную «чистую» форму TEXа, вы можете затем перезагрузить файл формата на высокой скорости и продолжить работу в том же состоянии, в котором находился TEX на момент создания дампа. \dump также завершает выполнение. Поскольку \dump можно использовать только в initex, а не в рабочих формах TEXа, он полезен только тем, кто устанавливает TEX.\everyjob [ 〈token list〉 parameter ]— Этот параметр содержит список токенов, который TEX расширяет в начале каждого задания. Поскольку назначение \everyjob не может повлиять на текущий запуск (к тому времени, когда вы выполните назначение, будет уже слишком поздно), оно полезно только для людей, которые подготавливают файлы форматирования.
7.6.2 - TEX for the Impatient
Некоторые команды
\null
Ставится после большой буквы,чтобы Tex мог понять, что точку нужно воспринимать не как после большой буквы.
Двойные кавычки
Поставить две одинарные, а чтобы разделить одинарную от двойной между ними поставить команду ’text’\thinspace"
Объявление \def
\def\xmpheader#1/#2{% Now here’s the title.
\leftline{\xmplbx Example #1:\quad\xmplbxti #2}%
\vglue .5\baselineskip % skip an extra half line
}
Какие особенности?
при объявлении между параметрами указывается разделитель,которым будут отделяться параметры, это может быть пробел или как у меня #1/#2. Сложные данные передаются просто в группе {}.
Но определению \def я еще посвящу отдельную главу.
Управляем отступами
- \parindent = 0pt — отступ первой строки
- \noindent — подавить отступ
- \parskip = 6pt — отступ между абзацев
- \par — новый абзац
- \smallskip — маленький разрыв абзацев
- \medskip
- \bigskip
- \narrower — отступ слева и справа на ширину \parindent
- \vskip 1pc — вертикальный отступ
- \leftskip .5in — отступ слева
- \rightskip .5in — отступ справа
- \baselineskip = 7pt — межстрочный интервал
- \raggedright — отключить выравнивание по правому краю
- \leftline{} — строку выравнивает по левому краю
- \rightline{}
- \centerline{}
Определение символов
\chardef \\ = `\\ — определили \\ как backslash
\char `\^ — выводит символ по его коду
Акценты и диакритические знаки
\`
\'
\"
\^
...
через backslash ставим знак и дальше нужную букву.
Дроби
Макрос дробилка. На вход две цифири через слеш.
\def\frac#1/#2{\leavevmode
\kern.1em \raise .5ex \hbox{\the\scriptfont0 #1}%
\kern-.1em $/$%
\kern-.15em \lower .25ex \hbox{\the\scriptfont0 #2}%
}%
`\kern` --- сдвигает символ вправо или влево
`\raise` --- сдвигает вверх
`\lower` --- сдвигает вниз
`\leavevmode` --- переключается из вертикальной моды
Определение измеряемых величин \newdimen
Нужно для правильной разметки пространства
\newdimen\descindent
\descindent = 8pc
llap начинает печатать влево от текущей позиции курсора
rlap — делает тоже, но вправо. Позицию курсора при этом не меняет.
\llap{\hbox to \descindent{\bf Queen of Hearts\hfil}}%
замечательный прием:
- создать hbox длиной \descindent и поместить текст, выровненный по левому краю с помощью \hfil
\hbox \vbox
У этих замечательных box-ов есть переменные:
- to — которая задает размер
- spread — которая задает отступ текста, это установка для \hfil и \vfil
\hbox spread 8pt{\hfil\vbox spread 8pt{\vfil
\leaders заполняет окна символами
Для различных строк с подчеркиванием или точками, а также любые пространства для заполнения однообразным элементом
\line{\hfil\hbox to 3in{\leaders\hbox{ * }\hfil}\hfil}
Заполнит 3in звездочками и выровняет их по центру
У него есть 2 брата: \cleaders и \xleaders — которые заполняют не выравнивая элементы заполнения относительно разных строк.
\proclaim теорема
Печатает первое предложение выделенным жирным, а остальной абзац курсивом.
\footline \headline
footer и header
Таблицы
{\xmpheader 8/{A ruled table}% see p. 21
\bigskip \offinterlineskip % So the vertical rules are connected.
% \tablerule constructs a thin rule across the table.
\def\tablerule{\noalign{\hrule}}
% \tableskip creates 9pt of space between entries.
\def\tableskip{\omit&height 9pt&&&\omit\cr}
% & separates templates for each column. TeX substitutes
% the text of the entries for #. We must have a strut
% present in every row of the table; otherwise, the boxes
% won’t butt together properly, and the rules won’t join.
\halign{\tabskip = .7em plus 1em % glue between columns
% Use \vtop for whole paragraphs in the first column.
% Typeset the lines ragged right, without hyphenation.
\vtop{\hsize=6pc\pretolerance = 10000\hbadness = 10000
\normalbaselines\noindent\it#\strut}%
&\vrule #&#\hfil &\vrule #% the rules and middle column
% Use \vtop for whole paragraphs in the last column.
&\vtop{\hsize=11pc \parindent=0pt \normalbaselineskip=12pt
\normalbaselines \rightskip=3pt plus2em #}\cr
- \offinterlineskip — не дает масштабироваться вертикальным отступам в таблице
- \def\tablerule{\noalign{\hrule}} — для правильного отображения горизонтальных линий
- \def\tableskip{\omit&height 9pt&&&\omit\cr} — расстояние между строками в таблице
- \halign — определяет параметры колонок таблицы
- \vtop — выравнивает вертикальный бокс по верху
- \pretolerance = 10000\hbadness = 10000 — не показывает ошибки
- \vrule — рисует вертикальные линии
- \omit — отменяет действие шаблона в ячейке или строке и заменяет его обычным #
- \vtop{\hsize=11pc \parindent=0pt \normalbaselineskip=12pt \normalbaselines \rightskip=3pt plus2em #}\cr — чтобы задать в ячейке многострочный текст, а ячейку размером 11pc
Формулы математика
Очень большой раздел и пока им не интересуюсь
- eqno — выведет номер формулы справа
- leqno — выведет номер формулы слева
Концепция TEX
Активный символ \active
Это символ, которому будет назначено действие в TEX
- Символ нужно определить в \catcode назначить ему категорию 13 (\active)
- Определить действия через \def \let \chardef
Если символ не будет \active до определения, назначить ему команду не удастся
Например: \catcode ‘~ = \active \def~{\penalty10000\ }
alignment — выравнивание
Выравнивание TAB
- \settabs
- \+
- &
- \cr
{\hsize = 1.7 in \settabs 2 \columns
\+cattle&herd\cr
\+fish&school\cr
\+lions&pride\cr}
Выравнивание \haling
выравнивание с учетом настроек преамбулы
\halign{\hfil#\hfil &\hfil#\hfil &\hfil#\hfil \cr
- \tabskip =2pc — клей между колонками
- \noalign — вертикально выровнять строки
- \strut — увеличивает отступ между строк
- \valign — вертикальное выравнивание (это таблица на боку)
{\hsize=0.6in \parindent=0pt
\valign{#\strut&#\strut&#\strut\cr
one&two&three\cr
four&five&six\cr
seven&eight&nine\cr
ten&eleven\cr}}
Анатомия TEX
Текс расширяет макросы слева направо, но команда \expandafter может изменить порядокраскрытия макросов
Блоки в TEX

- reference point
- height
- width
- depth
- baseline
Коды категорий символов
| Code | Назначение |
|---|---|
| 0 | \ |
| 1 | { |
| 2 | } |
| 3 | $ |
| 4 | & |
| 5 | ^^M= |
| 6 | # |
| 7 | ^ и ^^K |
| 8 | _ и ^^A |
| 9 | ^^@ (ignored) |
| 10 | пробел ^^I |
| 11 | a..z A..Z |
| 12 | другие символы |
| 13 | ~ и ^^L активный |
| 14 | % |
| 15 | ^^? ошибка |
Символы
Категория 11 и 12
команда (напечатать символ) \char `h тоже самое, что \char104 напечатает h
Классы символов
Используется в математической моде и влияет на выделение места для каждого символа
Команды TEX
Все, что должен выполнить TEX:
- активный символ
- последовательность управляющих символов
- сам символ
Сравнение
\ifα〈true text〉\else〈false text〉\fi или \ifα〈true text〉\fi
проверка выполняется до расширения макросов
Управляющая последовательность
Обычно начинаетяс с \ и имя последовательности, определенное в \def
Заканчивается, когда TEX видит небукву. Или когда заканчивается управляющий символ.
Управляющий символ
состоит из \ и символа
Разделители — delimeters
обычно скобки в математической моде
dimention
| код | значение |
|---|---|
| pt | point (72.27 points = 1 inch) |
| pc | pica (1 pica = 12 points) |
| bp | big point (72 big points = 1 inch) |
| in | inch |
| cm | centimeter (2.54 centimeters = 1 inch) |
| mm | millimeter (10 millimeters = 1 centimeter) |
| dd | didˆot point (1157 didˆot points = 1238 points) |
| cc | cicero (1 cicero = 12 didoˆt points) |
| sp | scaled point (65536 scaled points = 1 point) |
| em | ширина M |
| ex | высота x |
бесконечность: fil, fill, filll
Множитель перед размерами f/1000
\kern 8 true pt — сделает неизменным размер при масштабировании
Шрифты
\font\имя=шрифт в системе
\font\twelvebf=cmbx12
Глобальное определение \globaldefs
распространяется на весь документ
или сокращенный вариант: \gdef или \xdef вместо \global\def и \global\edef
Клей \hskip
есть вертикальный и горизонтальный
\hskip 6pt plus 2pt minus 3pt — клей может растягиваться и сжиматься
у клея есть свойства stretch — plus и shrink — minus
Межстрочный клей
определяет расстояние между строк и определяется параметрами:
\baselineskip, \lineskip, \lineskiplimit
item
текст с отступом
выравнивание
\leftskip, \rightskip, \raggedright — установит размеры горизонтального бокса
kern
смещает символы горизонтально
leaders
заполнит пространство символами (нужно для оглавления)
Метка MARK
\topmark, \firstmark, \botmark размещаются на странице и используются командой \mark
\def\section#1{\medskip{\bf#1}\smallskip\mark{#1}} % #1 is the name of the section
Определение section устанавливает метку с именем секции
Числа
- 52 — десятичное число
- ‘14 — восьмеричное число
- “FF — шестнадцатиричное число
- `с или `\с — ASCII последовательность, но лучше второй вариант, хотя они идентичны. Со вторым вариантом можно использовать `\\, `\%, `\^^M
Но нежелательно при использовании команды \edef и \write
78 +078 "4E '116 `N `\N — это один и тот же код
число печатается командой \number78 или \romannumeral78 — получим 78lxxviii
box255
в этот box помещается готовая страница
готовый box255 отправляется командой \shipout в файл .dvi
Разрыв страницы
В Tex разрывом страницы управляет штраф:
\penalty 10000 = \nobreak
\penalty -10000 = \break
Размер страницы
- \voffset — отступ сверху
- \hoffset — отступ слева
- hsize — ширина текста
- vsize — высота текста
Регистры
| тип | контент |
|---|---|
| box | a box |
| count | a number |
| dimen | a dimension |
| muskip | muglue |
| skip | glue |
| toks | a token list |
Все регистры имеют нумерацию от 0 до 255
Вызов регистра \box0 или \box100, \skip0 или \skip20
setbox3 = \hbox{text} — присвоит значение регистру box3
count255 = -1 — присвоит -1
для резервирования регистров используются команды:
- \newbox,
- \newcount,
- \newdimen,
- \newmuskip,
- \newskip,
- \newtoks
Просмотреть содержимое регистра можно с помощью команды \showthe\dimen0
\whatsit
действия для TeX когда, что-то пошло не так
- команды \openout, \closeout, \write — откладывает запись в выходной файл до следующей команды
- \special — вставить текс в выходной файл
- при смене языка поместит информацию
7.6.3 - TEX
Введение
% A small font and close interline spacing make this work
\smallskip\font\sixrm=cmr6 \sixrm \baselineskip=7pt
\dimen0=\fontdimen3\font \dimen2=\fontdimen4\font
\fontdimen3\font=1.8pt \fontdimen4\font=.9pt
\noindent \hfuzz=.1pt
\parshape 30 0pt 120pt 1pt 118pt 2pt 116pt 4pt 112pt 6pt
108pt 9pt 102pt 12pt 96pt 15pt 90pt 19pt 84pt 23pt 77pt
27pt 68pt 30.5pt 60pt 35pt 52pt 39pt 45pt 43pt 36pt 48pt
27pt 51.5pt 21pt 53pt 16.75pt 53pt 16.75pt 53pt 16.75pt 53pt
16.75pt 53pt 16.75pt 53pt 16.75pt 53pt 16.75pt 53pt 16.75pt
53pt 14.6pt 48pt 24pt 45pt 30.67pt 36.5pt 51pt 23pt 76.3pt
The wines of France and California may be the best known,
but they are not the only fine wines. Spanish wines are
often underestimated, and quite old ones may be available at
reasonable prices. For Spanish wines the vintage is not so
critical, but the climate of the Bordeaux region varies
greatly from year to year. Some vintages are not as good as
others, so these years ought to be s\kern -.1pt p\kern -.1pt
e\kern -.1pt c\hfil ially n\kern .1pt o\kern .1pt
t\kern .1pt e\kern .1pt d\hfil: 1962, 1964, 1966. 1958,
1959, 1960, 1961, 1964, 1966 are also good California
vintages. Good luck finding them!
\fontdimen3\font=\dimen0 \fontdimen4\font=\dimen2

Первый шаг Создать файл.
Я это делаю в своем любимом Emacs
Here is my first \TeX\ sentence.
\bye
и сохранил с именем test.tex
Второй шаг выполнить tex
tex test.tex
Получилось два файла на выходе: test.dvi и test.log
В test.log
This is TeX, Version 3.141592653 (TeX Live 2024) (preloaded format=tex 2024.10.2) 5 JAN 2025 20:03
**test.tex
(./test.tex [1] )
Output written on test.dvi (1 page, 292 bytes).
А файл dvi вполне себе просматривается emacs, в том виде, как и должно быть.
Специальные символы в Tex
| символ | назначение | как вывести в tex |
|---|---|---|
| \ | спец символ и инструкции | $\backslash$ |
| { | открывает группу | ${$ |
| } | закрывает группу | $}$ |
| % | комментарии | % |
| & | разграничение колонок в таблице | & |
| ~ | неразрываемый пробел | ~{} |
| $ | начало и окончание математической моды | $ |
| ^ | надстрочник | ^{} |
| _ | подстрочник | _{} |
| # | определение заменяемого символа | # |
Набор текста с акцентом
Акцент — это надстрочники и подстрочники над и под буквами
Акцент за которым следует буква
| наименование | Tex input | Tex output | Compose |
|---|---|---|---|
| grave | \`o | ò | cmp+` o |
| acute | \’o | ó | cmp+’ o |
| circumflex | \^o | ô | cmp+^ o |
| umlaut/dieresis/tr ́emat | \“o | ö | cmp+” o |
| tilde | \~o | õ | cmp+~ o |
| macron | \=o | ő | cmp+= o |
| dot | \.o | ȯ | cmp+. o |
Продолжение для символов требующих пробела
| наименование | Tex input | Tex output | Compose |
|---|---|---|---|
| cedilla | \c o | ǫ | cmp+, o |
| underdot | \d o | ọ | cmp+! o |
| underbar | \b o | o᤻ | o C-x 8 RET 193b |
| h ́acˇek | \v o | ǒ | cmp+v o |
| breve | \u o | ŏ | cmp+u o |
| tie | \t oo | o͡o | o C-x 8 RET 0361 o |
| Hungarian umlaut | \H o | ő | cmp+= o |
| ơ | cmp++ o | ||
| ° | cmp+o o | ||
| § | cmp+s o | ||
| ø | cmp+? o |
По этой ссылке весь unicode а в Emacs C-x 8 RET в помощь. ⤖ https://www.compart.com/en/unicode/
Но и это еще не всё!
Это нужно при оформлении HTML документации просто пишем имя через &Rarrtl и получаем результат.
Можно создать собственную комбинацию клавиш
Создайте пустой ~/.XCompose и включите в него содержимое стандартного файла, используя директиву include “%L”, например:
# ~/.XCompose
include "%L"
<Multi_key> <g> <a> : "α"
<Multi_key> <g> <b> : "β"
<Multi_key> <g> <g> : "γ"
Определение шрифта
В Tex по умолчанию доступны 16 шрифтов
| Наименование | команда |
|---|---|
| Roman | \rm |
| Boldface | \bf |
| Italic | \it |
| Slanted | \sl |
| Typewriter | \tt |
| Math symbol5 | \cal |
Масштабирование шрифта
используем команду \magstep 0...5 или \magstephalf
\font\bigrm = cmr10 scaled \magstep 5 %объявим свой шрифт crm10 и смасштабируем 5 magstep
\font\bigbigrm = cmr14 scaled \magstep 3
Имена стандартных шрифтов TEX
| CMBSY10 | CMBXSL10 | CMBXTI10 | CMBX10 | CMBX12 | CMBX5 |
|---|---|---|---|---|---|
| CMBX6 | CMBX7 | CMBX8 | CMBX9 | CMB10 | CMCSC10 |
| CMDUNH10 | CMEX10 | CMFF10 | CMFIB8 | CMFI10 | CMITT10 |
| CMMIB10 | CMMI10 | CMMI12 | CMMI5 | CMMI6 | CMMI7 |
| CMMI8 | CMMI9 | CMR10 | CMR12 | CMR17 | CMR5 |
| CMR6 | CMR7 | CMR8 | CMR9 | CMSLTT10 | CMSL10 |
| CMSL12 | CMSL8 | CMSL9 | CMSSBX10 | CMSSDC10 | CMSSI10 |
| CMSSI12 | CMSSI17 | CMSSI8 | CMSSI9 | CMSSQI8 | CMSSQ8 |
| CMSS10 | CMSS12 | CMSS17 | CMSS8 | CMSS9 | CMSY10 |
| CMSY5 | CMSY6 | CMSY7 | CMSY8 | CMSY9 | CMTCSC10 |
| CMTEX10 | CMTEX8 | CMTEX9 | CMTI10 | CMTI12 | CMTI7 |
| CMTI8 | CMTI9 | CMTT10 | CMTT12 | CMTT8 | CMTT9 |
| CMU10 | CMVTT10 |
- CM — Computer Modern
- B — Bold
- R — roman
- I — italic
- CSC — small caps
- SL — наклонный
- SS — sans serif
- SY — symbols
- TT — моноширинный
Форма выводимого текста
Tex понимает различные единицы измерения:
- in
- cm
- pt
- pc
и другие
- ex — высота маленькой x
- em — ширина большой M
Форма страницы
Три части:
- header
- body
- footer
| наименование | команда | значение |
|---|---|---|
| ширина | \hsize | 6.5in |
| высота | \vsize | 8.9in |
| горизонтальный отступ | \hoffset | 0 |
| вертикальный отступ | \voffset | 0 |
\vfill \eject — оборвет страницу и начнет новую
\hsize = 4in — определяет горизонтальный размер текста в текущем абзаце
0.75\hsize установит размер \hsize 0.75 от последнего значения
\vsize — задает вертикальный размер страницы
\hoffset \voffset — задают смещение текста относительно левого верхнего угла страницы. По умолчанию они равны 1in.
Для \hoffset и \voffset нет пределов страницы. Спокойно выведет текст за его пределами
\magnification = \magstep 3
Ставится в самом начале документа до начала первого символа и увеличивает весь документ, вместе с \hsize и \vsize
чтобы сохранить неизменными \hsize и \vsize используем true
\hsize = 5 true in
Форма параграфа
На размер абзаца влияет \hsize
Tex всегда читает весь абзац целиком и применяет последние настройки.
| функция | команда | значение |
|---|---|---|
| ширина | \hsize | 6.5in |
| отступ первой линии | \parindent | 20pt |
| расстояние между линиями | \baselineskip | 12pt |
| расстояние между абзацами | \parskip | 0pt |
команда \noindent убирает первый отступ линии, тоже,что и \parindent= 0pt
\rightskip \leftskip
это команды margin отступов слева и справа от обзаца
\narrower — изменяет оба значения сразу значением равным \parindent
\hangindent=2.5 in \hangafter=2
первую строку заполняет полностью на всю ширину, а следующую с отступом. Если положительное, то слева, если отрицательное, то справа.
\hangafter указывает после какой строки начинать отступ.
По умолчанию равно 1. Если поставлю 0, то отступ начнется с первой строки. Если отрицательное, то первые строки будут с отступом, а следующие на полную ширину.
еще есть команда \hang — которая сделает отступ абзаца на длину \parindent
\parshape
Создает абзацы любой формы
\item
Начинает абзац с отступом \parindent и вначале указывает значение, которое в {}
Команда \itemitem сделает двойной отступ
\parskip = 0pt \parindent = 30 pt \noindent
Answer all the following questions:
\item{(1)} What is question 1?
\item{(2)} What is question 2?
\item{(3)} What is question 3?
\itemitem{(3a)} What is question 3a?
\itemitem{(3b)} What is question 3b?
\parskip
расстояние между параграфами
и его друг \vskip 1 in — задают интервал между абзацами (у него нет знака равно)
\vglue 1 in — вставляет 1 in куда угодно, даже в начале страницы.
\topinsert \vskip -2 in \centerline{Figure 1} \endinsert
Эта команда поставит на текущей странице все, что находится между командами \topinsert и \endinsert
Я умышленно поставил \vskip -2 in и весь текстстраницы улетел вверх.
\smallskip, \medskip, \bigskip
Для смещений между абзацами. Действует только на текущий абзац.
Форма строки
\hfill \break — разорвет строку
\hfill — заполнит пространство
\line{} — выведет строку
\liftline{} \rightline{} \centerline{} выравнивает строку
\hfil — заполняет пространство для выравнивания
\raggedrigth — обрыв правого выравнивания
\hskip 1 in — горизонтальный отступ
Сноски
\footnote{}{}
в первой части {} могут быть знаки \dag, \ddag, \S, \P или номер ссылки в формате Tex {${}^{21}$} но сейчас работает {$^{21}$}
в Latex немного измененный формат \footnote{}
header и footer
определяется командами
\headline{} — header
\footline{} — footer
аналогично как при заполнении \line{}
\headline={\hfil \tenrm Page \the\pageno}
\tenrm — это шрифт roman 10pt
\the\pageno — номер страницы
\folio — тоже номер страницы, но выводит римские буквы когда \pageno отрицательный
\pageno=-1 может быть любого значения
Четные и нечетные заголовки
\headline={\ifodd \pageno {...}\else {...}\fi}
Переполнение или недобор в боксах
При переполнении или недоборе в строках появляется slug — слизень █ который показывает проблему в этой строке.
vbox hbox
Так Tex делит на блоки всю страницу и заполняет ее
vbox — вертикальные блоки абзацев
hbox — горизонтальные блоки строк
\hbadness
Это параметр плохости строки — по умолчанию 1000
Накапливается от количества пробелов, вставленных в строку для ее выравнивания.
Увеличения параметра до 10000 подавляет все сообщения о плохости блока.
\tolerance
Это параметр устанавливает на сколько строка может превышать допустимый размер
По умолчанию = 200. 10000 также стирает все предупреждения.
\hfuzz
Параметр, который определяет, на сколько может выступать переполнение строки \hfuzz = 0.1 pt
\overfullrule
это толщина слизняка slug, появляющегося на полях.
Если установить его 0pt то маркеры будут незаметны
\hyphenation{data-base}
установка переносов для лучшего форматирования боксов
\vbadness
параметры для вертикального наполнения текста на странице
Группы
При наборе текст можно упаковать в группы {}
При выходе из группы, все настройки возвращаются к тем, которые были до входа в группу.
{ \hsize = 4 in \parindent = 0 pt \leftskip = 1 in will produce a paragraph that is four ... (this is an easy mistake to make). \par }
Математичесский режим
Третий режим Tex математический. Задается $…$ в строке и $$…$$ для многострочного блока.
Теоремы — это тоже почти математика.
\proclaim — макрос,который выделит первое предложение до точки. А оставшуюся часть абзаца выдаст как описание теоремы.
\proclaim Theorem 1 (H.~G.~Wells). In the country of the blind, the one-eyed man is king.
Матрицы
Это мне всегда больше нравилось.
$$\pmatrix{
a & b & c & d \cr
b & a & c+d & c-d \cr
0 & 0 & a+b & a-b \cr
0 & 0 & ab & cd \cr
}.$$
создаст матрицу с круглыми скобками
\hfill — выравнивают значения в матрице
\matrix
удаляет разделители круглые скобки и их можно задать явно с помощью команд: \left и \right
$$ \left |
\matrix{
a & b & c & d \cr
b & a & c+d & c-d \cr
0 & 0 & a+b & a-b \cr
0 & 0 & ab & cd \cr
}
\right | $$
типы скобок: (){}[]||
еще можно значения замещать многоточием: \cdots, \vdots, \ddots
Выравнивание по знаку =
$$\eqalign{
a+b &= c+d \cr
x &= w + y + z \cr
m + n + o + p &= q \cr
}$$
Можно нумеровать уравнения тоже через знак &
$$\eqalignno{
a+b &= c+d & (1) \cr
x &= w + y + z \cr
m + n + o + p &= q & * \cr
}$$
Таблицы и tabbing
\settabs — команда создать tabbing
\settabs 4 \columns %установить 4 равных столбца
\+ British Columbia & Alberta & Saskatchewan & Manitoba \cr
\+ Ontario & Quebec & New Brunswick & Nova Scotia \cr
\+ & Prince Edward Island & Newfoundland \cr
+ — начало строки
\cr — завершение строки
\hfil, \hfill выравнивают текст в ячейках
\settabs \+ \hskip 1 in & \hskip 2 in & \hskip 1.5 in & \cr — это более жизненный пример таблицы с установленными значениями ширины столбцов
или так: \settabs \+ ---------- & ------------------ & ----------------------- & \cr
черточки не выводятся, так же как и любой текст
\hrule — начертит линию под строкой
+\strut — сделает отступ вокруг строки
$$\vbox{
\settabs \+ ----------------&-----&----\cr
\+Plums&\hfill \$1&.22\hfill \cr
\+Coffee&\hfill 1&.78\hfill \cr
\+Granola&\hfill 1&.98\hfill \cr
\+Mushrooms&\hfill &.63\hfill \cr
\+Kiwi fruit&\hfill& .39\hfill \cr
\+Orange juice&\hfill 1&.09\hfill \cr
\+Tuna&\hfill 1&.29\hfill \cr
\+Zucchini&\hfill 0&.64\hfill \cr
\+Grapes&\hfill 1&.69\hfill \cr
\+Smoked beef&\hfill &.75\hfill \cr
\+Broccoli&\hfill\underbar{\ \ 1}&\underbar{.09}\hfill \cr
\+Total&\hfill \$12&.55\hfill \cr
}$$
Горизонтальное выравнивание и шаблон \halign
\halign{шаблон} \cr
\halign{\hskip 2 in $#$& \hfil \quad # \hfil & \qquad $#$ & \hfil \quad # \hfil \cr
вместо # будет подставлено значение из строки
\halign{\hskip 2 in $#$& \hfil \quad # \hfil & \qquad $#$ & \hfil \quad # \hfil \cr \alpha & alpha & \beta & beta \cr
\gamma & gamma & \delta & delta \cr
\epsilon & epsilon & \zeta & zeta \cr
}
\hrule — горизонтальная линия
\vrule — вертикальная линия
\offinterlineskip — позволяет зафиксировать раздвижение строк в таблице
\moveright 2 in
\vbox{\offinterlineskip
\halign{\strut \vrule \quad $#$\quad &\vrule \hfil \quad #\quad \hfil &\vrule \quad $#$\quad &\vrule \hfil \quad #\quad \hfil \vrule \cr
\noalign{\hrule}
\alpha & alpha & \beta & beta \cr
\noalign{\hrule} \gamma & gamma & \delta & delta \cr
\noalign{\hrule} \epsilon & epsilon & \zeta & zeta \cr
\noalign{\hrule}
}}
финальный вариант. \moveright сдвинет box на два In вправо
но для этого также исправно работают \centrline, а также \rightline и \leftline
Создание своих макросов
\def\name{}
name — только буквы или одна не буква
Задать переменные #1
\def\name#1#2{#1...#2}
Задать синоним команде \let
\let \newname = \oldname
работать будут оба имени
Протокол ошибок Tex
обязательно в конце ввода поставить \bye
! Undefined control sequence. %название ошибки
l.1 \line{ The left side \hfli %успешно прочитанная строка
the right side} % продолжение строки после ошибки
? %что делать?
варианты ответа:
| Ответ | буква | результат |
|---|---|---|
| help | h | причина указана на терминале |
| insert | i | показать следующую строку |
| exit | x | завершить tex |
| scroll | s | прокрутить ошибки |
| run | r | продолжить работу |
| quiet | q | подавляет вывод в терминал |
| carry on | продолжить лучше как можно |
Большие файлы
\input filename
добавит маленькие файлы в большой
Линии rule
\hrule \vrule — имеют параметры width height depth
\vrule height 0 pt depth 0.4 pt width 3 in
Boxes
\vbox и \hbox — основные кирпичи в tex.
Вкладывая их друг в друга можно получить любой результат.
Задать размер \hbox to 5cm{}
у \vbox есть брат \vtop — будет выравнивать по верхнему краю boxes
\vbox{ \hrule
\hbox{\vrule{} The text to be boxed \vrule}
\hrule }
А это будет текст в рамочке, а с ключевым слово \strut — оно будет с отступами
Перемещение box по странице
\moveright \moveleft — переместит вертикальный бокс
\raise \lower — переместит горизонтальный бокс
Линии в боксе
\hbox to 5 in{Getting Started\hrulefill 1} и еще есть \dotfill — полезно для оглавления
7.6.4 -
7.7 - Графический пакет TIKZ для Latex
Дружелюбный функционал для полной графики в Latex. Картинки, иконки, графики и пр. Очень мощный пакет в котором можно нарисовать все.
Установка пакета
\usepackage{tikz}
Использование пакета
Окружение {tikzpicture} или команды \tikzpicture и \endtikzpicture
Использование дополнительных библиотек
\documentclass{article} % say
\usepackage{tikz}
\usetikzlibrary{arrows.meta,decorations.pathmorphing,backgrounds,positioning,fit,petri}
\begin{document}
\begin{tikzpicture}
\draw (0,0) -- (1,1);
\end{tikzpicture}
\end{document}
7.7.1 - Дисплей для руководства пользователя
Примеры использования поисковых запросов POSIX
Постановка задачи
Для описания инструкции по эксплуатации прибора необходимо описывать интерфейс внутренней программы с меню и другими изображениями на 7-ми строчном дисплее.
Дисплей имеет 22 знака в ширину и 7 строк.

Необходимо создать однострочную команду в Latex для удобного заполнения параметров дисплея и вывода графического изображения в любое место на странице документации.
Команда должна обеспечивать сохранение размеров и цветовой гаммы дисплея на всех страницах документации однообразными.
- Дисплей должен отражать текстовые строки заглавными и строчными буквами латинского алфавита.
- На дисплее должны отображаться арабские цифры
- Графические элементы применяемые на дисплее:
- аккумулятор
- антенна
- уровень сигнала
- замок
- линия под статусной строкой
- линия середины экрана
- Типы строк дисплея:
- строка с текстом выровненным по левому краю до 22 символов
- строка подсвеченная прямоугольником с инвертированным цветом символов
- строка с текстом выровненным по середине экрана
- строка с текстом в две колонки
- строка без текста
- Типы строк статусной строки
- режим 1 с аккумулятором и антенной
- режим 2 с аккумулятором
- режим 3 текст
- Отдельный режим отображения средней линии на дисплее
- Режим вывода картинки в правой части дисплея
- Обозначение подсвеченных информационных кнопок в нижней части дисплея
- Информационный режим дисплея
Решение задачи
- Использование издательской системы Latex
- Загрузка специального графического пакета TIKZ
- Настройка графических примитивов с помощью библиотеки TIKZ для использования в строках
- Программирование Tex для создания простых команд для указания в строках дисплея выводимой информации
- Создание библиотеки с возможностью многократного использования дисплея в различных документах
Описание решения
\definecolor{disp}{HTML}{000041} % цвет дисплея
\definecolor{textdisp}{HTML}{f0ffff} %цвет текста дисплея
\tikzset{%настройки стиля шрифта для вывода символов на терминал дисплея
terminal/.style = {text=textdisp,inner sep=0pt, anchor=west,font=\fontfamily{cmtt}\fontsize{10}{10}\selectfont}}
Создание графических элементов
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Аккумулятор
%%%%%%%%%%%%%
\tikzset{
accum/.pic={[font=\ttfamily]
\path (.5,.35) coordinate(acbl) ++(1,0) coordinate(acbr)
++(0,.6) coordinate(actr) ++(-1,0) coordinate(actl);
\draw[pic actions,thick] (acbl) -- (acbr) -- ($(acbr)!.2!(actr)$)-- ++(1pt,0) |- ($(acbr)!.8!(actr)$) -- (actr) -- (actl) -- cycle;
\fill[pic actions] (acbl) rectangle ($(actl)!#1!(actr)$);
}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Антенна
%%%%%%%%%%%%%
\tikzset{
antena/.pic={
\path
(0,.35) coordinate(anbot) ++(0,.6) coordinate(antop)
+(-.3,0) coordinate(antl) +(.3,0) coordinate(antr);
\draw[pic actions,thick] (anbot) -- (antop)
($(anbot)!.5!(antop)$)--(antl)
($(anbot)!.5!(antop)$)--(antr);
\path[pic actions] (anbot) ++(.4,.3) node[terminal]{100\%};
}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Уровень сигнала
%%%%%%%%%%%%%
\tikzset{
lsignal/.pic={
\coordinate (a) at (.35,.35);
\draw[pic actions,thick] (a) foreach \x in {1,...,#1} {+(.\x,0) -- +(.\x,.\x)};
}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%замок LOCK
%%%%%%%%%%%
\tikzset{
lockc/.pic={
\path (0,.15) coordinate (bl) +(.4,0) coordinate (br) +(.4,.3) coordinate (tr) +(0,.3) coordinate (tl);
\draw[pic actions,thick,fill] (bl) rectangle (tr);
\draw[thick,out=90,in=90,distance=.3em] (tl) to (tr);
}
}
Настройка типов строк
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%активная строка
%%%%%%%%%%%%%
\tikzset{
araw/.pic={%отображает строку подсвеченной как активную без текста
\path
(.4,.2) coordinate(arbl) ++(11.6,0) coordinate(arbr)
++(0,.9) coordinate(artr) ++(-11.6,0) coordinate(artl);
\fill[white!95,opacity=.7] (arbl) rectangle (artr);
},
arawp/.pic={%выводит текст без подсветки
\path
(0.4,.2) coordinate(arbl) ++(11.6,0) coordinate(arbr)
++(0,.9) coordinate(artr) ++(-11.6,0) coordinate(artl);
\node[terminal,text width=5.6em] at ($(arbl)!.5!(artl)$) {#1};%обычная строка
},
arawa/.pic={%выводит текст в активной строке
\path
(0.4,.2) coordinate(arbl) ++(11.6,0) coordinate(arbr)
++(0,.9) coordinate(artr) ++(-11.6,0) coordinate(artl);
\node[terminal,text width=5.6em,text=disp] at ($(arbl)!.5!(artl)$) {#1} [fill=white!95,opacity=.7] (arbl) rectangle (artr);%обычная строка
},
lbut/.pic={%выводит текст в левой функциональной кнопке в нижнем ряду
\path
(.4,.2) coordinate(arbl) ++(5.7,0) coordinate(arbr)
++(0,.9) coordinate(artr) ++(-5.7,0) coordinate(artl);
\node[terminal,text=disp,anchor=center] at ($(arbl)!.5!(artr)$) {#1} [fill=white!95,opacity=.7] (arbl) rectangle (artr) ;
},
rbut/.pic={%выводит текст в правой функциональной кнопке в нижнем ряду
\path
(6.3,.2) coordinate(arbl) ++(5.7,0) coordinate(arbr)
++(0,.9) coordinate(artr) ++(-5.7,0) coordinate(artl);
\node[terminal,text=disp,anchor=center] at ($(arbl)!.5!(artr)$) {#1} [fill=white!95,opacity=.7] (arbl) rectangle (artr) ;
},
rawc/.pic={%строка через весь дисплей с выделенной активностью и текстом по центру
\path
(.4,.2) coordinate(arbl) ++(11.6,0) coordinate(arbr)
++(0,.9) coordinate(artr) ++(-11.6,0) coordinate(artl);
\node[terminal,text=disp,anchor=center] at ($(arbl)!.5!(artr)$) {#1} [fill=white!95,opacity=.7] (arbl) rectangle (artr);
}
}
Оформление контура дисплея
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Дисплей маленького экрана
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\tikzset{
display/.pic={%рамка для дисплея
\path[terminal] (0,.2) coordinate (dtl) ++(12.4,0) coordinate (dtr) ++(0,-7.2) coordinate (dbr) ++(-12.4,0) coordinate (dbl);
\draw[thick,gray!20,fill=disp,rounded corners] (dbl) rectangle (dtr);
}
}
Создание стилей строки статуса для различных режимов
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Строка состояния пульта
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\tikzset{
pultmain/.pic={% режим 1 с произвольным текстом, часами и аккумулятором заголовок дисплея пульт на вход отправим text
\path
(0.4,.2) coordinate(arbl) ++(11.6,0) coordinate(arbr)
++(0,.9) coordinate(artr) ++(-11.6,0) coordinate(artl);
\path ($(arbl)!.5!(artl)$) node[terminal] {#1} +(4,0) node[terminal] {08:20:46};
\pic[textdisp] at (10.4,0) {accum=.4};
\draw[textdisp,thick] (arbl.south west)--(arbr.south east);
},
pultfree/.pic={%заголовок дисплея пульт на вход отправим свободную строку
\path
(0.4,.2) coordinate(arbl) ++(11.6,0) coordinate(arbr)
++(0,.9) coordinate(artr) ++(-11.6,0) coordinate(artl);
\node[terminal,text width=10.5em] at ($(arbl)!.5!(artl)$) {#1};%обычная строка
\pic[textdisp] at (10.4,0) {accum=.4};%\fill[red](arbl.south west)circle (1pt);
\draw[textdisp,thick] (arbl.south west)--(arbr.south east);
},
priemfree/.pic={%заголовок дисплея приемника на вход отправим свободную строку
\path
(0.4,.2) coordinate(arbl) ++(11.6,0) coordinate(arbr)
++(0,.9) coordinate(artr) ++(-11.6,0) coordinate(artl);
\pic[textdisp]{accum=.5};\pic[textdisp] at (9.4,0) {antena};
\draw[textdisp,thick] (arbl.south west)--(arbr.south east);
},
rawg/.pic={\node[terminal,text width=5.6em] {#1};%обычная строка
},
rawa/.pic={\pic{arow} node[terminal,text width=5.6em,text=disp] {#1};%активная строка
}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%шаблон дисплея создаем команду \dispm с 8-ю входными параметрами
\def\dispm#1#2#3#4#5#6#7#8{
\begin{tikzpicture}[x=10pt,y=10pt,node distance=10pt]%установить масштаб отображения
\pic{display};%вывести фон дисплея
\pic at (0,-1) {#1};%строка состояния
\pic at (0,-2) {#2};%вторая строка
\pic at (0,-3) {#3};%третья строка
\pic at (0,-4) {#4};%четвертая строка
\pic at (0,-5) {#5};%пятая строка
\pic at (0,-6) {#6};%шестая строка
\path (0,-7) pic{lbut=#7} pic{rbut=#8};%седьмая строка с кнопками состояния
\draw[textdisp,thick] (6.2,-.9) -- (6.2,-5.9);%линия по центру экрана вертикальная
\end{tikzpicture}
}
% \dispm
% {}%1-я строка значения входного параметра (pultmain=text priemfree, pultfree=TEXT)
% {}%2-я строка (arawa=TEXT - активная строка, )
% {}%3-я строка (arawp=TEXT - пассивная строка,)
% {}%4-я строка (rawc=TEXT - активная строка с текстом по центру)
% {}%5-я строка
% {}%6-я строка
% {}{}%нижние кнопки в 7-й строке
%
Пример
\dispm
{pultmain=ARM}%1-я строка (pultmain=ARM, pultmain=DISARM, priemfree, pultfree=TEXT)
{arawa=TEXT}%2-я строка (arawa=TEXT - активная строка, )
{arawp=TEXT}%3-я строка (arawp=TEXT - пассивная строка,)
{}%4-я строка (rawc=TEXT - активная строка с текстом по центру)
{}%5-я строка
{rawc=TEXT}%6-я строка
{MENU}{SERVICE}%нижние кнопки в 7-й строке

7.7.2 - Foreach for Tex
Установка
\usepackage{pgffor} % LATEX
\input pgffor.tex % plain TEX
\usemodule[pgffor] % ConTEXt
Отдельный пакет для самостоятельного использования в документах Tex и Latex
По умолчанию сам загружает пакет \tikz
Он определяет две новые команды: \foreach и \breakforeach.
Синтаксис
\foreach 〈variables〉 [〈options〉] in 〈list〉 〈commands〉
Простой пример
\def\mylist{1,2,3,0}
\foreach \x in \mylist {[\x]}
Выдаст: [1][2][3][0]
Вложенные циклы
\begin{tikzpicture}
\foreach \x in {0,1,2,3}
\foreach \y in {0,1,2,3}
{
\draw (\x,\y) circle (0.2cm);
\fill (\x,\y) circle (0.1cm);
}
\end{tikzpicture}
Списки через многоточие
\foreach \x in {a,b,9,8,...,1,2,2.125,...,2.5} {\x, }
выдаст:
a, b, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 2.125, 2.25, 2.375, 2.5,
\foreach \x in {2^1,2^...,2^7} {$\x$, } yields 21, 22, 23, 24, 25, 26, 27,
\foreach \x in {0\pi,0.5\pi,...\pi,3\pi} {$\x$, } yields 0π, 0.5π, 1π, 1.5π, 2π, 2.5π, 3π,
\foreach \x in {A_1,..._1,H_1} {$\x$, } yields A1, B1, C1, D1, E1, F1, G1, H1,
Координаты для TIKZ
\tikz \foreach \position in {(0,0), (1,1), (2,0), (3,1)}
\draw \position rectangle +(.25,.5);
Несколько переменных в цикле
\begin{tikzpicture}
\foreach \x/\xtext in {0,...,3,2.72 / e}
\draw (\x,0) node{$\xtext$};
\end{tikzpicture}
задан паттерн для получения переменных \x второе значение через / — \xtext
Отсутствие значений для второго параметра замещается первым значением.
/\begin{tikzpicture} % Let's draw circles at interesting points:
\foreach \x / \y / \r in {0 / 0 / 2mm, 1 / 1 / 3mm, 2 / 0 / 1mm}
\draw (\x,\y) circle (\r);
% Same effect
\foreach \center/\r in {{(0,0)/2mm}, {(1,1)/3mm}, {(2,0)/1mm}} \draw[yshift=2.5cm] \center circle (\r);
\end{tikzpicture}
Угловые координаты
\begin{tikzpicture}[line cap=round,line width=3pt]
\filldraw [fill=yellow!80!black] (0,0) circle (2cm);
\foreach \angle / \label in
{0/3, 30/2, 60/1, 90/12, 120/11, 150/10, 180/9, 210/8, 240/7, 270/6, 300/5, 330/4}
{
\draw[line width=1pt] (\angle:1.8cm) -- (\angle:2cm);
\draw (\angle:1.4cm) node{\textsf{\label}};
}
\foreach \angle in {0,90,180,270}
\draw[line width=2pt] (\angle:1.6cm) -- (\angle:2cm);
\draw (0,0) -- (120:0.8cm); % hour
\draw (0,0) -- (90:1cm); % minute
\end{tikzpicture}%

Параметры настройки оператора foreach
Описанные ниже ключи можно использовать в аргументе 〈options〉 команды \foreach. Все они имеют путь /pgf/foreach/, однако путь устанавливается автоматически при анализе 〈options〉, поэтому его не нужно указывать явно.
/pgf/foreach/var=〈variable〉— Этот ключ обеспечивает альтернативный способ указания переменных: \foreach [var=\x,var=\y] аналогичен \foreach \x/\y./pgf/foreach/evaluate=〈variable〉 as 〈macro〉 using 〈formula〉— Этот ключ позволяет оценивать переменную с помощью математического механизма.\foreach \x [evaluate=\x] in {2^0,2^...,2^8}{$\x$, }вернет 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0,
as
или \foreach \x [evaluate=\x as \xeval] in {2^0,2^...,2^8}{$\x=\xeval$, } значение будет помещено в \xeval
using
указывает формулу для вычисления
\tikz\foreach \x [evaluate=\x as \shade using \x*10] in {0,1,...,10} \node [fill=red!\shade!yellow, minimum size=0.65cm] at (\x,0) {\x};
/pgf/foreach/remember=〈variable〉 as 〈macro〉 (initially 〈value〉)— Этот ключ позволяет запомнить значение элемента, хранящееся в 〈variable〉, во время следующей итерации, сохраненное в 〈macro〉.
\foreach \x [remember=\x as \lastx (initially A)] in {B,...,H}{$\overrightarrow{\lastx\x}$, }
/pgf/foreach/count=〈macro〉 from 〈value〉— считает номер итерации
\tikz[x=0.75cm,y=0.75cm]
\foreach \x [count=\xi] in {a,...,e}
\foreach \y [count=\yi] in {\x,...,e}
\node [draw, top color=white, bottom color=blue!50, minimum size=0.666cm]
at (\xi,-\yi) {$\mathstrut\x\y$};
/pgf/foreach/parse={〈boolean〉}— Если для этого ключа установлено значение true, верхняя граница цикла будет передана в \pgfmathparse./pgf/foreach/expand list={〈boolean〉}— Если для этого ключа установлено значение true, содержимое списка полностью раскрывается с помощью \edef перед дальнейшей обработкой.
\breakforeach
Если эта команда задана внутри команды \foreach, дальнейшее выполнение 〈команд〉 происходить не будет. Однако текущее выполнение 〈команд〉 продолжается в обычном режиме, поэтому, вероятно, лучше использовать эту команду только в конце команды \foreach.
7.7.3 - Key Management
Введение
В основном этот раздел описываю, так как его активно используют библиотеки TIKZ.
А в общем этот вопрос вполне удовлетворяет знание TEX и его внутренней кухни по созданию макросов и переменных.
Подключение пакета
\usepackage{pgfkeys}
Отличия pgfkeys от xkeyval
- pgfkeys организует дерево ключей
- pgfkeys не влияет на состояние стека
- pgfkeys медленнее keyval
- pgfkeys поддерживает стили (полезно для TIKZ)
- pgfkeys поддерживает множественные аргументы
- pgfkeys поддерживает обработчики обратного вызова и ошибок
Краткое описание механизма Key Management
Организован по принципу файловой системы Unix, корень и как дерево ветвление всех элементов
Можно указать полный путь к ключу или сокращенное наименование и путь будет подставлен автоматически.
Основная команда \pgfkeys берет пару ключ и значение.
Для каждого
\pgfkeys{/my key=hallo,/your keys/main key=something\strange,
key name without path=something else}
Сначала установим код для ключа: стр.1 и затем выполним его с переданным параметром стр.2
\pgfkeys{/my key/.code=The value is '#1'.}
\pgfkeys{/my key=hi!}
В качестве параметров может быть несколько значений (ключевое слово /.code 2 args=)
\pgfkeys{/my key/.code 2 args=The values are '#1' and '#2'.}
\pgfkeys{/my key={a1}{a2}}
Может быть значение по умолчанию: \pgfkeys{/my key/.default=hello}
Можно указать обязательное значение /.value required или запрещенное значение /.value forbidden, т.е. не нужно вводить значение.
Ключ /.cd - изменит путь. Т.е. после этого ключа, все остальные будут выполнять команды с новым путем.
\pgfkeys{/tikz/.cd,line width=1cm,line cap=round}
т.е. все остальные команды будут начинаться с /tikz/
Ключи могут вызывать выполнение других ключей.
\pgfkeys{/a/.code=(a:#1)}
\pgfkeys{/b/.code=(b:#1)}
\pgfkeys{/my style/.style={/a=foo,/b=bar,/a=#1}}
\pgfkeys{/my style=wow}
получим (a:foo)(b:bar)(a:wow)
Еще пример с созданием стиля tikz
\pgfkeys{/tikz/.style=/tikz/.cd}
\pgfkeys{tikz,line width=1cm,draw=red}
Описание синтаксиса pgfkeys
Если ключ начинается с / — это ключ с полным путем, если без слеша, то это не полный путь.
\pgfkeyssetvalue{⟨full key⟩}{⟨token text⟩}
Эта команда сохраняет token text в full key
Это не может быть частичным ключом.
\pgfkeyssetvalue{/my family/my key}{Hello, world!}%установить ключ
\pgfkeysvalueof{/my family/my key}%вывести ключ
\pgfkeyssetevalue{⟨full key⟩}{⟨token text⟩} — это тоже, но \edef версия
\pgfkeyslet{⟨full key⟩}{⟨macro⟩}
\def\helloworld{Hello, world!}
\pgfkeyslet{/my family/my key}{\helloworld}
\pgfkeysvalueof{/my family/my key}
позволяет устанавливать для ключа значение макроса, в нашем случае будет подставлено значение \helloworld
Недопустимо,чтобы ключ совпадал с \relax — relax это пустышка
\pgfkeysgetvalue{⟨full key⟩}{⟨macro⟩}
Извлекает токены из ключа
Если ключ не установлен то токен будет равен \relax
\pgfkeysvalueof{⟨full key⟩}
Возвращает значение ключа и вставляет его в текст
\pgfkeysifdefined{⟨full key⟩}{⟨if⟩}{⟨else⟩}
\pgfkeyssetvalue{/my family/my key}{Hello, world!}
\pgfkeysifdefined{/my family/my key}{yes}{no}
проверяет, если ключ был определен, то выведет значение if, если не определен, то else
\pgfkeys
Ключи могут выполнять следующие действия:
- выполняет команду,хранящуюся в key с аргументом value
- сохраняет значение value в ключе key
- если имя ключа известный обработчик,тогда обработчик все сделает
- если ключ неизвестный, то вызовется обработчик неизвестных ключей
Синтаксис команд
\pgfkeys{key=value,key,key={val1}{val2}}
Возможно указать:
- key=value,
- key,
- key={val1}{val2}
или просто значение в {} если оно содержит запятые или спецсимволы
\pgfqkeys{⟨default path⟩}{⟨key list⟩}
Эта команда имеет тот же эффект,что и \pgfkeys{⟨default path⟩/.cd,⟨key list⟩}
\pgfkeysalso{⟨key list⟩}
в этой команде путь не изменяется
\pgfqkeysalso{⟨default path⟩}{⟨key list⟩}
вызывает с изменением пути
Команда привязанная к 1 символу
Наверно это удобно.
Так работают во всех nodes кавычки " которые заменяются текстом \label={}
Для этого нужно:
- Установить
/handlers/first char syntax=〈true or false〉вtrue - Привязать к волшебному слову
the character <символ>макрос, который будет выполняться - Объявить привязанный макрос
\pgfkeys{
/handlers/first char syntax=true,
/handlers/first char syntax/the character "/.initial=\myquotemacro,
/handlers/first char syntax/the character </.initial=\mypointedmacro,
}
\def\myquotemacro#1{Quoted: #1. }
\def\mypointedmacro#1{Pointed: #1. }
\ttfamily \pgfkeys{"foo", <bar>}
Дальше все параметры в "" будут переданы в макрос myquotemacro, а в <> в макрос mypointedmacro
Значение по умолчанию 〈key〉/.@def
- если не нужно вводить значения, то можно указать
key=\pgfkeysnovalue - проверяется наличие ключа:
〈key〉/.@def - если ключ есть, то он замещается в токене
Для установки по умолчанию значения используем команду: \pgfkeys{/my key/.default=hello}
Команды выполняемые в ключах 〈key〉/.@cmd
Во всем макросах в \pgf параметры должны заканчиваться значением \pgfeov
т.е. что сделает на самом деле пакет \pgf
\usepackage {shortvrb} \MakeShortVerb {\|}
\def\mystore#1+#2\pgfeov{\def\a{#1}\def\b{#2}}
\pgfkeyslet{/my key/.@cmd}{\mystore}
\pgfkeys{/my key=hello+world}
получим:
|\a| is `\a', |\b| is `\b'.
т.е.
\a is ‘hello’, \b is ‘world’.
Что предлагает пакет взамен
\pgfkeysdef{〈key〉}{〈code〉}— Эта команда временно определяет TEX-макрос со списком аргументов #1\pgfeov, а затем позволяет 〈key〉/.@cmd быть равным этому макросу.\pgfkeysedef{〈key〉}{〈code〉}— аналогично, но работает, какedef\pgfkeysdefnargs{〈key〉}{〈argument count〉}{〈code〉}— Эта команда работает аналогично \pgfkeysdef, но позволяет вам указать произвольное «счетчик аргументов» от 0 до 9 (включительно).
\usepackage {shortvrb} \MakeShortVerb {\|}
\pgfkeysdefnargs{/my key}{2}{\def\a{#1}\def\b{#2}}
\pgfkeys{/my key= {hello} {world}}
|\a| is `\a', |\b| is `\b'
\pgfkeysedefnargs{〈key〉}{〈argument count〉}{〈code〉}— аналогично, ноedef\pgfkeysdefargs{〈key〉}{〈argument pattern〉}{〈code〉}— Эта команда работает аналогично \pgfkeysdefnargs, но позволяет вам предоставить произвольный «шаблон аргумента», а не просто несколько аргументов.\pgfkeysdefargs{/my key}{#1+#2}{\def\a{#1}\def\b{#2}}\pgfkeysedefargs{〈key〉}{〈argument pattern〉}{〈code〉}— это егоedefверсия
Хранение значений в ключах
Если у ключа не определен key/.@cmd, то он будет просто хранить значение которое может быть задано командой \pgfkeyssetvalue
Обработчики ключей
Обработчики — это дополнительная возможность выполнять некие действия над ключами сверх того, что предоставляется стандартной библиотекой.
\pgfkeysdef{/handlers/.my code}{\pgfkeysdef{\pgfkeyscurrentpath}{#1}}
Путь ключа, хранится в макросе
\pgfkeyscurrentpathИмя ключа, хранится в макросе
\pgfkeyscurrentnameобработчик должен начинаться с
./handler config=all|only existing|full or existing— Изменяет исходную конфигурацию использования обработчиков ключей./handler config/only existing/add exception={〈key handler name〉}— Позволяет добавлять исключения к существующей функции /handler config=only.
Обработка ключей, которые неизвестны
Для некоторых ключей не определен ни сам ключ, ни его подраздел .@cmd, ни обработчик. В этом случае проверяется, существует ли ключ 〈текущий путь〉/.unknown/.@cmd.
Т.к. он существует, то будет выполнена какая-то странная вещь, как он ее поймет.
Пути поиска и обрабатываемые ключи
Обработчики ключей
Теперь мы опишем, какие обработчики клавиш определены по умолчанию.
Обработчик пути
Key handler 〈key〉/.cd— Этот обработчик устанавливает путь по умолчанию 〈key〉. Обратите внимание, что путь по умолчанию сбрасывается в начале каждого вызова \pgfkeys и становится равным/.
\pgfkeys{/tikz/.cd,...}
Key handler 〈key〉/.is family— Этот обработчик настраивает такие вещи, что при выполнении 〈key〉 текущий путь устанавливается на 〈key〉.
\pgfkeys{/tikz/.is family}
\pgfkeys{tikz,line width=1cm}
Установка по умолчанию
Key handler 〈key〉/.default=〈value〉— Устанавливает значение по умолчанию 〈key〉 в 〈value〉. Это означает, что всякий раз, когда при вызове \pgfkeys не указывается значение, вместо него будет использоваться это 〈значение〉.\pgfkeys{/width/.default=1cm}Key handler 〈key〉/.value required— Этот обработчик вызывает выдачу ключа /errors/value сообщения об ошибке всякий раз, когда 〈key〉 используется без значения.\pgfkeys{/width/.value required}Т.е. требует обязательно указать значение.Key handler 〈key〉/.value forbidden— не будет выдавать сообщение об ошибке, если указано будет значение ключа
Определение кода ключа
Key handler 〈key〉/.code=〈code〉— Этот обработчик выполняет \pgfkeysdef с параметрами 〈key〉 и 〈code〉.Key handler 〈key〉/.ecode=〈code〉— выполнит команду \pgfkeysedefKey handler 〈key〉/.code 2 args=〈code〉— с двумя аргументамиKey handler 〈key〉/.ecode 2 args=〈code〉— с двумя аргументами edefKey handler 〈key〉/.code n args={〈argument count〉}{〈code〉}— с n аргументамиKey handler 〈key〉/.ecode n args={〈argument count〉}{〈code〉}— с n аргументами edefKey handler 〈key〉/.code args={〈argument pattern〉}{〈code〉}— с произвольным паттерном аргументовKey handler 〈key〉/.ecode args={〈argument pattern〉}{〈code〉}— с произвольным паттерном аргументов edefKey handler 〈key〉/.add code={〈prefix code〉}{〈append code〉}— Этот обработчик добавляет код к существующему ключу. 〈код префикса〉 добавляется к коду, хранящемуся в 〈key〉/.@cmd, в начале, 〈код добавления〉 добавляется к этому коду в конце.
\pgfkeys{/par indent/.code={\parindent=#1}}
\newdimen\myparindent
\pgfkeys{/par indent/.add code={}{\myparindent=#1}}
...
\pgfkeys{/par indent=1cm} % This will set both \p
Key handler 〈key〉/.prefix code=〈prefix code〉— Этот обработчик является ярлыком для 〈key〉/.add code={〈prefix code〉}{}. То есть этот обработчик добавляет 〈префиксный код〉 в начало кода, хранящегося в 〈key〉/.@cmd.Key handler 〈key〉/.append code=〈append code〉— Этот обработчик является ярлыком для 〈key〉/.add code={}{〈append code〉}.
Определение стиля
Key handler 〈key〉/.style=〈key list〉— Этот обработчик настраивает ситуацию таким образом, что всякий раз, когда 〈ключ〉=〈значение〉 встречается в списке ключей, вместо этого обрабатывается 〈список ключей〉, в котором каждое вхождение #1 заменено на 〈значение〉. Как всегда, если 〈значение〉 не указано, используется значение по умолчанию, если оно определено, или специальное значение \pgfkeysnovalue.
\pgfkeys{/par indent/.code={\parindent=#1}}
\pgfkeys{/no indent/.style={/par indent=0pt}}
\pgfkeys{/normal indent/.style={/par indent=2em}}
\pgfkeys{/no indent}
...
\pgfkeys{/normal indent}
Key handler 〈key〉/.estyle=〈key list〉— определяет стиль черезedefKey handler 〈key〉/.style 2 args=〈key list〉— с двумя аргументамиKey handler 〈key〉/.estyle 2 args=〈key list〉— с двумя аргументами edefKey handler 〈key〉/.style n args={〈argument count〉}〈key list〉— n аргументовKey handler 〈key〉/.add style={〈prefix key list〉}{〈append key list〉}— добавить значение к стилюKey handler 〈key〉/.style args={〈argument pattern〉}{〈key list〉}— стиль с произвольным паттерномKey handler 〈key〉/.estyle args={〈argument pattern〉}{〈code〉}— стиль с произвольным паттерном edefKey handler 〈key〉/.prefix style=〈prefix key list〉— prefix style добавитьKey handler 〈key〉/.append style=〈append key list〉— добавить стиль в конец
Определение ключей значений, макросов, if и выбора
Для некоторых клавиш код, который должен по ним выполняться, достаточно «специализирован».
Key handler 〈key〉/.initial=〈value〉— Этот обработчик устанавливает значение 〈key〉 в 〈value〉. Обратите внимание, что никакие подразделы не задействованы. После использования этого обработчика, согласно правилам, регулирующим ключи, вы можете впоследствии изменить значение 〈key〉, просто написав 〈key〉=〈value〉. Таким образом, этот обработчик используется для установки начального значения ключа.Key handler 〈key〉/.get=〈macro〉— выведет содержимое ключа и поместит в\macroKey handler 〈key〉/.add={〈prefix value〉}{〈append value〉}— добавит к ключуKey handler 〈key〉/.prefix={〈prefix value〉}— добавит префиксKey handler 〈key〉/.append={〈append value〉}— добавит суффиксKey handler 〈key〉/.link=〈another key〉— сделает ссылку на другой ключKey handler 〈key〉/.store in=〈macro〉— это прямой аналог\def\macro{#1}
\pgfkeys{/text/.store in=\mytext}
\def\a{world} \pgfkeys{/text=Hello \a!}
\def\a{Gruffalo}
\mytext
выведет:
Hello Gruffalo!
Key handler 〈key〉/.estore in=〈macro〉— тоже, только edefKey handler 〈key〉/.is if=〈TEX-if name〉— имитация if Tex
\newif\iftheworldisflat
\pgfkeys{/flat world/.is if=theworldisflat}
\pgfkeys{/flat world=false}
\iftheworldisflat
Flat \else Round?
\fi
Key handler 〈key〉/.is choice— Этот обработчик настраивает ситуацию так, что запись 〈key〉=〈value〉 приведет к выполнению подраздела 〈key〉/〈value〉. Таким образом, каждый из возможных вариантов должен быть задан подразделом 〈key〉.
\pgfkeys{/line cap/.is choice}
\pgfkeys{/line cap/round/.code={\pgfsetroundcap}}
\pgfkeys{/line cap/butt/.code={\pgfsetbuttcap}}
\pgfkeys{/line cap/rect/.code={\pgfsetrectcap}}
\pgfkeys{/line cap/rectangle/.style={/line cap=rect}}
...
\draw [/line cap=butt] ...
Расширенные и множественные значения
Key handler 〈key〉/.expand once=〈value〉— Этот обработчик расширяет 〈value〉 один раз (точнее, он выполняет команду \expandafter для первого токена 〈value〉), а затем обрабатывает полученный 〈result〉, как если бы вы написали 〈key〉=〈result〉.Key handler 〈key〉/.expand twice=〈value〉— дважды расширяет значениеKey handler 〈key〉/.expanded=〈value〉— Этот обработчик полностью расширит 〈value〉 (с помощью \edef) перед обработкой 〈key〉=〈result〉.Key handler 〈key〉/.evaluated=〈value〉— Этот обработчик оценит 〈value〉 как математическое выражение с помощью \pgfmathparse и присвоит 〈key〉=\pgfmathresult.Key handler 〈key〉/.list=〈comma-separated list of values〉— Этот обработчик вызывает многократное использование ключа, а именно один раз для каждого элемента списка значений. Что-то вроде foreach
Обработчик с пересылкой значений
Key handler 〈key〉/.forward to=〈another key〉— Этот обработчик заставляет 〈key〉 «пересылать» свой аргумент 〈другому ключу〉. При использовании 〈key〉 сначала будет выполнен ее обычный код. Затем значение (дополнительно) передается «другому ключу».
\pgfkeys{
/a/.code=(a:#1),
/b/.code=(b:#1),
/b/.forward to=/a,
/c/.forward to=/a
}
\pgfkeys{/b=1} \pgfkeys{/c=2}
выведет
(b:1)(a:1) (a:2)
Key handler 〈key〉/.search also={〈path list〉}— Стиль, который устанавливает обработчик /.unknown в 〈key〉. Этот обработчик /.unknown затем будет искать неизвестные ключи по каждому пути, указанному в {〈списке путей〉}.
Обработчики для тестирования ключей
Key handler 〈key〉/.try=〈value〉— Этот обработчик вызывает то же самое, как если бы вместо этого было написано 〈key〉=〈value〉. Однако если ни 〈key〉/.@cmd, ни сам ключ не определены, обработчики вызываться не будут. Вместо этого выполнение ключа просто останавливается. Таким образом, этот обработчик «пытается» использовать ключ, но никаких дальнейших действий не предпринимается, если ключ не определен.Key handler 〈key〉/.retry=〈value〉— Этот обработчик работает так же, как /.try, только он ничего не будет делать, если \ifpgfkeyssuccess имеет значение false. Таким образом, этот обработчик попытается установить ключ только в том случае, если «последняя попытка не удалась».Key handler 〈key〉/.lastretry=〈value〉— Этот обработчик работает как /.retry, только он будет вызывать обычные обработчики для неизвестных ключей, если \ifpgfkeyssuccess имеет значение false.
Обработчики для проверки ключей
Key handler 〈key〉/.show value— Этот обработчик выполняет команду \show для значения, хранящегося в 〈key〉. Это полезно в основном для отладки.Key handler 〈key〉/.show code— Этот обработчик выполняет команду \show для кода, хранящегося в 〈key〉/.@cmd. Это полезно в основном для отладки.
Обработка ошибок
В определенных ситуациях могут возникнуть ошибки, например, при использовании неопределенного ключа. В таких ситуациях выполняются ключи ошибок. Они должны хранить макрос, который получает два аргумента: первый — это ключ-нарушитель (возможно, только после раскрытия макроса), второй — значение, которое было передано в качестве параметра (также возможно, только после раскрытия макроса).
Ключевая фильтрация
Обычно вызов \pgfkeys устанавливает все ключи, указанные в списке аргументов. Обычно именно этого ожидают пользователи. Однако реализации различных пакетов или pgf-библиотек могут нуждаться в большем контроле над процедурой установки ключей: библиотека A может захотеть установить свои параметры напрямую и передать все оставшиеся в библиотеку B.
Установить библиотеку фильтрации
\usepgfkeyslibrary{filtered} % LATEX and plain TEX
\usepgfkeyslibrary[filtered] % ConTEXt
7.7.4 - Примеры PIC в библиотеке TIKZ
Примеры использования поисковых запросов POSIX
Постановка задачи
Немного запутанно, но суть в том, что у устройства есть адреса на каждом выходе, и эти адреса изменяются, а картинок несколько.
Было принято решение не рисовать в редакторе картинки, а запрограммировать в LATEX и на вход просто подавать массив с адресами и номерами выходов.
- рисуем матрицу с адресами
- адрес состоит из двух частей, разделенных :
- первая часть 4 разряда
- вторая часть 5 разрядов
- матрица может располагаться горизонтально и вертикально
- в вертикальном положении над каждым адресом необходимо указать номер порта в черном кружке и схематичное изображение в виде скобки с кружком
- в горизонтальном положении слева от адреса расположить номер порта в черном кружке
Решение
- Создать стили для вертикальных и горизонтальных адресов
- Создать шаблон для номера выходного порта (цифра в черном кружке)
- Создать шаблон для имитации скрепки с красной точкой
- Создать шаблон для формирования горизонтального адреса
- Создать шаблон для формирования вертикального адреса
- Создать матрицу из 5-ти горизонтальных адресов в одной строке с номерами выходных портов в черных кружках
- Создать матрицу из 5-ти вертикальных адресов в одной колонке с номерами выходных портов в черных кружках и скрепкой с красной точкой

Код с описанием
\tikzset{vad/.style={node distance=0pt,inner sep=2pt,rotate=90,draw}}%настройка стиля для вертикальных адресов
\tikzset{had/.style={node distance=0pt,inner sep=2pt,rotate=0,draw}}%настройка стиля для горизонтальных адресов
\tikzset{
orr/.pic={%рисуем маленький красный кружок на белом фоне
\fill[white] (0,-0.3mm) ellipse (.6mm and 1mm);
\fill[red] (0,0) ellipse (.4mm and .6mm);},
piro/.pic={%рисуем скобку и внизу скобки помещаем красный кружок orr
\draw[thick,orange,rounded corners] (-.7ex,1cm) -- (-.7ex,.3cm) -- (0,0) pic{orr} -- (.7ex,.3cm) -- (.7ex,1cm);},
pics/ntt/.style={%рисуем черный кружок с переменной номер внутри кружка
code={\node [circle,fill=black,minimum size=1em,inner sep=0pt,text=white] {#1};}},
sp/.pic={\path (0,0)--(.2,0);}%это хитрый pic пробел. Чтобы не разъезжались строки.
}
\def\haddr#1#2{%строим горизонтальный адрес в формате 4:5
\coordinate(a0)at(0,.12);
\foreach \z [count=\x,evaluate=\x as \y using \x-1] in {#1}{
\node(a\x)[had,right=of a\y] {\z};
};
\node(s0)[had,draw=none,right=of a4] {:};
\foreach \z [count=\x,evaluate=\x as \y using \x-1] in {#2}{
\node(s\x)[had,right=of s\y] {\z};
};
}
\def\vaddr#1#2{%строим вертикальный адрес в формате 4:5
\coordinate(a0)at(0,0);
\foreach \z [count=\x,evaluate=\x as \y using \x-1] in {#1}{
\node(a\x)[vad,right=of a\y] {\z};
};
\node(s0)[vad,draw=none,right=of a4] {:};
\foreach \z [count=\x,evaluate=\x as \y using \x-1] in {#2}{
\node(s\x)[vad,right=of s\y] {\z};
};
}
%рисуем горизонтальную матрицу из пяти адресов
%в первой колонке черный кружок с номером \pic{ntt=1}
%во второй колонке пробел \pic{sp}, чтобы отделить
%в третьей колонке горизонтальный адрес \haddr...
\begin{tikzpicture}
\matrix[matrix of nodes,row sep={0ex}]{
\pic{ntt=1};&\pic{sp};&\haddr{0,0,0,1}{0,0,0,1,2}\\
\pic{ntt=2};& &\haddr{0,0,0,1}{0,0,0,1,3}\\
\pic{ntt=3};& &\haddr{0,0,0,1}{0,0,0,1,4}\\
\pic{ntt=4};& &\haddr{0,0,0,1}{0,0,0,1,5}\\
\pic{ntt=5};& &\haddr{0,0,0,1}{0,0,0,1,6}\\};
\end{tikzpicture}
%рисуем вертикальную матрицу из пяти адресов
%в первой строке черные кружки с номерами \pic{ntt=1}
%во второй строке скобки, \pic{piro}
%в третьей строке вертикальный адрес \vaddr...
\begin{tikzpicture}
\matrix[matrix of nodes,column sep={0ex}]{
\pic{ntt=1};&\pic{ntt=2};&\pic{ntt=3};&\pic{ntt=4};&\pic{ntt=5};\\
\pic{piro};&\pic{piro};&\pic{piro};&\pic{piro};&\pic{piro};\\
\vaddr{0,0,0,1}{0,0,0,1,2}&
\vaddr{0,0,0,1}{0,0,0,1,2}&
\vaddr{0,0,0,1}{0,0,0,1,2}&
\vaddr{0,0,0,1}{0,0,0,1,2}&
\vaddr{0,0,0,1}{0,0,0,1,2}\\};
\end{tikzpicture}

7.7.5 - Matrix в модуле TIKZ
Введение в MATRIX
при объявлении node просто указать, что это будет matrix
\node [matrix,fill=red!20,draw=blue,very thick]
а дальше как в обычной таблице или array
\draw (0,0) circle (4mm); & \node[rotate=10] {Hello}; \\
\draw (0.2,0) circle (2mm); & \fill[red] (0,0) circle (3mm); \\
};
вот и всё.
every matrix
определяет стиль matrix
every outer matrix
это настраивает внешний node в котором объявлен matrix
\matrix
специальная команда без node
аналог \path node[matrix]
Выравнивание matrix
column sep=⟨spacing list⟩
расстояние между колонками

column sep={1cm,between origins} — расстояние будет мерить не по краям, а по центрам
row sep=⟨spacing list⟩
расстояние между строк
Задавать можно целиком на matrix, так и на отдельную ячейку
\draw (0,0) circle (2mm); \\[1cm,between origins] — можно так
\node {8}; &[2mm] \node{1}; &[-1mm] \node {6}; \\ — а можно и так
&[between borders] \node (c) {6}; — а можно и так
параметры ячейки (размеры)
every cell={⟨row⟩}{⟨column⟩} задает параметры каждой ячейки
cells=⟨options⟩
это стиль ячейки cell/.append style=⟨options⟩
nodes=⟨options⟩
это тоже стиль для ячеек matrix node/.append style=⟨options⟩
\begin{tikzpicture}
\matrix [nodes={fill=blue!20,minimum size=5mm}]
{
\node {8}; & \node{1}; & \node {6}; \\
\node {3}; & \node{5}; & \node {7}; \\
\node {4}; & \node{9}; & \node {2}; \\
};
\end{tikzpicture}
стили колонок и строк
- /tikz/column ⟨number⟩ —
column 2/.style={green!50!black} - /tikz/every odd column — стиль для нечетной колонки
- /tikz/every even column — стиль для четной колонки
- /tikz/row ⟨number⟩ —
row 3/.style={green!50!black} - /tikz/every odd row — стиль для нечетной строки
- /tikz/every even row — стиль для четной строки
- /tikz/row ⟨row number⟩ column ⟨column number⟩ — стиль для строки и колонки
\begin{tikzpicture}
[row 1/.style={red},
column 2/.style={green!50!black},
row 3 column 3/.style={blue}]
\matrix
{
\node {8}; & \node{1}; & \node {6}; \\
\node {3}; & \node{5}; & \node {7}; \\
\node {4}; & \node{9}; & \node {2}; \\
};
\end{tikzpicture}
Выравнивание в ячейках и колонках
\begin{tikzpicture}
[column 1/.style={anchor=base west},%выравнивает слева
column 2/.style={anchor=base east},%выравнивает справа
column 3/.style={anchor=base}]% выравнивает по центру
\matrix
{
\node {123}; & \node{456}; & \node {789}; \\
\node {12}; & \node{45}; & \node {78}; \\
\node {1}; & \node{4}; & \node {7}; \\
};
\end{tikzpicture}
Большая таблица
\usetikzlibrary {matrix,fit}
\begin{tikzpicture}[
font=\sffamily,
head color/.style args={#1/#2}{
row 1 column #1/.append style={nodes={fill=#2}}},
% swap order of row and column styles
matrix/inner style order={
every cell,
row, even odd row,
column, even odd column,
cell
}
]
\matrix [
matrix of nodes, nodes in empty cells,
nodes={text width=2cm, align=center,
minimum height=1.5em, anchor=center},
% add striped row style
every even row/.style={nodes={fill=olive!50}},
% modify the feature column and header row
column 1/.style= {nodes={fill=olive, inner ysep=0}},
row 1/.style= {nodes={text depth=0.2ex, text=white}},
row 1 column 1/.style={nodes={fill=none, draw=none}},
head color/.list={2/orange,3/teal,4/cyan,5/magenta} % specify header colors
] (m)
{
& Basic & Standard & Professional & Enterprise \\
Feature A & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
Feature B & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
Feature C & & & & $\bullet$ \\
Feature D & & $\bullet$ & $\bullet$ & $\bullet$ \\
Feature E & & & $\bullet$ & $\bullet$ \\
};
% Add emphasis on selection by the use of "fit" library
\node[fit={(m-1-4.north west) (m-6-4.south east)},
ultra thick, inner sep=0pt, rounded corners=1mm,
draw=cyan, label={[cyan,align=center]270:Popular\\Choice!}]{};
\end{tikzpicture}

внутренние стили назначаются в определенной очередности.
Очередность задается параметром:
inner style order
\tikzset{
matrix/inner style order={
every cell,
column,
even odd column,
row,
even odd row,
cell,
},
}
- inner style/every cell
- inner style/column
- inner style/even odd column
- inner style/row
- inner style/even odd row
- inner style/cell
- inner style order
Настройки по умолчанию
Для многих матриц нужно делать однообразные настройки
node{ какой-то текст и };
поэтому определим три макроса:
- /tikz/execute at begin cell=⟨code⟩ — перед текстом
- /tikz/execute at end cell=⟨code⟩ — послетекста
- /tikz/execute at empty cell=⟨code⟩ — если пусто
\begin{tikzpicture}
[matrix of nodes/.style={
execute at begin cell=\node\bgroup,
execute at end cell=\egroup;%
}]
\matrix [matrix of nodes]
{
8 & 1 & 6 \\
3 & 5 & 7 \\
4 & 9 & 2 \\
};
\end{tikzpicture}
или так
\begin{tikzpicture}
[matrix of nodes/.style={
execute at begin cell=\node\bgroup,
execute at end cell=\egroup;,%
execute at empty cell=\node{--};%
}]
\matrix [matrix of nodes]
{
8 & 1 & \\
3 & & 7 \\
& & 2 \\
};
\end{tikzpicture}
https://tikz.dev/library-matrix
Якоря Matrix
matrix anchor=⟨anchor⟩
этот параметр применяется только к самой матрице, но не применяется к ячейкам
т.е. все north, south, east, west
\matrix [matrix anchor=west] at (0,0) поместит левую сторону матрицы в координату (0,0)
отличается от параметра [anchor=west] — который выравнивает в ячейках по левому краю
anchor=⟨anchor or node.anchor⟩
относится только к ячейке
если ячейке дали имя, то можно обращаться к ее якорям node.anchor
\begin{tikzpicture}
\draw[help lines] (0,0) grid (3,2);
\matrix[matrix anchor=inner node.south,anchor=base,row sep=3mm] at (1,1)
{
\node {a}; & \node {b}; & \node {c}; & \node {d}; \\
\node {a}; & \node(inner node) {b}; & \node {c}; & \node {d}; \\
\node {a}; & \node {b}; & \node {c}; & \node {d}; \\
};
\draw (inner node.south) circle (1pt);
\end{tikzpicture}

кратко по примеру выше:
- во второй строчке node дали имя
inner node - в опциях matrix дали команду
[matrix anchor=inner node.south, ... at (1,1), т.е. сказали, что точку юга этой ноды поместить в координату (1,1) anchor=base— колонки выравнивать по центру
Замена & как разделителя колонок
ampersand replacement=⟨macro name or empty⟩
для некоторых процедур это нужно,чтобы не было конфликта с другими библиотеками. Если матрицу закручивать по контуру, то придется поменять разделитель на другое.
\matrix [ampersand replacement=\&]
Matrix Library
без нее эта тема не закончена
\usetikzlibrary{matrix}
matrix of nodes
это матрица в которой каждая ячейка это node
\usetikzlibrary {matrix}
\begin{tikzpicture}
\matrix (magic) [matrix of nodes]
{
8 & 1 & 6 \\
3 & 5 & 7 \\
4 & 9 & 2 \\
};
\draw[thick,red,->] (magic-1-1) |- (magic-2-3);
\end{tikzpicture}
мы такую уже делали сами, но она объявлена в библиотеке, нужно просто сослаться в заголовке
добавить свои опции вариант 1
указать колонку и строку в заголовке и назначить свой стиль
\begin{tikzpicture}[row 2 column 3/.style=red]
\matrix [matrix of nodes]
добавить опции непосредственно ячейке вариант 2
\usetikzlibrary {matrix}
\begin{tikzpicture}
\matrix [matrix of nodes]
{
8 & 1 & 6 \\
3 & 5 & |[red]| 7 \\
4 & 9 & 2 \\
};
\end{tikzpicture}
для этого нужно поместить между вертикальных линий все данные |[red] (seven)|, как здесь передаем цвет и имя ноды
у & есть необязательный аргумент [3mm] — это расстояние между колонками
8 &[1cm] 1 &[3mm] |[red]| 6 \\
вариант 3 — указать полный список параметров
3 & 5 & \node[red]{7}; \draw(0,0) circle(10pt);\\
matrix of math nodes
все ячейки становятся заключены в $
nodes in empty cells=⟨true or false⟩
обязывает отображать пустые ячейки
\usetikzlibrary {matrix}
\begin{tikzpicture}
\matrix [matrix of math nodes,nodes={circle,draw},nodes in empty cells]
{
a_8 & & a_6 \\
a_3 & & a_7 \\
a_4 & a_9 & \\
};
\end{tikzpicture}

Символы конца строк и переноса строк в узлах
обычно это \\
чтобы в ячейке переносить по строкам, нужно поместить текст в {}
\usetikzlibrary {matrix}
\begin{tikzpicture}
\matrix [matrix of nodes,nodes={text width=16mm,draw}]
{
row 1 & {upper line \\ lower line} \\
row 2 & hmm \\
};
\end{tikzpicture}
Разделители в матрицах
- left delimiter=⟨delimiter⟩
- right delimiter=⟨delimiter⟩
- every delimiter
- every left delimiter
- every right delimiter
- above delimiter
- every above delimiter
- below delimiter=⟨delimiter⟩
- every below delimiter
\usetikzlibrary {matrix}
\begin{tikzpicture}
\matrix [matrix of math nodes,%
left delimiter=\|,right delimiter=\rmoustache,%
above delimiter=(,below delimiter=\}]
{
a_8 & a_1 & a_6 \\
a_3 & a_5 & a_7 \\
a_4 & a_9 & a_2 \\
};
\end{tikzpicture}

7.7.6 - PIC маленький рисунок
Синтаксис PIC
\path … pic ⟨foreach statements⟩ [⟨options⟩] (⟨prefix⟩) at(⟨coordinate⟩) :⟨animation attribute⟩={⟨options⟩} {⟨pic type⟩} …;
- PIC можно объявить в
\tikzsetв преамбуле - можно написать прямо в path в опции code
\tikzset{
seagull/.pic={
% Code for a "seagull". Do you see it?...
\draw (-3mm,0) to [bend left] (0,0) to [bend left] (3mm,0);
}
}
Вообще PIC это упрощенная запись вставки кода в path.
во втором случае напишем через pic type =:
\tikz {
\path (0,0) pic [pic type = seagull]
(1,0) pic {seagull};
}
- Или в третьем случае через
pics/code={}:
\tikz \pic [pics/code={\draw (-3mm,0) to[bend left] (0,0)
to[bend left] (3mm,0);}]
{}; % no pic type specified
но в последнем варианте, pic не будет, а будет чистый code, который и делает сам pic
pic action
позволяет в опцияхк команде pic передать дополнительные параметры.
\tikzset{
my pic/.pic = {
\path [pic actions] (0,0) circle[radius=3mm];
\draw (-3mm,-3mm) rectangle (3mm,3mm);
}
}
\tikz \pic {my pic}; \space
\tikz \pic [red] {my pic}; \space
\tikz \pic [draw] {my pic}; \space
\tikz \pic [draw=red] {my pic}; \space
\tikz \pic [draw, shading=ball] {my pic}; \space
\tikz \pic [fill=red!50] {my pic};
behind path и in front of path
также как и node позволяет рисовать за основным рисунком или перед ним
foreground code=⟨code⟩ и background code=⟨code⟩
можно указать индекс слоя
foreach
принимает параметры от foreach
\tikz \pic foreach \x in {1,2,3} at (\x,0) {seagull};
every pic
настраиваем стили для pic
\begin{tikzpicture}[every pic/.style={scale=2,transform shape}]
\pic foreach \x in {1,2,3} at (\x,0) {seagull};
\end{tikzpicture}
prefix name
я не уверен,что буду этим пользоваться, но можно добавлять префиксы к именам точек pic
pic text
будет работать как label в nodes
или его аналог в библиотеке quotes
pic [draw, "$\alpha$"] {angle};
every pic quotes — для настройки кавычек
глобальный стиль для pic
\tikzset{
pics/my circle/.style = {
background code = { \fill circle [radius=#1]; }
}
}
\tikz [fill=blue!30]
\draw (0,0) pic {my circle=2mm} -- (1,1) pic {my circle=5mm};
7.7.7 - Node TIKZ
Синтаксис NODE
\path … node ⟨foreach statements⟩ [⟨options⟩] (⟨name⟩) at(⟨coordinate⟩) :⟨animation attribute⟩={⟨options⟩} {⟨node contents⟩} …;
node contents
это тоже, что и в фигурных скобках.
\tikz {
\path (0,0) node [red] {A}
(1,0) node [blue] {B}
(2,0) node [green, node contents=C]
(3,0) node [node contents=D] ;
}
at
Node размещается в последней координате path, а at указывает конкретно куда поместить node.
\node at (0,0) {сюда}
behind path
нарисует сзади текущего рисунка.
\tikz \fill [fill=blue!50, draw=blue, very thick] (0,0) node [behind path, fill=red!50] {first node}
in front of path
тоже, что и выше, только нарисует спереди текущего рисунка
name
задает имя node, полезно для якорей и координат
можно задать alias и есть еще режим also, позволяет под этим же именем node разместить другой текст
coordinate
\path … coordinate[⟨options⟩](⟨name⟩)at(⟨coordinate⟩) …;
специальный синтаксис для легковесных node
это будет просто точка и все якоря будут иметь одно и тоже значение.
\coordinate — простая запись
\path[shape=coordinate]
(0,0) coordinate(b1)
(1,0) coordinate(b2)
(1,1) coordinate(b3)
(0,1) coordinate(b4);
OPTIONS
Опции для node отличаются от назначений path, поэтому для node нужно давать свои назначения в опциях.
Для рисования вокруг node используем библиотеку \usetikzlibrary {shapes.geometric}
https://tikz.dev/library-shapes
в ней много разных shapes, которые можно указывать в options
По умолчанию без библиотек в node можно применять 3 вида shapes:
- rectangle
- circle
- coordinate
foreach
в node можно вставлять несколько foreach
\tikz \node foreach \x in {1,...,4} foreach \y in {1,2,3}
[draw] at (\x,\y) {\x,\y};

every node
устанавливает стиль для каждой ноды
\begin{tikzpicture}[every node/.style={draw}]
или
\begin{tikzpicture}
[every rectangle node/.style={draw},
every circle node/.style={draw,double}]
\draw (0,0) node[rectangle] {A} -- (1,1) node[circle] {B};
\end{tikzpicture}
для каждой прямоугольной node или для каждой круглой node
execute at begin node (end node)
\begin{tikzpicture}
[execute at begin node={A},
execute at end node={D}]
\node[execute at begin node={B}] {C};
\end{tikzpicture}
На выходе даст ABCD
name prefix=⟨text⟩
Используется в scope и добавляет префикс к имени node
\tikz {
\begin{scope}[name prefix = top-]
\node (A) at (0,1) {A};
\node (B) at (1,1) {B};
\draw (A) -- (B);
\end{scope}
\begin{scope}[name prefix = bottom-]
\node (A) at (0,0) {A};
\node (B) at (1,0) {B};
\draw (A) -- (B);
\end{scope}
\draw [red] (top-A) -- (bottom-B);
}
ее брат name suffix=⟨text⟩ добавит суффикс в конце имени
inner sep=⟨dimension⟩
внутренний отступ от текста к рамке
inner xsep=⟨dimension⟩
margin по x
inner ysep=⟨dimension⟩
margin по y
outer sep=⟨dimension or “auto”⟩
эффект этой опции позволит сместить все якоря вовне
outer sep=auto
outer xsep=⟨dimension⟩
outer ysep=⟨dimension⟩
minimum height=⟨dimension⟩
минимальная высота node
если текст не вместится,то node расширится
minimum width=⟨dimension⟩
минимальная ширина node
minimum size=⟨dimension⟩
для квадратных и круглых форм
shape aspect=⟨aspect ratio⟩
пропорции сжатия
shape border uses incircle=⟨boolean⟩
проверяет,чтобы внутрь фигуры вписывалась окружность
shape border rotate=⟨angle⟩
поворачивает контур фигуры, но не поворачивает текст
\nodepart[⟨options⟩]{⟨part name⟩}
это node состоящая из нескольких частей
\usetikzlibrary {shapes.multipart}
\begin{tikzpicture}
\node [circle split,draw,double,fill=red!20]
{
% No \nodepart has been used, yet. So, the following is put in the
% ``text'' node part by default.
$q_1$
\nodepart{lower} % Ok, end ``text'' part, start ``output'' part
$00$
}; % output part ended.
\end{tikzpicture}

для ее использования нужно применить circle split и в \nodeparts указать аргументы {text,lower}.
для нее же можно настроить стиль:
every ⟨part name⟩ node part
\usetikzlibrary {shapes.multipart}
\tikz [every lower node part/.style={red}]
\node [circle split,draw] {$q_1$ \nodepart{lower} $00$};
NODE TEXT
text=color
задает цвет текста
node font=⟨font commands⟩
\draw[node font=\itshape] — задает шрифт в node
или font=⟨font commands⟩ если задать внутри node
\begin{tikzpicture}
\node [font=\itshape] {italic};
\end{tikzpicture}
align
- center
- left
- right
- align=flush left
- align=flush right — выравнивает без переноса слов
- align=fkush center
- align=justify
- align=none
\tikz[align=center] \node[draw] {This is a\\demonstration.};
text width=⟨dimension⟩
задает ширину текстового поля в node
text height=⟨dimension⟩
высоту текстового блока
text depth=⟨dimension⟩
глубина текста
badness warnings for centered text=⟨true or false⟩
система координат NODE

south тоже есть
anchor=⟨anchor name⟩
anchor= — по умолчанию это центр node, но можно задать любую координату и относительно ее будет идти привязка
относительные надписи
- above=⟨offset⟩
- below=⟨offset⟩
- left=⟨offset⟩
- right=⟨offset⟩
- above left
- above right
- below left
- below right
- centered
\tikz \fill (0,0) circle (2pt) node[above=2pt] {above};
библиотека positioning
\usetikzlibrary{positioning}
дает все тоже самое,но можно еще вычислять расстояния
\node at (1,1) [above=2pt+3pt,draw]
плюс у нее есть команда of
\usetikzlibrary {positioning}
\begin{tikzpicture}[every node/.style=draw]
\draw[help lines] (0,0) grid (2,2);
\node (somenode) at (1,1) {some node};
\node [above=5mm of somenode.north east] {\tiny 5mm of somenode.north east};
\node [above=1cm of somenode.north] {\tiny 1cm of somenode.north};
\end{tikzpicture}
of укажет относительно чего смещение
on grig
смещает node по сетке, а не относительно бордюра node
\usetikzlibrary {positioning}
\begin{tikzpicture}[every node/.style=draw]
\draw[help lines] (0,0) grid (2,3);
% Not gridded
\node (a1) at (0,0) {not gridded};
\node (b1) [above=1cm of a1] {fooy};
\node (c1) [above=1cm of b1] {a};
% gridded
\node (a2) at (2,0) {gridded};
\node (b2) [on grid,above=1cm of a2] {fooy};
\node (c2) [on grid,above=1cm of b2] {a};
\end{tikzpicture}

смещает без on grid относительно бордюра node
с on grid смещает четко по сетке grid
node distance=⟨shifting part⟩
\begin{tikzpicture}[every node/.style=draw,node distance=5mm]
теперь все смещения будут на 5мм
Очень показательно как работает этот ключ
\usetikzlibrary {positioning}
\begin{tikzpicture}[every node/.style={draw,node distance=0mm}]
\draw[help lines] (0,0) grid (2,3);
% Not gridded
\node (a1) at (0,0) {not gridded};
\node (b1) [above=of a1] {fooy};
\node (c1) [above=of b1] {a};
% gridded
\node (a2) at (2,0) {gridded};
\node (b2) [on grid,above=of a2] {fooy};
\node (c2) [on grid,above=of b2] {a};
\end{tikzpicture}

node distance=0mm — показало смещение для on grid по центрам, а без grid от бордюра.
еще есть вариант [node distance=1 and 1]
К вышеперечисленной серии команд в библиотеке еще есть
- base left=⟨specification⟩
- base right
- mid left
- mid right
библиотека matrix и graphdrawing
о них отдельно
лучше позиционируют большие массивы node
fitting node
т.е. подгонка координат
\usetikzlibrary {fit,shapes.geometric}
\begin{tikzpicture}[level distance=8mm]
\node (root) {root}
child { node (a) {a} }
child { node (b) {b}
child { node (d) {d} }
child { node (e) {e} } }
child { node (c) {c} };
\node[draw=red,inner sep=0pt,thick,ellipse,fit=(root) (b) (d) (e)] {};
\node[draw=blue,inner sep=0pt,thick,ellipse,fit=(b) (c) (e)] {};
\end{tikzpicture}
библиотека fit и опция fit позволяет охватить место,чтобы в него могли войти нужные данные

Transformations
transform shape
\tikz[scale=3] \node[transform shape] {X};
т.е. я сначала сказал, что нужно сделать scale=3, а потом команда transform shape выполнит это действие и я получу гигантскую X.
причем сказать можно в path или draw, а команда выполнится в node
\usepgfmodule {nonlineartransformations}\usetikzlibrary {curvilinear}
модули и библиотеки для трансформаций
transform shape nonlinear=⟨true or false⟩
будет рисовать по криволинейным траекториям подробнее https://tikz.dev/tikz-shapes
pos
указывает явно координату, где разместить node в path
\tikz \draw (0,0) -- (3,1)
node[pos=0]{0} node[pos=0.5]{1/2} node[pos=0.9]{9/10};

pos получает значение от 0 до 1 по длине пути
auto=⟨direction⟩
направление может быть left или right в зависимости от этого будет выбираться якорь в node для соединения
swap
если установлена опция auto то будет делать наоборот, для left будет искать right якорь
' — апостроф отработает как swap
sloped
будет писать текст вдоль кривой
можно добавить [allow upside down] или [rotate=180]
node[midway,sloped,below] {$y$};
allow upside down=⟨boolean⟩
перевернет надпись вверх ногами
midway имена точек в пути
- midway — напишет посередине линии
- near start — pos=0.25.
- near end — pos=0.75.
- very near start — pos=0.125.
- very near end — pos=0.875.
- at start — pos=0.
- at end — pos=1
label
это такая надпись в надписи
\usetikzlibrary {positioning}
\tikz [circle] {
\node [draw] (s) [label=below:$s$] {ф};
\node [draw] (a) [right=of s] {} edge (s);
\node [draw] (b) [right=of a] {} edge (a);
\node [draw] (t) [right=of b, label=$t$] {} edge (b);
}

направление метки словами left, right, below, above или градусы и двоеточие:
label=[⟨options⟩]⟨angle⟩:⟨text⟩ или \node [draw] (s) [label=100:$s$] {ф};
\tikz
\node [circle, draw,
label=default,
label=60:$60^\circ$,
label=below:$-90^\circ$,
label=3:$3^\circ$,
label=2:$2^\circ$,
label={[below]180:$180^\circ$},
label={[centered]135:$135^\circ$}] {my circle};
label distance=⟨distance⟩
установит дистанцию для label от меток
every label
настроит стиль для label
PIN
булавка — похожа на label, но с булавкой)
pin distance=⟨distance⟩
расстояние до текста в булавке
every pin
стиль булавки
pin position=⟨angle⟩
аналогично label position
every pin edge
настроит вид edge для pin
pin={[pin edge={blue,thick}]right:X},
Кавычки
Нужна библиотека \usetikzlibrary{quotes}
\usetikzlibrary {quotes}
\begin{tikzpicture}
\matrix [row sep=5mm] {
\node [draw, "label"] {A}; \\
\node [draw, "label" left] {B}; \\
\node [draw, "label" centered] {C}; \\
\node [draw, "label" color=red] {D}; \\
\node [draw, "label" {red,draw,thick}] {E}; \\
};
\end{tikzpicture}
текст в кавычках становится обычным label
quotes mean label
\usetikzlibrary {quotes}
\tikz
\node ["90:$90^\circ$", "left:$180^\circ$", circle, draw] {circle};
every label quotes
задать стиль
quotes mean pin
Connecting Nodes
Соединение Nodes
\begin{tikzpicture}
\path (0,0) node (x) {Hello World!}
(3,1) node[circle,draw](y) {$\int_1^2 x \mathrm d x$};
\draw[->,blue] (x) -- (y);
\draw[->,red] (x) -| node[near start,below] {label} (y);
\draw[->,orange] (x) .. controls +(up:1cm) and +(left:1cm) .. node[above,sloped] {label} (y);
\end{tikzpicture}
При соединении nodes стрелки будут проходить от границы node
EDGES
это ребро, которое будет добавлено после того, как будет нарисован основной путь.
\path … edge[⟨options⟩] ⟨nodes⟩ (⟨coordinate⟩) …;
\begin{tikzpicture}
\node foreach \name/\angle in {a/0,b/90,c/180,d/270}
(\name) at (\angle:1) {$\name$};
\path[->] (b) edge (a)
edge (c)
edge [-,dotted] (d)
(c) edge (a)
edge (d)
(d) edge (a);
\end{tikzpicture}

edge — это просто ребра между координатами.
Внутри edge можно вставлять node
every edge
назначить стиль для всех edge
quotes
для edge в библиотеке quotes также работает текст в кавычках, как label
\usetikzlibrary {quotes}
\tikz \draw (0,0) edge ["left", ->] (2,0);
every edge quotes
Стиль quotes
swap
к тексту с кавычками добавить '
расстояние между label и edge
определяется параметром inner sep=
\usetikzlibrary {quotes}
\tikz [tight/.style={inner sep=1pt}, loose/.style={inner sep=.7em}]
\draw (0,0) edge ["left" tight,
"right"' loose,
"start" near start] (4,0);
Ссылка на узлы за пределами текущего изображения
Это означает,что можно ссылаться из одной картинки в другую картинку на странице.
remember picture=⟨boolean⟩
этот параметр нужно назначить картинкам, которые будут друг на друга ссылаться
\tikzset{every picture/.append style={remember picture}}
этот стиль для всех картинок сразу.
overlay
эту опцию необходимо указать в свойствах path, которые будут ссылаться на другие изображения.
Да, я это видел и я это сделал. Все соединились стрелочками.
\tikz[remember picture] \node[circle,fill=red!50] (n1) {}; — это кружок в любом месте текста.
\tikz[remember picture] \node[fill=blue!50] (n2) {}; — это квадратик, в другом месте.
\begin{tikzpicture}[remember picture,overlay]
\draw[->,very thick] (n1) -- (n2);
\end{tikzpicture}
а это линия,которая соединит кружок с квадратиком

все так и произошло.
\begin{tikzpicture}[remember picture]
\node (c) [circle,draw] {Big circle};
\draw [overlay,->,very thick,red,opacity=.5]
(c) to[bend left] (n1) (n1) -| (n2);
\end{tikzpicture}
Это красная линия с еще более сложным маршрутом.
Абсолютные координаты страницы
на каждой странице присутствует node — current page и у нее есть полный набор ancher: west,east,north,south,center…
для размещения в любом месте страницы нужно в свойствах указать:
\begin{tikzpicture}[remember picture,overlay]
Поздний код
\path … node also[⟨late options⟩](⟨name⟩) …; — добавляет опции к узлу позже.
Обязательно нужно указать имя node и не должно быть указано текста. Только опции.
\begin{tikzpicture}
\node [draw,circle] (a) {Hello};
\node also [label=above:world] (a);
\end{tikzpicture}
\tikzlastnode
этот макрос подобен командам append after command и prefix after command
late options=⟨options⟩
это еще один аналог node also
\begin{tikzpicture}
\node [draw,circle] (a) {Hello};
\path [late options={name=a, label=above:world}];
\end{tikzpicture}
7.7.8 - Path и его особенности
Вступление с моими открытиями
\begin{tikzpicture}
\begin{scope}%делаю специальнуюзону видимости для CLIP
\fill[black!20](-6,0) circle (1.6);%немного фона вокруг кружка
\clip (-6,0) circle (1.5cm);%клипаю будущий рисунок
\node (p) at (-6,0) {\includegraphics[width=3.5cm]{lamp}%вставляю рисунок
\rule{15pt}{0pt}};%так я придумал делать отступ от рисунка невидимой rule
\end{scope}
\gridnum %это просто разметка координат в моем нехитром исполнении, покажу позже
\node[text width=12cm,anchor=north west] at (p.north east) {Для проведения теста, подайте рабочее напряжение на вход ...};%это собственно текстовый блок, который выровнялся по правому верхнему углу рисунка и левому верхнему углу текста
%anchor=north west] at (p.north east) - это магия
\end{tikzpicture}

Grid
Grid сделал, чтобы удобно было рисовать и не разу не пожалел.
Кидаешь рисунок в координату и дальше расставляешь свои фичи.
%%%%%%%%%%%%%%%%%%%%%%%%% GRID
\def\gridnum {
\draw[help lines] (-8,-8) grid +(16,16);
\node foreach \x in {-8,-7,...,8} at (\x,8.5) {\x};
\node foreach \y in {-8,-7,...,8} at (8.5,\y) {\y};
\node foreach \x in {-8,-7,...,8} at (\x,-8.5) {\x};
\node foreach \y in {-8,-7,...,8} at (-8.5,\y) {\y};
\draw[red] (0,-8.5) -- (0,8.5);
\draw[red] (-8.5,0) -- (8.5,0);
}
Кружки со стрелками
\tikzset{
num/.style={draw,shape=circle,fill=black,text=white,minimum size=2em,font=\bf,general shadow={fill=gray,shadow scale=1.1}},%определяет стиль кружка для отметки на рисунках
numtext/.style={draw,shape=circle,fill=black!85,text=white,minimum size=1em,font=\bf,general shadow={fill=gray,shadow scale=1.1}},%определяет стиль кружка для отметки в тексте
arrow num/.style={line width=.1em, gray,arrows = {-Stealth[line width=0.3pt, fill=gray, length=10pt,open,fill=gray,white,quick]}},%определяет стиль стрелки для отметки на рисунках
}
А это сами кружки
\def\numar#1#2#3{
\node [num] (l#1) at (#2) {#1};
\coordinate (t#1) at (#3);
\draw[line width=.15em, white] (l#1) -- ($(l#1)!.95!(t#1)$);
\draw[arrow num] (l#1) -- (t#1);
%рисует черный кружок с цифрой #1 кружок в координате #2, а стрелочку в координату #3
}
А это результат все вместе:
\begin{tikzpicture}
\begin{scope}%это клипнутый рисунок
\fill[black!20](-6,0) circle (1.6);
\clip (-6,0) circle (1.5cm);
\node (p) at (-6,0) {\includegraphics[width=3.5cm]{lamp}\rule{15pt}{0pt}};
\end{scope}
\gridnum % это мой грид
\numar{2}{0,-4}{-2.2,-1.8};%это кружок с 2 и со стрелкой
\numar{2}{0,-4}{2.2,-1.8};%из двойки вторая стрелка
\node at (-4,0){\num{1}};%это кружок без стрелки
\node at ( 4,0){\num{1}};
\end{tikzpicture}

Path
Мощная примудрость, позволит на многое открыть глаза в TIKZ
\begin{tikzpicture}
\gridnum
\begin{scope}[scale=2] %сделал, чтобы видно лучше было
\draw[thick,red]
(0,0) coordinate (a) %назначаем координате имя (a)
-- coordinate (ab) %а это пока рисуем от (a) к (b) запоминаем середину и называем ее (ab)
(1,.5) coordinate (b) %назначаем координате имя (b)
.. coordinate (bc) controls +(up:1.5cm) and +(left:0cm) .. %а это пока рисуем от (b) к (c) запоминаем середину и называем ее (bc)
%но считает серидину сложно с учетом контрольных точек
(3,1) coordinate (c) %назначаем координате имя (c)
(0,1) -- (2,1) -- %просто рисуем замкнутый треугольник и
coordinate (x) (1,2) -- cycle;%x - будет точно серединой между двух вершин
\draw (a) node[below] {start part 1} %ничего интересного, просто подписать точки
(ab) node[below right] {straight segment}
(b) node[right] {end first segment}
(c) node[right] {end part 1}
(x) node[above right] {part 2 (closed)};
\fill[red](a) circle (1pt); %а это просто эти точки разукрасить
\fill[blue](b) circle (1pt);
\fill[green](ab) circle (1pt);
\fill[yellow](bc) circle (1pt);
\fill[magenta](c) circle (1pt);
\fill[orange](x) circle (1pt);
\end{scope}
\end{tikzpicture}

[rounded corners] [sharp corners]
круглые и угловатые соединения линий
rounded corners=4pt — по умолчанию, или можно поменять
\tikz \draw (0,0) -- (1,1) [rounded corners] -- (2,0) -- (3,1) [sharp corners] -- (3,0) -- (2,1);
это группировка scope для назначения стиля
\tikz \draw (0,0) -- (1,1) {[rounded corners] -- (2,0) -- (3,1)} -- (3,0) -- (2,1);
name=
задает имя пути, полезно при пересечениях
every path
задает стиль всем значениям path
\begin{tikzpicture}
[fill=yellow!80!black, % only sets the color
every path/.style={draw}] % all paths are drawn
\fill (0,0) rectangle +(1,1); %все будут с конуром
\shade (2,0) rectangle +(1,1);%и градиент тоже
\end{tikzpicture}

insert path
по пути основного пути вставит любой другой путь))))
\tikz [c/.style={insert path={circle[radius=2pt]}}] \draw (0,0) -- (1,1) [c] -- (3,2) [c];
append after command=
и его брат prefix after command=〈path〉
\tikz \draw node [append after command={(foo)--(1,1) (foo)--(2,1) (foo)--(3,1)},draw] (foo){foo};
Т.е. пока рисую draw, включаю node и обвожу ее [draw], а в параметрах command задаю лучики, сколько угодно.

cycle & current subpath start
cycle — замыкает контур
current subpath start — возвращается в исходную координату, но контур не замыкает
\useasboundingbox (0,2.5); % увеличивает отступ в картинке
– |- -| .. controls ..
тип линии которую нужно провести
-- — прямая
|- — вертикально, потом горизонтально или cycle
.. controls .. — контрольная точка 1 или 2
circle
begin{tikzpicture}
\draw (1,0) circle [radius=1.5];
\fill (1,0) circle [x radius=1cm, y radius=5mm, rotate=30];
\end{tikzpicture}
ellipse
\begin{tikzpicture}
\draw [help lines] (0,0) grid (3,2);
\draw (1,1) ellipse [x radius=1cm,y radius=.5cm];
\end{tikzpicture}
arc
/tikz/start angle=〈degrees〉
/tikz/end angle=〈degrees〉
/tikz/delta angle=〈degrees〉
grid
\tikz[rotate=30] \draw[step=1mm] (0,0) grid (2,2);
/tikz/step=〈number or dimension or coordinate〉
/tikz/xstep=〈dimension or number〉
/tikz/ystep=〈dimension or number〉
/tikz/help lines
parabola
\path ... parabola[〈options〉]bend〈bend coordinate〉〈coordinate or cycle〉 ...;
/tikz/bend=〈coordinate〉
/tikz/bend pos=〈fraction〉
/tikz/parabola height=〈dimension〉
/tikz/bend at start
/tikz/bend at end
sin & cos
\path ... sin〈coordinate or cycle〉 ...;
svg
\path ... svg[〈options〉]{〈path data〉} ...;
\usetikzlibrary {svg.path}
\begin{tikzpicture}
\filldraw [fill=red!20] (0,1) svg[scale=2] {h 10 v 10 h -10} node [above left] {upper left} -- cycle;
\draw svg {M 0 0 L 20 20 h 10 a 10 10 0 0 0 -20 0};
\end{tikzpicture}
И кульминация!!!
\usetikzlibrary {svg.path}
\begin{tikzpicture}
\draw[fill=red] svg[rotate=180,scale=1pt] {m 0,0 c -7.1455,-3.0005 -14.1485,-6.184 -6.261,-17.3275 l 0.7006,-8.7994 -2.2838,-2.151 c 6.7935,-23.5259 19.2799,-46.8506 29.895,-65.918 11.1032,-15.0145 24.2647,-28.7189 28.7623,-47.9367 l 11.9841,-34.99407 c -0.1546,-13.35578 -2.0371,-27.40362 3.835,-38.34918 l 6.2318,-9.82699 c 1.5939,-28.91141 13.1608,-53.72504 12.7031,-82.211751 11.2272,-29.04903 17.5024,-22.60743 25.1668,-26.1256 4.524,-1.40654 8.693,-3.38055 10.0668,-9.827 l 4.554,2.1571 c -3.5888,-15.13669 -2.1459,-27.75767 1.9176,-39.06851 1.3477,-6.40097 7.8536,-8.21675 14.8602,-9.58722 8.592,-2.16346 14.2134,1.61359 20.3733,4.31421 3.564,5.54462 6.8227,11.17624 5.9921,17.97645 -0.088,2.44508 -1.4805,0.80239 -1.7797,2.90917 -0.6305,4.43879 2.7321,11.60579 -0.8615,12.55824 -4.4315,1.17434 -0.8057,12.46002 -5.2394,13.07901 -11.4427,1.59752 -8.2461,7.35191 -11.8607,9.9434 -2.2929,3.4139 -3.7804,7.09455 0.088,11.12472 7.8121,8.29041 7.5135,18.05557 8.6284,27.563671 5.5774,16.1437 10.1453,32.62388 26.8446,45.06055 8.8021,6.70563 14.713,14.56771 20.3734,22.53013 l 11.0253,11.26537 c 9.1625,0.81664 11.8325,3.66246 10.7858,7.6699 5.2654,7.69444 0.9194,8.78118 -3.835,9.58721 l -19.4145,0.23948 c -6.3528,-2.57118 -8.2777,-6.80263 -9.5872,-11.26507 -4.7804,-8.04729 -11.2793,-15.52136 -19.8938,-22.29065 -18.0192,-7.5638 -23.762,-19.73159 -32.1176,-30.91936 l -1.6779,37.15119 c 1.1413,7.46498 1.8943,15.70567 2.3969,24.44775 6.3573,7.86785 13.5455,15.45832 14.381,25.16679 l 14.6207,50.57336 c 5.1154,14.4625 1.2032,22.1542 -0.9588,31.1588 l -16.0588,44.3416 c -4.5409,19.7879 5.1463,25.3556 -1.6827,26.5005 1.2122,4.1548 5.7941,11.5294 10.791,15.6839 l 16.538,5.5128 c 5.8814,5.4882 4.5425,8.71988 0.2395,11.02528 -10.2823,0.03 -20.4991,0.7699 -31.3983,-5.99208 -24.5966,2.299 -20.5907,-1.8606 -27.3242,-3.5952 -6.3237,-9.1034 0.046,-19.8628 2.075,-24.194 l -6.8033,2.9522 c 2.2535,-29.9275 11.2296,-63.866 17.911,-84.9381 l 4.0747,-4.3145 c -2.5708,-2.0158 -5.4922,-2.5127 -6.2318,-12.4634 -4.9405,-15.5883 -14.1539,-28.3278 -22.7699,-41.4653 -16.0976,16.02 -27.5888,36.6464 -36.6716,59.6813 -3.0305,7.3616 -8.3362,10.1725 -13.1827,13.9017 -11.4324,16.4468 -20.5631,46.1767 -29.4813,66.3954 l -3.5952,-1.2016 c -2.918,8.9664 1.9352,10.8095 6.4716,12.9432 l 8.6284,4.7935 c 5.8839,5.6301 4.5728,8.9879 -1.6778,10.7858 -9.743,4.25658 -18.0911,2.2347 -26.6049,0.9588 -3.7097,-3.4521 -7.4534,-6.8618 -13.6619,-7.1907 z};
\end{tikzpicture}

plot
- –plot[〈local options〉]coordinates{〈coordinate 1〉〈coordinate 2〉…〈coordinate n〉}
- –plot[〈local options〉]file{〈filename〉} 342
- –plot[〈local options〉]〈coordinate expression〉
- –plot[〈local options〉]function{〈gnuplot formula〉}
строит график по координатам
\tikz \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)};
to path
(a) to (b) примерно тоже, что (a) – (b), но есть нюансы.
После to я могу передать дополнительные настройки для этого участка пути:
(a) to [out=135,in=45] (b) выйдет из точки (a) под углом 135, а войдет под 45.
или еще 3 замечательных макроса:
\tikztostart, \tikztotarget, и \tikztonodes — запоминают координаты без зацикливания пути: т.е. в режиме current subpath start
\begin{tikzpicture}[to path={
.. controls +(1,0) and +(1,0) .. (\tikztotarget) \tikztonodes}]
\node (a) at (0,0) {a};
\node (b) at (2,1) {b};
\node (c) at (1,2) {c};
\draw (a) to node {x} (b)
(a) to (c);
\end{tikzpicture}
Этот вариант я припас для вертикального написания шрифта
\begin{tikzpicture}
\draw (0,0) to node [sloped,above] {x} (3,2);
\draw (0,0) to[out=90,in=180] node [sloped,above] {x} (3,2);
\draw (0,0) to node[sloped,above] {0001000:000200} (0,5);
\end{tikzpicture}

edge
EDGE умеет делать:
edge node={node [sloped,above] {x}}нодыedge label=xставит меткиedge label=x, edge label'=yставит зеркальные метки
every to
Назначаем стили для всех to
\tikz[every to/.style={bend left}] \draw (0,0) to (3,2); назначает стиль для to
execute at begin to=⟨code⟩ (no default)
и ее брат execute at end to=⟨code⟩ выполняют код до и после начала рисования
FOREACH
Для него посвящу отдельную статью но в кратце:
\tikz \draw (0,0) foreach \x in {1,...,3} { -- (\x,1) -- (\x,0) };
Это цикл по списку.
LET IN
Сначала не хотел разбираться, но потом стало так интересно, а выяснилось, что еще и полезно.
\path … let⟨assignment⟩ ,⟨assignment⟩,⟨assignment⟩… in …;
В let … in можем использовать переменные
- \n1 или \n5 — суть номер регистра, где можно вычислить что нибудь и потом в разделе IN подставить
- \p1,\x1,\y1 — работает с координатами и тоже запоминает в своих регистрах
- \p{name} — тоже, что и \p1,\p3 … только под любым именем.
\usetikzlibrary {calc}
\begin{tikzpicture}
\draw [help lines] (0,0) grid (3,2);
\draw let \p{foo} = (1,1), \p2 = (2,0) in
(0,0) -- (\p2) -- (\p{foo});
\end{tikzpicture}
xshift yshift
оказалась полезная штука для смещения SCOPE и рисовать все в координатах с (0,0)
\pgfextra{⟨code⟩}
сначала хотел выбросить, но появилось время, почитал и тоже понравилось
\newdimen\mydim %назначаем переменную для измерения
\begin{tikzpicture}
\mydim=1cm% присваиваем первое значение
\draw (0pt,\mydim) \pgfextra{\mydim=2cm} -- (0pt,\mydim); изменяем значение и получаем новый результат
\end{tikzpicture}
я думаю использовать при настройке типовых рисунков для передачи им параметров
SOFT USE PATH
это такие ячейки памяти с сохранеными PATH, которые потом можно применять безограничений
\usetikzlibrary {intersections}
\begin{tikzpicture}
\path[save path=\pathA,name path=A] (0,1) to [bend left] (1,0);%запоминаю путь pathA
\path[save path=\pathB,name path=B]%запоминаю путь pathB
(0,0) .. controls (.33,.1) and (.66,.9) .. (1,1);
\fill[name intersections={of=A and B}] (intersection-1) circle (1pt);%нахожу пересечения пути (причем пути даже не наприсовал)
\draw[blue][use path=\pathA];%а теперь достаю путь и рисую
\draw[red] [use path=\pathB];
\end{tikzpicture}
действия с path
Это наверно аксиомы с которыми работает path
\draw — аналогично \path[draw]. рисует
\fill — аналогично \path[fill]. заполняет цветом
\filldraw — \path[fill,draw]. рисует и заполняет
\pattern — \path[pattern]. заполняет маленькими path из библиотеки pattern
\shade — \path[shade]. градиент
\shadedraw — \path[shade,draw]. рисует и заполняет градиентом
\clip — \path[clip]. клипит
\useasboundingbox — \path[use as bounding box] связывает до и после
опции
color=— покрасит в цветомline width=— толщина линииline cap=— round, rect, butt — завершение линииline join=— тип соединения линии round, bevel, mitermiter limit=— определяет остроту угла соединенияdash pattern— чередуются on 2pt off 3pt on 4pt off 4pt и получаем свой пунктирdash phase=— первоначальный сдвиг паттернаdash=— совмещает pattern и phase \draw [dash=on 20pt off 10pt phase 10pt]dash expand offрастягивает на сколько может dash, т.е. линия будет нужной длины и без разрывов
\usetikzlibrary {decorations}
\begin{tikzpicture}[|-|, dash pattern=on 4pt off 2pt]
\draw [dash expand off] (0pt,30pt) -- (26pt,30pt);
\draw [dash expand off] (0pt,20pt) -- (24pt,20pt);
\draw [dash expand off] (0pt,10pt) -- (22pt,10pt);
\draw [dash expand off] (0pt, 0pt) -- (20pt, 0pt);
\begin{scope}[xshift=2cm]
\draw (0pt,30pt) -- (26pt,30pt);
\draw (0pt,20pt) -- (24pt,20pt);
\draw (0pt,10pt) -- (22pt,10pt);
\draw (0pt, 0pt) -- (20pt, 0pt);
\end{scope}
\end{tikzpicture}

solid— сплошная прямая- dotted
- densely dotted
- loosely dotted
- dashed
- densely dashed
- loosely dashed
- dash dot
- densely dash dot
- loosely dash dot
- dash dot dot
- densely dash dot dot
- loosely dash dot dot
draw opacity
работает для всего и draw и fill и svg
double
double=<color>— нарисует двойную линию и закрасит цветомdouble distance=⟨dimension⟩— расстояние между линиямиdouble distance between line centers=⟨dimension⟩— расстояние между центрами линийdouble equal sign distance— удвоит расстояние знака
\Huge $==>\implies$\tikz[baseline,double equal sign distance]
\draw[double,thick,-{Implies[]}](0,0.55ex) --++(3ex,0);

рисуем стрелу
\usetikzlibrary {arrows.meta,bending} — это нам пригодится
\usetikzlibrary {arrows.meta,bending}
\tikz \draw[tips, -{Latex[open,length=10pt,bend]}] (0,0) to[bend left] (1,0);

pattern
\usetikzlibrary {patterns}
\begin{tikzpicture}
\draw[pattern=dots] (0,0) circle (1cm);
\draw[pattern=fivepointed stars] (0,0) rectangle (3,1);
\end{tikzpicture}

в библиотеке их много и лучше смотреть библиотеку https://tikz.dev/library-patterns#section-library-patterns
- pattern color — покрасит в нужный цвет
nonzero rule
исключит из пересечения фигур
\begin{tikzpicture}
\filldraw[fill=yellow!80!black]
% Clockwise rectangle
(0,0) -- (0,1) -- (1,1) -- (1,0) -- cycle
% Counter-clockwise rectangle
(0.25,0.25) -- (0.75,0.25) -- (0.75,0.75) -- (0.25,0.75) -- cycle;
\draw[->] (0,1) -- (.4,1);
\draw[->] (0.75,0.75) -- (0.3,.75);
\draw[->] (0.5,0.5) -- +(0,1) node[above] {crossings: $-1+1 = 0$};
\begin{scope}[yshift=-3cm]
\filldraw[fill=yellow!80!black]
% Clockwise rectangle
(0,0) -- (0,1) -- (1,1) -- (1,0) -- cycle
% Clockwise rectangle
(0.25,0.25) -- (0.25,0.75) -- (0.75,0.75) -- (0.75,0.25) -- cycle;
\draw[->] (0,1) -- (.4,1);
\draw[->] (0.25,0.75) -- (0.4,.75);
\draw[->] (0.5,0.5) -- +(0,1) node[above] {crossings: $1+1 = 2$};
\end{scope}
\end{tikzpicture}

сразу не понял, но если внутри рисунок против шерсти,то вырезает пустоту. Смотрим на стрелочки внутреннего квадрата.
even odd rule
просто вырежет внутренний паттерн
pattern picture
Идея данной функции, добавить внутрь объекта другой объект, ограниченный первым.
причем родительский объект будет иметь имя box с метками по сторонам света.
\begin{tikzpicture}
\draw [help lines] (0,0) grid (3,2);
\filldraw [fill=blue!10,draw=blue,thick] (1.5,1) circle (1)% нарисую круг
[path picture={
\node at (path picture bounding box.center) {%вставлю в круг надпись в центр круга
This is a long text.
};}
];
\end{tikzpicture}
также path picture может быть \draw, \fill, \node, \pattern
Shade
Градиент
у него есть настройки
\tikz \shadedraw [shading=axis] (0,0) rectangle (1,1);
\tikz \shadedraw [shading=radial] (0,0) rectangle (1,1);
\tikz \shadedraw [shading=ball,ball color=red] (0,0) circle (.5cm);
\tikz \shadedraw [shading=ball,ball color=blue] (0,0) circle (.5cm);
\tikz \shadedraw [shading=ball,ball color=green] (0,0) circle (.5cm);

bilinear interpolation
это красивые градиентные заливки объектов по 4-м углам
\usepgflibrary {shadings}
\tikz
\shade[upper left=red,upper right=green,
lower left=blue,lower right=yellow]
(0,0) rectangle (3,2);
\tikz \shade[shading=color wheel] (0,0) circle (1.5);
\tikz \shade[shading=color wheel] [even odd rule]
(0,0) circle (1.5)
(0,0) circle (1);
- color wheel
- color wheel black center
- color wheel white center
- inner color= % радиальная заливка
- outer color= %радиальная заливка

use as bounding box
графически привязывает блоки слева и справа Наверно будет удобно для создания различных перекрестных указателей или еще чего-нибудь, где важно, чтобы блоки склеились в единое целое
У них есть подпараметры:
- trim left=⟨dimension or coordinate or default⟩
- trim right=⟨dimension or coordinate or default⟩
- trim lowlevel=true|false

clip
вырезает все на скорую руку
лучше использовать внутри рисунков с применением группировки scope
\begin{tikzpicture}
\draw (0,0) -- ( 0:1cm);
\draw (0,0) -- (10:1cm);
\draw (0,0) -- (20:1cm);
\draw (0,0) -- (30:1cm);
\begin{scope}[fill=red]
\fill[clip] (0.2,0.2) rectangle (0.5,0.5);
\draw (0,0) -- (40:1cm);
\draw (0,0) -- (50:1cm);
\draw (0,0) -- (60:1cm);
\end{scope}
\draw (0,0) -- (70:1cm);
\draw (0,0) -- (80:1cm);
\draw (0,0) -- (90:1cm);
\end{tikzpicture}

preaction
Я раньше использовал подобное для рисование стрелок с подложкой белого фона.
Оказалось, что все уже придумано до нас))
\begin{tikzpicture}
\draw[help lines] (0,0) grid (3,2);
\draw
[preaction={draw,line width=4mm,blue}]%нарисует по координатам draw прямоугольник с толщиной линии 4mm
[line width=2mm,red] (0,0) rectangle (2,2);%нарисует сверху по этим же координатам линию 2mm
\end{tikzpicture}

удобно для выделения контраста и рисования теней
\begin{tikzpicture}
\draw[help lines] (0,0) grid (3,2);
\draw
[preaction={fill=black,opacity=.5,
transform canvas={xshift=1mm,yshift=-1mm}}]
[fill=red] (0,0) rectangle (1,2)
(1,2) circle (5mm);
\end{tikzpicture}

preaction — может быть несколько штук в одном объекте
postaction=⟨options⟩
Это друг preaction, только делает после того как нарисовал основной рисунок
decorations
\usetikzlibrary {decorations.pathmorphing,shadows}
\begin{tikzpicture}
\node [circular drop shadow={shadow scale=1.05},minimum size=3.13cm,
decorate, decoration=zigzag,
fill=blue!20,draw,thick,circle] {Hello!};
\end{tikzpicture}
Целая библиотека различных декораций и линий для рисования объектов.

7.7.9 - Вводные понятия в TIKZ
Подключение TIKZ в документ.
Для подключения TIKZ нужно в преамбуле добавить:
\usepackage{tikz} %подключить пакет
\usetikzlibrary {angles,calc,quotes} %подключить нужные библиотеки
Библиотеки по ходу буду тоже описывать, те, которые мне точно понравились и нужны. Но их очень много.
Чтобы вставить в текст объект TIKZ нужно использовать окружение
\begin{tikzpicture}
...
\end{tikzpicture}
или
\tikz ...
Координаты в TIKZ
Обычные координаты
(X, Y) — разделитель запятая.
Измеряем либо в стандартных единицах TeX (cm, pt). По умолчанию PGF использует сантиметр: X -> вправо, Y -> вверх.
(30:1cm) — полярные координаты. Т.е. от текущей точки на 1см 30 градусов.
Для трехмерных объектов (1,1,1)
Якорные координаты
У каждого объекта есть свои якорные координаты,связанные со сторонами света:
например: first node.north
- north
- south
- east
- west
И их возможные комбинации: node.north west
Относительные координаты
Нужно перед указанием координат поставить ++ и указать относительное смещение ++(1cm,0pt) — вправо на 1см.
Но для этого нужно знать, где сейчас находится курсор.
Как выяснил, команда \node не изменяет текущую координату.
Если использовать один + перед координатами, то перемещение произойдет, но текущая координата не сменится.
(1,0) +(1,0) +(0,1) даст три точки (1,0), (2,0), (1,1).
Специальный синтаксис для PATH
PATH — водит пером по бумаге, но не оставляет следов, если его не попросить специально.
-- — прямая линия
-| — горизонтально + вертикально
|- — вертикально + горизонтально
cycle — вернуться в точку старта
PATH может:
- draw — рисовать линию
- fill — заполнять пространство
- shade — градиент
- clip — вырезать
Так же доступны комбинации с ними.
\path (0,0) rectangle (2ex,1ex); % ничего визуального не произойдет
\path[draw] (0,0) rectangle (2ex,1ex); % появится рамка
\path[fill=black] (0,0) rectangle (2ex,1ex); % появится черный прямоугольник
Для этих случаев есть сокращенные команды:
\path[draw]=\draw\path[fill]=\fill\path[fill,draw]=\filldraw\path[shade]=\shade\path[shade,draw]=\shadedraw\path[clip]=\clip\path[clip,draw]=\draw[clip]
Вставка текста
Текст добавляем с помощью команды \node прямо в синтаксис \path
\tikz \draw (1,1) node {text} -- (2,2);
У node могут быть:
(name) или [name=имя] [другие опции] {текст}
опции node:
- rectangle
- fill
- circle
- draw
- ellipse
и т.д. это то, что будет нарисовано вокруг текста.
Рисуем деревья
Это такая умная \node с поднодиками.
\begin{tikzpicture}
\node {root}
child {node {left}}
child {node {right}
child {node {child}}
child {node {child}}
};
\end{tikzpicture}
Подключаем библиотеку со стрелочками и оформим стили.
FORK — это вилка, которой будем соединять вниз (down),также можно написать up, left, right и от этой стороны будет выходить стрелка.
\usetikzlibrary {arrows.meta,trees}
\begin{tikzpicture}
[edge from parent fork down, sibling distance=15mm, level distance=15mm,
every node/.style={fill=red!30,rounded corners},
edge from parent/.style={red,-{Circle[open]},thick,draw}]
\node {root}
child {node {left}}
child {node {right}
child {node {child}}
child {node {child}}
};
\end{tikzpicture}

И еще с шариками, а grow — покажет куда расти дереву (up,down,left,right или north,south,east,west). Anchor — это куда прицепляться parent и child.
sibling — ширина плечика на одном уровне, level — это расстояние между уровнями.
every node/.style — назначает стиль глобально для всех node без указания класса.
edge — это собственно само ребро или соединение
ball — это еще одна разновидность фигуры, шарик называется.
\begin{tikzpicture}
[parent anchor=east,child anchor=west,grow=east,
sibling distance=15mm, level distance=15mm,
every node/.style={ball color=red,circle,text=white},
edge from parent/.style={draw,dashed,thick,red}]
\node {root}
child {node {left}}
child {node {right}
child {node {child}}
child {node {child}}
};
\end{tikzpicture}

Графы
Нужна своя библиотека graphs
\usetikzlibrary {graphs}
\tikz \graph [grow down, branch left] {
root -> {
left,
2,3 ->{
5,6,7,8 ->{
11,12,13},
9},
right -> {
child,
child} }
};

Тема с графом тоже интересна.
grow — куда растем, указать сторону
branch — в какую сторону ветви раскидать
\usetikzlibrary {graphs.standard}
\tikz \graph [clockwise] { subgraph K_n [n=9] };
Уж очень он мне понравился. Библиотеку обязательно отдельно всю опишу.

SCOPE
Это внутреннее окружение для группировки настроек.
Это фактически зона видимости.
\begin{tikzpicture}
\begin{scope}[color=red]
\draw (0mm,10mm) -- (10mm,10mm);
\draw (0mm, 8mm) -- (10mm, 8mm);
\draw (0mm, 6mm) -- (10mm, 6mm);
\end{scope}
\begin{scope}[color=green]
\draw (0mm, 4mm) -- (10mm, 4mm);
\draw (0mm, 2mm) -- (10mm, 2mm);
\draw[color=blue] (0mm, 0mm) -- (10mm, 0mm);
\end{scope}
\end{tikzpicture}

Еще SCOPE умеет
/tikz/name=⟨scope name⟩ /tikz/every scope /tikz/execute at begin scope=⟨code⟩ /tikz/execute at end scope=⟨code⟩
И у нее есть даже библиотека \usetikzlibrary{scopes}
Когда библиотека загружена, то можно просто указать фигурные скобки, без begin/end
А еще становится доступной команда \scoped ⟨animations spec⟩[⟨options⟩]⟨path command⟩
\usetikzlibrary {scopes}
\begin{tikzpicture}
{ [ultra thick]
{ [red]
\draw (0mm,10mm) -- (10mm,10mm);
\draw (0mm,8mm) -- (10mm,8mm);
}
\draw (0mm,6mm) -- (10mm,6mm);
}
{ [green]
\draw (0mm,4mm) -- (10mm,4mm);
\draw (0mm,2mm) -- (10mm,2mm);
\draw[blue] (0mm,0mm) -- (10mm,0mm);
}
\end{tikzpicture}
\usetikzlibrary {backgrounds}
\begin{tikzpicture}
\node [fill=white] at (1,1) {Hello world};
\scoped [on background layer]
\draw (0,0) grid (3,2);
\end{tikzpicture}
Опции
\tikzset
— установит в переменную любую команду для применения в окружении \begin{tikzpicture}
baseline
— еще можно задать с помощью координаты, тоже поймет.
\tikz[baseline=0pt]\draw(0,0)circle(.5ex); — установит смещение от базовой линии. По умолчанию строго по центру.

А вот так перечеркнем слово
\usetikzlibrary {shapes.misc}
Hello
\tikz[baseline=(X.base)]
\node [cross out,draw] (X) {world.};

Назначение своего стиля
my style/.style={draw=red,fill=red!20}
Использование стилей
\begin{tikzpicture}[help lines/.style={blue!50,very thin}]
\draw (0,0) grid +(2,2);
\draw[help lines] (2,0) grid +(2,2);
\end{tikzpicture}
Чтобы добавить настройки к существующему стилю /.append style вместо style
Стили с переменными
\begin{tikzpicture}[outline/.style={draw=#1,thick,fill=#1!50}]
\node [outline=red] at (0,1) {red};
\node [outline=blue] at (0,0) {blue};
\end{tikzpicture}
или задать значение по умолчанию
\begin{tikzpicture}[outline/.style={draw=#1,thick,fill=#1!50},
outline/.default=black]
\node [outline] at (0,1) {default};
\node [outline=blue] at (0,0) {blue};
\end{tikzpicture}
/tikz/execute at begin picture=⟨code⟩
Выполнит код до того как начал рисовать картину
/tikz/execute at end picture=⟨code⟩
Выполнит код после того как нарисовал картину
\usetikzlibrary {backgrounds}
\begin{tikzpicture}[execute at end picture=%
{
\begin{pgfonlayer}{background}
\path[fill=yellow,rounded corners]
(current bounding box.south west) rectangle
(current bounding box.north east);
\end{pgfonlayer}
}]
\node at (0,0) {X};
\node at (2,1) {Y};
\end{tikzpicture}

Нарисовал X и Y, а потом подрисовал фон желтого цвета.
Установка глобального стиля /tikz/every picture
В преамбуле напишем \tikzset{every picture/.style=semithick}
или если несколько значений, то \tikzset{every picture/.style={line width=1pt}}
Библиотека \usetikzlibrary{babel}
Для работы со шрифтами,рекомендуется всегда загружать эту библиотеку.
Specifying Coordinates
Или поговорим о координатах.
([⟨options⟩]⟨coordinate specification⟩)
Три вида координат:
- декартовы
- полярные
- сферические
Явное указание координат и неявное указание.
Декартова система координат CANVAS
/tikz/cs/x=⟨dimension⟩
/tikz/cs/y=⟨dimension⟩
Система координат XYZ
Все тоже, только xyz
\begin{tikzpicture}[->]
\draw (0,0) -- (xyz cs:x=1);
\draw (0,0) -- (xyz cs:y=1);
\draw (0,0) -- (xyz cs:z=1);
\end{tikzpicture}

Система координат canvas polar
/tikz/cs/angle=⟨градусы⟩ — Угол координаты. Угол всегда должен быть указан в градусах.
/tikz/cs/radius=⟨размер) — Расстояние от текущей точки
/tikz/cs/x radius=⟨размер⟩ /tikz/cs/y radius=⟨размер⟩
\tikz \draw (0cm,0cm) -- (30:1cm) -- (60:1cm) -- (90:1cm)
-- (120:1cm) -- (150:1cm) -- (180:1cm);

Специальные слова для указания угла
up, down, left, right, north, south, west, east, north east, north west, south east, south west
Система координат XYZ POLAR
\begin{tikzpicture}[x=1.5cm,y=1cm]%масштаб системы координат
\draw[help lines] (0cm,0cm) grid (3cm,2cm);
\draw (0,0) -- (xyz polar cs:angle=0,radius=1);
\draw (0,0) -- (xyz polar cs:angle=30,radius=1);
\draw (0,0) -- (xyz polar cs:angle=60,radius=1);
\draw (0,0) -- (xyz polar cs:angle=90,radius=1);
\draw (xyz polar cs:angle=0,radius=2)
-- (xyz polar cs:angle=30,radius=2)
-- (xyz polar cs:angle=60,radius=2)
-- (xyz polar cs:angle=90,radius=2);
\end{tikzpicture}
\begin{tikzpicture}[x={(-1cm,0cm)},y={(0cm,-1cm)}] %переворачиваю систему координат
\draw[help lines] (0cm,0cm) grid (3cm,2cm);%рисую сетку
\fill (canvas cs:x=1cm,y=0cm) node[right] {X} circle (2pt);%точка в абсолютных координатах без изменений (черная)
\fill (canvas cs:x=0cm,y=1cm) node[left] {Y} circle (2pt);%точка в абсолютных координатах без изменений (черная)
\fill [color=red] (1,0) node[left]{X'} circle (2pt);%точка в относительных координатах перевернутая (красная)
\fill [color=red] (0,1) node[right]{Y'} circle (2pt);%точка в относительных координатах перевернутая (красная)
\draw [color=red] (0,0) -- (30:1) -- (60:1) -- (90:1)
-- (120:1) -- (150:1) -- (180:1);%рисунок в относительных координатах красный
\end{tikzpicture}

Барицентрические системы координат
barycentric — это координаты по сторонам света north, south, east, west и их комбинации
\begin{tikzpicture}
\coordinate (content) at (90:3cm);
\coordinate (structure) at (210:3cm);
\coordinate (form) at (-30:3cm);
\node [above] at (content) {content oriented};
\node [below left] at (structure) {structure oriented};
\node [below right] at (form) {form oriented};
\draw [thick,gray] (content.south) -- (structure.north east) -- (form.north west) -- cycle;
\small
\node at (barycentric cs:content=0.5,structure=0.1 ,form=1) {PostScript};
\node at (barycentric cs:content=1 ,structure=0 ,form=0.4) {DVI};
\node at (barycentric cs:content=0.5,structure=0.5 ,form=1) {PDF};
\node at (barycentric cs:content=0 ,structure=0.25,form=1) {CSS};
\node at (barycentric cs:content=0.5,structure=1 ,form=0) {XML};
\node at (barycentric cs:content=0.5,structure=1 ,form=0.4) {HTML};
\node at (barycentric cs:content=1 ,structure=0.2 ,form=0.8) {\TeX};
\node at (barycentric cs:content=1 ,structure=0.6 ,form=0.8) {\LaTeX};
\node at (barycentric cs:content=0.8,structure=0.8 ,form=1) {Word};
\node at (barycentric cs:content=1 ,structure=0.05,form=0.05) {ASCII};
\end{tikzpicture}

Для понимания процесса barycentric, каждая координата тянет к себе с определенной силой. Если я поставлю с одинаковой силой, то будет ровно посередине, относительно всех точек.
\node at (barycentric cs:content=1,structure=1 ,form=1) {PostScript}; как на рисунке ниже

Node координатная система
/tikz/cs/name=⟨node name⟩
/tikz/anchor=⟨anchor⟩
\usetikzlibrary {arrows.meta}
\begin{tikzpicture}[node font=\ttfamily]
\node (shape) at (0,2) [draw] {class Shape};
\node (rect) at (-2,0) [draw] {class Rectangle};
\node (circle) at (2,0) [draw] {class Circle};
\node (ellipse) at (6,0) [draw] {class Ellipse};
\draw [color=red](node cs:name=circle,anchor=north) |- (0,1);
\draw [blue] (node cs:name=ellipse,anchor=north) |- (0,1);
\draw [arrows = -{Triangle[open, angle=60:3mm]}]
(node cs:name=rect,anchor=north)
|- (0,1) -| (node cs:name=shape,anchor=south);
\end{tikzpicture}
\usetikzlibrary {arrows.meta} — библиотека для красивых стрелочек
\begin{tikzpicture}[node font=\ttfamily] — назначаем шрифт
Присвоим имена каждой ноде
\node (shape) at (0,2) [draw] {class Shape};
\node (rect) at (-2,0) [draw] {class Rectangle};
\node (circle) at (2,0) [draw] {class Circle};
\node (ellipse) at (6,0) [draw] {class Ellipse};
Нарисуем первую линию красного цвета
\draw [color=red](node cs:name=circle,anchor=north) |- (0,1);

Нарисуем вторую линию синего цвета
\draw [blue] (node cs:name=ellipse,anchor=north) |- (0,1);

Нарисуем стрелку черногго цвета
\draw [arrows = -{Triangle[open, angle=60:3mm]}]
(node cs:name=rect,anchor=north)
|- (0,1) -| (node cs:name=shape,anchor=south);

А эта штука соединяет между собой две ноды по бордюру самым коротким путем: (node cs:name=a) -- (node cs:name=b), т.е. все, что в круглых скобках — это координаты.
\usetikzlibrary {shapes.geometric}
\begin{tikzpicture}
\path (0,0) node(a) [ellipse,rotate=10,draw] {An ellipse}
(3,-1) node(b) [circle,draw] {A circle};
\draw[thick] (node cs:name=a) -- (node cs:name=b);
\end{tikzpicture}
А это легкая замена rectangle, чтобы не пересекалось
\tikz \draw (0,0) node(x) [draw] {Text}
% rectangle (1,1)
(node cs:name=x) -- +(0,1) -- +(1,1) -- +(1,0) -- (node cs:name=x)
(node cs:name=x) -- +(1,1)
(node cs:name=x) -- +(1,.5)
(node cs:name=x) -- +(.5,1)
;

Для те, кто в танке, чтобы не забыть: +(координаты) — не изменяет точку отсчета и указывает относительную координату; ++(координаты) — изменяет точку отсчета и указывает относительные координаты; (координаты) — изменяет точку отсчета и указывает абсолютные координаты.
\begin{tikzpicture}
\draw[blue!20] (0,0) grid +(2,2);
\draw (0,0) node(x) [draw] {Text}
(node cs:name=x) -- ++(0,1) -- ++(1,1) -- +(1,0) -- (node cs:name=x);
\end{tikzpicture}

\usetikzlibrary {shapes.geometric}
\begin{tikzpicture}[fill=blue!20]
\draw[help lines] (-1,-2) grid (6,3);
\path (0,0) node(a) [ellipse,rotate=10,draw,fill] {An ellipse}
(3,-1) node(b) [circle,draw,fill] {A circle}
(2,2) node(c) [rectangle,rotate=20,draw,fill] {A rectangle}
(5,2) node(d) [rectangle,rotate=-30,draw,fill] {Another rectangle};
\draw[thick] (a.south) -- (b) -- (c) -- (d);
\draw[thick,red,->] (a) |- +(1,3) -| (c) |- (b);
\draw[thick,blue,<->] (b) .. controls +(right:2cm) and +(down:1cm) .. (d);
\end{tikzpicture}

Что здесь примечательного?
- Все ноды рисуются в один присест, просто перечисляем через слово
nodeи вначале подставляем координаты. - Линии рисуем отдельными командами через
\draw
Координатная система TANGENT
Работает только с загруженной библиотекой CALC
Нарисует по касательной от точки (a):
- tangent — система координат
- cs: — сами координаты
- node=c — фигура
- point={(a)} — точка, от которой пойдет касательная
- solution=1 — номер решения, если их несколько
\usetikzlibrary {calc}
\begin{tikzpicture}
\draw[help lines] (0,0) grid (3,2);
\coordinate (a) at (3,2);
\node [circle,draw] (c) at (1,1) [minimum size=40pt] {$c$};
\draw[red] (a) -- (tangent cs:node=c,point={(a)},solution=1) --
(c.center) -- (tangent cs:node=c,point={(a)},solution=2) -- cycle;
\end{tikzpicture}

Создание собственной системы координат
Требует отдельного изучения, если вдруг понадобится
Или создать alias существующей системекоординат
\tikzaliascoordinatesystem{⟨new name⟩}{⟨old name⟩}
https://tikz.dev/tikz-coordinates#sec-13.2.5
Координаты точек пересечения
Библиотека \usetikzlibrary{intersections}
/tikz/name path=⟨name⟩ — задать имя path для поиска пересечения
/tikz/name path global=⟨name⟩ — задает имя path глобально,будет доступно за пределами окружения SCOPE в рисунке
/tikz/name intersections={⟨options⟩} — поиск точек пересечения путей path
Если несколько точек пересечения им будут заданы координаты intersections-1 и intersections-2 и т.д. сколько получится.
\usetikzlibrary {intersections}
\begin{tikzpicture}[every node/.style={opacity=1, black, above left}]%стиль node подписи в лево вверх
\draw [help lines] grid (3,2);%нарисуем grid
\draw [name path=ellipse] (2,0.5) ellipse (0.75cm and 1cm);%нарисуем элипс и имя path=ellipse
\draw [name path=rectangle, rotate=10] (0.5,0.5) rectangle +(2,1);%нарисуем прямоугольник и имя path=rectangle
\fill [red, opacity=0.5, name intersections={of=ellipse and rectangle}]% найдем точки пересечения двух path
%name intersections --- это команда для поиска пересечений
%of= --- задает path для поиска пересечений
(intersection-1) circle (2pt) node {1}%нарисовать точку в пересечении 1
(intersection-2) circle (2pt) node {2};%нарисовать точку в пересечении 2
\end{tikzpicture}

Ключи intersections
of=
name intersections={of=ellipse and rectangle} — задает имена path для поиска пересечений
name=
выдаст имена точек пересечения, какие заданы в name
\fill [red, opacity=0.5, name intersections={of=ellipse and rectangle,name=insec}]
(insec-1) circle (2pt) node {1}
(insec-2) circle (2pt) node {2};
total=⟨macro⟩
Создает список всех точек пересечения и сохраняет его в макросе tex по номерам 1,2,3 и т.д.
[name intersections={of=curve 1 and curve 2, name=i, total=\t}] — сохранит в макросе \t
by={a,b}
присвоит каждой точке свое имя a и b
\fill [name intersections={of=curve 1 and curve 2, by={a,b}}]
(a) circle (2pt)
(b) circle (2pt);
Еще можно использовать нотацию ... подставит имена автоматически
[name intersections={
of=curve 1 and curve 2,
by={[label=center:a],[label=center:...],[label=center:i]}}]
Относительные и инкрементальные координаты
Это мои любимые + и ++
Дают одинаковый вариант:
++ изменяет текущую координату и премещается относительно
+ не изменяет текущую координату и перемещается относительно
\begin{tikzpicture}
\draw (0,0) -- ++(1,0) -- ++(0,1) -- ++(-1,0) -- cycle;
\draw (2,0) -- ++(1,0) -- ++(0,1) -- ++(-1,0) -- cycle;
\draw (1.5,1.5) -- ++(1,0) -- ++(0,1) -- ++(-1,0) -- cycle;
\end{tikzpicture}
\begin{tikzpicture}
\draw (0,0) -- +(1,0) -- +(1,1) -- +(0,1) -- cycle;
\draw (2,0) -- +(1,0) -- +(1,1) -- +(0,1) -- cycle;
\draw (1.5,1.5) -- +(1,0) -- +(1,1) -- +(0,1) -- cycle;
\end{tikzpicture}

Ключевое слово TURN
\tikz \draw (0,0) -- (1,1) -- ([turn]-45:1cm) -- ([turn]-30:1cm);
Поворачивает ось координат по касательной к последней точке.
\begin{tikzpicture} [delta angle=-180, radius=1cm]
\draw [help lines] (0,0) grid (10,5);
\draw (0,3) arc [start angle=-180] -- ([turn]60:1cm)
arc [start angle=-180] -- ([turn]60:1cm)
arc [start angle=180] -- ([turn]60:1cm);
\end{tikzpicture}

До меня дошло, когда нарисовал сетку координат
[delta angle=-180, radius=1cm] — параметры дуги: ее угол и радиус, минус говорит, что рисуем по часовой стрелке
[start angle=-180] — собственно стартовый угол дуги, относительно системы координат — здесь -180 и +180 роли не играет, но -90 и +90 развернут дугу в разные стороны.
– ([turn]60:1cm) — эта штука нарисует отрезок из последней точки но в системе координат именно последней точки. Т.е. 60 градусов она развернет относительно мысленного продолжения arc по касательной.
[current point is local]
Укажет, что внутри фигурных скобок была относительная координата и после выхода из скобок, система координат будет как была до нее.
\begin{tikzpicture}
\draw (0,0) -- ++(1,0) -- ++(0,1) -- ++(-1,0);
\draw[red] (2,0) -- ++(1,0)
{ [current point is local] -- ++(0,1) } -- ++(-1,0);
\end{tikzpicture}
Вычисляемые координаты
Вся мощь библиотеки CALC в расчете координат
($(a) + 1/3*(1cm,0)$) — вот так берем и изменяем координаты. Не забываем поставить эту конструкцию в $.
([⟨options⟩]$⟨coordinate computation⟩$)
— синтаксис
\usetikzlibrary {calc}
\begin{tikzpicture}
\draw [help lines] (0,0) grid (3,2);
\fill [red] ($2*(1,1)$) circle (2pt);
\fill [green] (${1+1}*(1,.5)$) circle (2pt);
\fill [blue] ($cos(0)*sin(90)*(1,1)$) circle (2pt);
\fill [black] (${3*(4-3)}*(1,0.5)$) circle (2pt);
\end{tikzpicture}
Это возможные операции над координатами. Координаты всегда имеют структуру (x,y) и умножение будет происходить над x и y по отдельности.
⟨coordinate⟩!⟨number⟩!⟨angle⟩:⟨second coordinate⟩
(1,2)!.75!(3,4) — это значит, что координата будет на .75 между точками (1,2) и (3,4)
\usetikzlibrary {calc}
\begin{tikzpicture}
\draw [help lines] (0,0) grid (3,2);
\draw (1,0) -- (3,2);
\foreach \i in {0,0.2,0.5,0.9,1}
\node at ($(1,0)!\i!(3,2)$) {\i};
\end{tikzpicture}

\usetikzlibrary {calc}
\begin{tikzpicture}
\draw [help lines] (0,0) grid (3,3);
\coordinate (a) at (1,0);
\coordinate (b) at (3,2);
\draw[->] (a) -- (b);
\coordinate (c) at ($ (a)!1! 10:(b) $); % от точки (a) длина !1! --- такая же как (ab) и повернуть на 10 градусов.
\draw[->,red] (a) -- (c);
\fill ($ (a)!.5! 10:(b) $) circle (2pt); % а здесь точку нарисуем
\end{tikzpicture}
Змея для примера
\usetikzlibrary {calc}
\begin{tikzpicture}
\draw [help lines] (0,0) grid (4,4);
\foreach \i in {0,0.125,...,2}
\fill ($(2,2) !\i! \i*180:(3,2)$) circle (2pt);
\end{tikzpicture}

Модифаеры могут быть по нескольку штук дляг за другом
\usetikzlibrary {calc}
\begin{tikzpicture}
\draw [help lines] (0,0) grid (3,2);
\draw (0,0) -- (3,2);
\draw[red] ($(0,0)!.3!(3,2)$) -- (3,0);
\fill[red] ($(0,0)!.3!(3,2)!.7!(3,0)$) circle (2pt); %как здесь. Нашли точку на одной прямой и о нее ищем на другой.
\end{tikzpicture}
⟨coordinate⟩!⟨dimension⟩!⟨angle⟩:⟨second coordinate⟩
т.е. эта штука вычислит все в миллиметрах и расставит метки по прямой
\usetikzlibrary {calc}
\begin{tikzpicture}
\draw [help lines] (0,0) grid (3,2);
\draw (1,0) -- (3,2);
\foreach \i in {0cm,1cm,15mm}
\node at ($(1,0)!\i!(3,2)$) {\i};
\end{tikzpicture}
А эта будет ставить измерения
\usetikzlibrary {calc}
\begin{tikzpicture}
\draw [help lines] (0,0) grid (3,2);
\coordinate (a) at (1,0);
\coordinate (b) at (3,1);
\draw (a) -- (b);%нарисуем прямую ab
\coordinate (c) at ($ (a)!.25!(b) $);%найдем точку c
\coordinate (d) at ($ (c)!1cm!90:(b) $);%найдем точку d 90град от cb
\draw [<->] (c) -- (d) node [sloped,midway,above] {1cm};% начертим стрелочки и напишем 1 cm
\end{tikzpicture}

⟨coordinate⟩!⟨projection coordinate⟩!⟨angle⟩:⟨second coordinate⟩
модификаторы проекции
Нарисуем треугольник и опустим перпендикуляры от вершин на противоположные стороны
между !()! укажем вершину в скобках
\usetikzlibrary {calc}
\begin{tikzpicture}
\draw [help lines] (0,0) grid (3,2);
\coordinate (a) at (0,1);
\coordinate (b) at (3,2);
\coordinate (c) at (2.5,0);
\draw (a) -- (b) -- (c) -- cycle;
\draw[red] (a) -- ($(b)!(a)!(c)$);%от a на сторону bc
\draw[orange] (b) -- ($(a)!(b)!(c)$);%от b на сторону ac
\draw[blue] (c) -- ($(a)!(c)!(b)$);%от c на сторону ab
\end{tikzpicture}

Перпендикуляры
Основные команды это:
- /tikz/cs/horizontal line through={(⟨coordinate⟩)}
- /tikz/cs/vertical line through={(⟨coordinate⟩)}
задают вертикальную и горизонтальные линии, но в основном используется синтаксис:
(⟨p⟩ |- ⟨q⟩) или (⟨q⟩ -| ⟨p⟩).
Для примера: (2,1 |- 3,4) и (3,4 -| 2,1) дадут точку (2,4)
\begin{tikzpicture}
\path (30:1cm) node(p1) {$p_1$} (75:1cm) node(p2) {$p_2$};
\draw (-0.2,0) -- (1.2,0) node(xline)[right] {$q_1$};
\draw (2,-0.2) -- (2,1.2) node(yline)[above] {$q_2$};
\draw[->] (p1) -- (p1 |- xline);
\draw[->] (p2) -- (p2 |- xline);
\draw[->] (p1) -- (p1 -| yline);
\draw[->] (p2) -- (p2 -| yline);
\end{tikzpicture}

или такой
\usetikzlibrary {calc}
\begin{tikzpicture}
\node (A) at (0,1) {A};
\node (B) at (1,1.5) {B};
\node (C) at (2,0) {C};
\node (D) at (2.5,-2) {D};
\draw (A) -- (B) node [midway] {x};
\draw (C) -- (D) node [midway] {x};
\node at ({$(A)!.5!(B)$} -| {$(C)!.5!(D)$}) {X};
\end{tikzpicture}
от одной средней точки возьмем координату X от другой Y и напишем метку X.

7.7.10 - Диаграммы в Latex библиотека TIKZ
Возможности библиотеки TIKZ для рисования графиков в Latex. Обзор учебника из документации.
Библиотеки для работы с диаграммами
\usetikzlibrary {
positioning,% нативные позиции node
shapes.misc, % настройка внешнего вида фигур, углы и т.д.
graphs, % работает с диаграммами и графами
calc, % считает координаты
arrows.meta % рисует наконечники стрел
}
Стилизация узлов диаграммы
Простой прямоугольник (Не-Терминал)
\usetikzlibrary {positioning}
\begin{tikzpicture}[
nonterminal/.style={
% The shape:
rectangle,
% The size:
minimum size=6mm,
% The border:
very thick,
draw=red!50!black!50, % 50% red and 50% black,
% and that mixed with 50% white
% The filling:
top color=white, % a shading that is white at the top...
bottom color=red!50!black!20, % and something else at the bottom
% Font
font=\itshape
}]
\node [nonterminal] {unsigned integer};
\end{tikzpicture}
В стиле определил:
- rectangle
- minimum size
- border — красночерного цвета толстый бордюр
- filling — градиент top и bottom
- font
Для рисования просто пишу NODE и все готово 
Стиль терминалов с круглыми углами
\usetikzlibrary {positioning}
\begin{tikzpicture}[node distance=5mm,
terminal/.style={
% The shape:
rectangle,minimum size=6mm,rounded corners=3mm,
% The rest
very thick,draw=black!50,
top color=white,bottom color=black!20,
font=\ttfamily}]
\node (dot) [terminal] {.};
\node (digit) [terminal,right=of dot] {digit};
\node (E) [terminal,right=of digit] {E};
\end{tikzpicture}
Как приятно писать что-то, когда ты понимаешь, что ты это понимаешь)))
В стиле определено:
- node distance — это значит,что расстояние между
nodeбудет, то, которое задано. - terminal — название стиля
- rectangle — форма
- minimum size
- rounded corners — радиус закругления углов (закругляет у любой фигуры \node, \fill, \path)
- very thick — толщина обводки
- top, bottom — градиент заливки
- font
Односимвольный терминал станет кругом, а многосимвольный — прямоугольником с закругленными углами.

Использование библиотеки shapes.misc
Только немного изменится настройка в описании стиля
[node distance=5mm,
terminal/.style={
% The shape:
rounded rectangle,
minimum size=6mm,
% The rest
very thick,draw=black!50,
top color=white,bottom color=black!20,
font=\ttfamily}]
убрали rounded corners а поставили rounded rectangle — собственно и все. Но разметка слегка отъехала. На рисунке можно увидеть небольшую разницу.
Выравнивание текста в терминалах
Просто добавляем в стиль высоту и глубину строки [text height=1.5ex,text depth=.25ex]
Полезная библиотека позиционирования
\usetikzlibrary {positioning,shapes.misc}
\begin{tikzpicture}[node distance=5mm and 5mm]
\node (ui1) [nonterminal] {unsigned integer};
\node (dot) [terminal,right=of ui1] {.};
\node (digit) [terminal,right=of dot] {digit};
\node (E) [terminal,right=of digit] {E};
\node (plus) [terminal,above right=of E] {+};
\node (minus) [terminal,below right=of E] {-};
\node (ui2) [nonterminal,below right=of plus] {unsigned integer};
\end{tikzpicture}
основные команды:
- right=of
- left=of
- above=of
- below=of
- above right=of
- и т.д.
Перенесем настройки стилей в преамбулу документа
\tikzset {terminal/.style={
% The shape:
rectangle,minimum size=6mm,rounded corners=3mm,
% The rest
very thick,draw=black!50,
top color=white,bottom color=black!20,
font=\ttfamily}}
\tikzset {nonterminal/.style={
% The shape:
rectangle,
% The size:
minimum size=6mm,
% The border:
very thick,
draw=red!50!black!50, % 50% red and 50% black,
% and that mixed with 50% white
% The filling:
top color=white, % a shading that is white at the top...
bottom color=red!50!black!20, % and something else at the bottom
% Font
font=\itshape
}}
Теперь будет действовать глобально на всех.
Рисуем стрелки
\usetikzlibrary {calc,positioning,shapes.misc}
\begin{tikzpicture}[node distance=5mm and 5mm,
skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}}]
\node (dot) [terminal] {.};
\node (digit) [terminal,right=of dot] {digit};
\node (E) [terminal,right=of digit] {E};
\path (dot) edge[->] (digit) % simple edges
(digit) edge[->] (E)
($ (digit.east)!.5!(E.west) $)
edge[->,skip loop=-5mm] ($ (digit.west)!.5!(dot.east) $);
\end{tikzpicture}
Разберем кривую стрелку
($ (digit.east)!.5!(E.west) $)
edge[->,skip loop=-5mm] ($ (digit.west)!.5!(dot.east) $);
т.е. от середины между метками (digit.east)!.5!(E.west) до середины между метками (digit.west)!.5!(dot.east) рисуем кривулину типа skip loop

Пока все довольны.
Но разобрать по частям стиль skip loop очень хочется: skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}}
- первая часть понятна: от текущей точке рисуем линию вертикально на заданный параметр
#1, а потом -|— рисует горизонтально, а потом вертикально к цели, это один из родственников--— рисует прямую;|-— рисует вертикально и горизонтально и..— рисует кривую- возвращаемся к поставленной цели
(\tikztotarget)вообще таких макросов три (\tikztostart, \tikztotarget, and \tikztonodes;)
Матрицы
\usetikzlibrary {shapes.misc}
\begin{tikzpicture}
\matrix[row sep=1mm,column sep=5mm] {
% First row:
& & & & \node [terminal] {+}; & \\
% Second row:
\node [nonterminal] {unsigned integer}; &
\node [terminal] {.}; &
\node [terminal] {digit}; &
\node [terminal] {E}; &
&
\node [nonterminal] {unsigned integer}; \\
% Third row:
& & & & \node [terminal] {-}; & \\
};
\end{tikzpicture}
Пока \matrix представляет собой что-то вроде таблицы, со своими дополнениями.
- row sep — расстояние между строками
- column sep — расстояние между столбцами
Дальше обычная tabular.

Промежуточная задача с узлами привязки
\usetikzlibrary {shapes.misc}
\begin{tikzpicture}[point/.style={circle,inner sep=0pt,minimum size=2pt,fill=red},
skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}}]
\matrix[row sep=1mm,column sep=2mm] {
% First row:
& & & & & & & & & & & \node (plus) [terminal] {+};\\
% Second row:
\node (p1) [point] {}; & \node (ui1) [nonterminal] {unsigned integer}; &
\node (p2) [point] {}; & \node (dot) [terminal] {.}; &
\node (p3) [point] {}; & \node (digit) [terminal] {digit}; &
\node (p4) [point] {}; & \node (p5) [point] {}; &
\node (p6) [point] {}; & \node (e) [terminal] {E}; &
\node (p7) [point] {}; & &
\node (p8) [point] {}; & \node (ui2) [nonterminal] {unsigned integer}; &
\node (p9) [point] {}; & \node (p10) [point] {};\\
% Third row:
& & & & & & & & & & & \node (minus)[terminal] {-};\\
};
\path (p4) edge [->,skip loop=-5mm] (p3)
(p2) edge [->,skip loop=5mm] (p6);
\end{tikzpicture}
- Описываем стиль
[point/.style={circle,inner sep=0pt,minimum size=2pt,fill=red}] - Расставляем точки в матрице и даем им имена:
\node (p1) [point] {}; - Соединяем точки
edge—(p4) edge [->,skip loop=-5mm] (p3)
Частично задача решена. Вторым этапом убираем видимость точек и результат готов.
Команда GRAPH (библиотека graphs)
Это еще одна мощная команда, которая должна со всем этим хозяйством управиться.
\begin{tikzpicture}[skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}},
point/.style={circle,inner sep=0pt,minimum size=2pt,fill=red},
hv path/.style={to path={-| (\tikztotarget)}},
vh path/.style={to path={|- (\tikztotarget)}}]
\matrix[row sep=1mm,column sep=2mm] {
% First row:
& & & & & & & & & & & \node (plus) [terminal] {+};\\
% Second row:
\node (p1) [point] {}; & \node (ui1) [nonterminal] {unsigned integer}; &
\node (p2) [point] {}; & \node (dot) [terminal] {.}; &
\node (p3) [point] {}; & \node (digit) [terminal] {digit}; &
\node (p4) [point] {}; & \node (p5) [point] {}; &
\node (p6) [point] {}; & \node (e) [terminal] {E}; &
\node (p7) [point] {}; & &
\node (p8) [point] {}; & \node (ui2) [nonterminal] {unsigned integer}; &
\node (p9) [point] {}; & \node (p10) [point] {};\\
% Third row:
& & & & & & & & & & & \node (minus)[terminal] {-};\\
};
\graph {
(p1) -> (ui1) -- (p2) -> (dot) -- (p3) -> (digit) -- (p4)
-- (p5) -- (p6) -> (e) -- (p7) -- (p8) -> (ui2) -- (p9) -> (p10);
(p4) ->[skip loop=-5mm] (p3);
(p2) ->[skip loop=5mm] (p5);
(p6) ->[skip loop=-11mm] (p9);
(p7) ->[vh path] (plus) -> [hv path] (p8);
(p7) ->[vh path] (minus) -> [hv path] (p8);
};
\end{tikzpicture}

Завершаем оформление и добавляем стрелочки
Библиотека arrows.meta: и вариант работы p7 ->[vh path] { plus, minus } -> [hv path] p8; библиотеки graphs по раздвоению стрелок. Просто перечисляем узлы в фигурных скобках.
Итоговый вариант:
\begin{tikzpicture}[skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}},
point/.style={circle,inner sep=0pt,minimum size=2pt,fill=red},
>={Stealth[round]},thick,black!50,text=black,
every new ->/.style={shorten >=1pt},
graphs/every graph/.style={edges=rounded corners},
hv path/.style={to path={-| (\tikztotarget)}},
vh path/.style={to path={|- (\tikztotarget)}}]
\matrix[column sep=4mm] {
% First row:
& & & & & & & & & & & \node (plus) [terminal] {+};\\
% Second row:
\node (p1) [point] {}; & \node (ui1) [nonterminal] {unsigned integer}; &
\node (p2) [point] {}; & \node (dot) [terminal] {.}; &
\node (p3) [point] {}; & \node (digit) [terminal] {digit}; &
\node (p4) [point] {}; & \node (p5) [point] {}; &
\node (p6) [point] {}; & \node (e) [terminal] {E}; &
\node (p7) [point] {}; & &
\node (p8) [point] {}; & \node (ui2) [nonterminal] {unsigned integer}; &
\node (p9) [point] {}; & \node (p10) [point] {};\\
% Third row:
& & & & & & & & & & & \node (minus)[terminal] {-};\\
};
\graph [use existing nodes] {
p1 -> ui1 -- p2 -> dot -- p3 -> digit -- p4 -- p5 -- p6 -> e -- p7 -- p8 -> ui2 -- p9 -> p10;
p4 ->[skip loop=-5mm] p3;
p2 ->[skip loop=5mm] p5;
p6 ->[skip loop=-11mm] p9;
p7 ->[vh path] { plus, minus } -> [hv path] p8;
};
\end{tikzpicture}

Более серьезное погужение в GRAPHs
\tikz \graph [grow right=2cm] { unsigned integer -> d -> digit -> E };
выдаст сразу: 
Добавим стилей:
\tikz \graph [grow right sep] {
unsigned integer[nonterminal] -> "."[terminal] -> digit[terminal] -> E[terminal]
};

Добавим + и -:
\usetikzlibrary {graphs,shapes.misc}
\tikz \graph [grow right sep] {
unsigned integer [nonterminal] ->
"." [terminal] ->
digit [terminal] ->
E [terminal] ->
{
"+" [terminal],
"" [coordinate],
"-" [terminal]
} ->
ui2/unsigned integer [nonterminal]
};

Окончательный вариант через Graphs
\usetikzlibrary {arrows.meta,graphs,shapes.misc}
\tikz [>={Stealth[round]}, black!50, text=black, thick,
every new ->/.style = {shorten >=1pt},
graphs/every graph/.style = {edges=rounded corners},
skip loop/.style = {to path={-- ++(0,#1) -| (\tikztotarget)}},
hv path/.style = {to path={-| (\tikztotarget)}},
vh path/.style = {to path={|- (\tikztotarget)}},
nonterminal/.style = {
rectangle, minimum size=6mm, very thick, draw=red!50!black!50, top color=white,
bottom color=red!50!black!20, font=\itshape, text height=1.5ex,text depth=.25ex},
terminal/.style = {
rounded rectangle, minimum size=6mm, very thick, draw=black!50, top color=white,
bottom color=black!20, font=\ttfamily, text height=1.5ex, text depth=.25ex},
shape = coordinate
]
\graph [grow right sep, branch down=7mm, simple] {
/ -> unsigned integer[nonterminal] -- p1 -> "." [terminal] -- p2 -> digit[terminal] --
p3 -- p4 -- p5 -> E[terminal] -- q1 ->[vh path]
{[nodes={yshift=7mm}]
"+"[terminal], q2, "-"[terminal]
} -> [hv path]
q3 -- /unsigned integer [nonterminal] -- p6 -> /;
p1 ->[skip loop=5mm] p4;
p3 ->[skip loop=-5mm] p2;
p5 ->[skip loop=-11mm] p6;
q1 -- q2 -- q3; % make these edges plain
};

Особенности кода:
- использовании групп, при делении веток, группы заключаем в
{} - анонимные координаты обозначаются
/ simpe— свойство graph — которое определяем, что между 2-мя узлами может быть только 1edge.graphs/every graph/.style = {edges=rounded corners}— закругленные уголки у стрелок>={Stealth[round]}, black!50, text=black, thick,— стиль стрелок
7.7.11 - Примеры по Эвклиду
Установка необходимых библиотек для работы
\documentclass{article} % say
% For LaTeX:
\usepackage{tikz}
\usetikzlibrary{calc,intersections,through,backgrounds}
\begin{tikzpicture}
\coordinate [label=left:\textcolor{blue}{$A$}] (A) at (0,0);
\coordinate [label=right:\textcolor{blue}{$B$}] (B) at (1.25,0.25);
\draw[blue] (A) -- (B);
\end{tikzpicture}
Мощь библиотеки calc
\begin{tikzpicture}
\coordinate [label=left:\textcolor{blue}{$A$}] (A) at ($ (0,0) + .1*(rand,rand) $);
\coordinate [label=right:\textcolor{red}{$B$}] (B) at ($ (1.25,0.25) + .1*(rand,rand) $);
\draw[blue] (A) -- (B);
\end{tikzpicture}
Все вычисления происходят между двух символов $.
Особенность оператора rand, что он каждый раз будет вычисляться одинаково. Т.е. не такой он уж и случайное число.
Оператор let и команда veclen
\usetikzlibrary {calc}
\begin{tikzpicture}
\coordinate [label=left:$A$] (A) at (0,0);
\coordinate [label=right:$B$] (B) at (1.25,0.25);
\draw (A) -- (B);
\draw (A) let
\p1 = ($ (B) - (A) $)
in
circle ({veclen(\x1,\y1)});
\end{tikzpicture}

\p1 = ($ (B) - (A) $)вычислит длину вектора и запишет в переменную1p— это команда записать точку (коорд.x, коорд.y)veclen(\x1,\y1)— соответственно передать коордитатыxиyиз переменной1и вычислить их длину для радиуса.n— похожа наp, но записывает число.
т.е. let определил p1 и передал in в circle
\usetikzlibrary {calc}
\begin{tikzpicture}
\coordinate [label=left:$A$] (A) at (0,0);
\coordinate [label=right:$B$] (B) at (1.25,0.25);
\draw (A) -- (B);
\draw let \p1 = ($ (B) - (A) $),
\n2 = {veclen(\x1,\y1)}
in
(A) circle (\n2)
(B) circle (\n2);
\end{tikzpicture}
в этом примере, как раз вычисленный радиус, записали в переменную 2. Вместо цифры в этих переменных можно использовать длинные имена в скобках n{ragius} и также их использовать circle (\n{radius})
Библиотека THROUGH
Создадим окружность через точку B относительно A, находящейся в центре координат. Т.е. точку A он всегда будет считать центром.
\usetikzlibrary {through}
\begin{tikzpicture}
\coordinate [label=left:$A$] (A) at (0,0);
\coordinate [label=right:$B$] (B) at (1.25,0.25);
\draw (A) -- (B);
\node [draw,circle through=(B),label=left:$D$] at (A) {};
\end{tikzpicture}

Библиотека INTERSECTION
\usetikzlibrary {intersections,through}
\begin{tikzpicture}
\coordinate [label=left:$A$] (A) at (0,0);
\coordinate [label=right:$B$] (B) at (1.25,0.25);
\draw (A) -- (B);
\node (D) [name path=D,draw,circle through=(B),label=left:$D$] at (A) {}; %нода D и путь D это разные объекты, можно называть по разному
\node (E) [name path=E,draw,circle through=(A),label=right:$E$] at (B) {};
% Name the coordinates, but do not draw anything:
\path [name intersections={of=D and E}];
\coordinate [label=above:$C$] (C) at (intersection-1);
\draw [red] (A) -- (C);
\draw [red] (B) -- (C);
\end{tikzpicture}

\node (D) [name path=D,draw,circle through=(B),label=left:$D$]задаем имя\pathгде проходит окружность.\path [name intersections={of=D and E}];— определяем пересечение двух путей D и E и у них образуются точки пересечения как(intersection-1)и(intersection-2).\coordinate [label=above:$C$] (C) at (intersection-1);— определим точку C с координатами пересечения.
но есть еще у name intersections команда by, которая все это решит автоматически: \path [name intersections={of=D and E, by={[label=above:$C$]C, [label=below:$C'$]C'}}]; т.е. поставит точки и метки в них.
Потом просто проведем линию и дадим ей тоже имя \path — \draw [name path=C--C',red] (C) -- (C'); имя будет C--C'.
Новый intersection получит точку F
\path [name intersections={of=A--B and C--C',by=F}];
\begin{tikzpicture}
\coordinate [label=left:$A$] (A) at (0,0);
\coordinate [label=right:$B$] (B) at (1.25,0.25);
\draw [name path=A--B] (A) -- (B);
\node (D) [name path=D,draw,circle through=(B),label=left:$D$] at (A) {};
\node (E) [name path=E,draw,circle through=(A),label=right:$E$] at (B) {};
\path [name intersections={of=D and E, by={[label=above:$C$]C, [label=below:$C'$]C'}}];
\draw [name path=C--C',red] (C) -- (C');
\path [name intersections={of=A--B and C--C',by=F}];
\node [fill=red,inner sep=2pt,label=-45:$F$] at (F) {};
\end{tikzpicture}
это полная картина, где из нового inner sep=2pt — это толщина точки пересечения, а на самом деле просто размер node в виде точки

если бы я написал \node [fill=red,circle, inner sep=2pt,label=-45:$F$] at (F) {}; то получилось бы:

Разукрашки и определение макросов
\begin{tikzpicture}[
thick,% толстые линии
help lines/.style={thin,draw=black!50}]%вспомогательные линии
\def\A{\textcolor{input}{$A$}} % макросы ABCDE со стилями меток
\def\B{\textcolor{input}{$B$}}
\def\C{\textcolor{output}{$C$}}
\def\D{$D$}
\def\E{$E$}
\colorlet{input}{blue!80!black} % input и output цвета, которые подставятся в макросы
\colorlet{output}{red!70!black}
\colorlet{triangle}{orange}
Наарисуем треугольник
\draw [output] (A) -- (C) -- (B);
Поставим в вершинах точки
\foreach \point in {A,B,C}
\fill [black,opacity=.5] (\point) circle (2pt);
Закрасим треугольник
\begin{pgfonlayer}{background}
\fill[triangle!80] (A) -- (C) -- (B) -- cycle;
\end{pgfonlayer}
Итоговый код
\usetikzlibrary {backgrounds,calc,intersections,through}
\begin{tikzpicture}[thick,help lines/.style={thin,draw=black!50}]
\def\A{\textcolor{input}{$A$}} \def\B{\textcolor{input}{$B$}}
\def\C{\textcolor{output}{$C$}} \def\D{$D$}
\def\E{$E$}
\colorlet{input}{blue!80!black} \colorlet{output}{red!70!black}
\colorlet{triangle}{orange}
\coordinate [label=left:\A] (A) at ($ (0,0) + .1*(rand,rand) $);
\coordinate [label=right:\B] (B) at ($ (1.25,0.25) + .1*(rand,rand) $);
\draw [input] (A) -- (B);
\node [name path=D,help lines,draw,label=left:\D] (D) at (A) [circle through=(B)] {};
\node [name path=E,help lines,draw,label=right:\E] (E) at (B) [circle through=(A)] {};
\path [name intersections={of=D and E,by={[label=above:\C]C}}];
\draw [output] (A) -- (C) -- (B);
\foreach \point in {A,B,C}
\fill [black,opacity=.5] (\point) circle (2pt);
\begin{pgfonlayer}{background}
\fill[triangle!80] (A) -- (C) -- (B) -- cycle;
\end{pgfonlayer}
\node [below right, text width=10cm,align=justify] at (4,3) {
\small\textbf{Proposition I}\par
\emph{To construct an \textcolor{triangle}{equilateral triangle}
on a given \textcolor{input}{finite straight line}.}
\par\vskip1em
Let \A\B\ be the given \textcolor{input}{finite straight line}. \dots
};
\end{tikzpicture}

Мой первый прямоугольник с почти умными координатами
\begin{tikzpicture}
\coordinate (NW) at (0,5); \coordinate (nw) at ($ (NW) + (1,-1) $);
\coordinate (NE) at (7,5); \coordinate (ne) at ($ (NE) + (-1,-1) $);
\coordinate (SE) at (7,0); \coordinate (se) at ($ (SE) + (-1,1) $);
\coordinate (SW) at (0,0); \coordinate (sw) at ($ (SW) + (1,1) $);
\draw[black!10] (NW) -- (NE) -- (SE) -- (SW) -- cycle;
\draw[black!30, thick, fill=black!25] ($ (NW) + (1,-1) $) -- (ne) -- (se) -- (sw) -- cycle;
\fill[black!25] (nw) -- (ne) -- (se) -- (sw) -- cycle;
\end{tikzpicture}

Немного неказист, но многообещающь.
Дальше он будет понемногу обрастать,пока не превратится в то,что я задумал.
Продолжение сериала по Эвклиду.
Найдем точку между координатами
Это будет ровно посередине между A и B.
\usetikzlibrary {calc}
\begin{tikzpicture}
\coordinate [label=left:$A$] (A) at (0,0);
\coordinate [label=right:$B$] (B) at (1.25,0.25);
\draw (A) -- (B);
\node [fill=red,inner sep=1pt,label=below:$X$] (X) at ($ (A)!.5!(B) $) {};
\end{tikzpicture}
Это для убедительности: 
Или за пределами точек и даже сложные вычисления:
\coordinate [label=above:$D$] (D) at ($ (A) ! .5 ! (B) ! {sin(60)*2} ! 90:(B) $) {};
И еще пример, чисто как памятка, потому-что очень сложные вычисления, мне точно не нужны.
\draw (D) -- ($ (D) ! 2.5 ! (A) $) coordinate [label=below:$E$] (E); — начертит прямую и установит новую точку E
7.7.12 - Сети PETRI
NODE и настройки своих стилей.Установка необходимых библиотек для работы
\documentclass{article} % say
\usepackage{tikz}
\usetikzlibrary{arrows.meta,decorations.pathmorphing,backgrounds,positioning,fit,petri}
\begin{document}
\begin{tikzpicture}
\draw (0,0) -- (1,1);
\end{tikzpicture}
\end{document}
NODE и настройки своих стилей.Просто нарисуем в системе координат 5 node
\begin{tikzpicture}
\path ( 0,2) node [shape=circle,draw] {}
( 0,1) node [shape=circle,draw] {}
( 0,0) node [shape=circle,draw] {}
( 1,1) node [shape=rectangle,draw] {}
(-1,1) node [shape=rectangle,draw] {};
\end{tikzpicture}
Но, выяснилось, что вариант выше не очень умен по своей сути. \path задает координату откуда начинается какое-то действие, в нашем случае размещаем node, а можно draw, но node с параметром draw обернет текст рамкой.
Синтаксис at т.е. поместить в…

\begin{tikzpicture}
\path node at ( 0,2) [shape=circle,draw] {}
node at ( 0,1) [shape=circle,draw] {}
node at ( 0,0) [shape=circle,draw] {}
node at ( 1,1) [shape=rectangle,draw] {}
node at (-1,1) [shape=rectangle,draw] {};
\end{tikzpicture}
Получаем тотже эффект, но говорят умнее.
Дальше больше:
\begin{tikzpicture}
\path node at ( 0,2) [circle,draw] {}
node at ( 0,1) [circle,draw] {}
node at ( 0,0) [circle,draw] {}
node at ( 1,1) [rectangle,draw] {}
node at (-1,1) [rectangle,draw] {};
\end{tikzpicture}
Прикручиваем стили
\begin{tikzpicture}[thick]
\path node at ( 0,2) [circle,draw=blue,fill=red] {}
node at ( 0,1) [circle,draw=blue,fill=yellow] {}
node at ( 0,0) [circle,draw=blue,fill=green] {}
node at ( 1,1) [rectangle,draw=black!50,fill=black!20] {}
node at (-1,1) [rectangle,draw=black!50,fill=black!20] {};
\end{tikzpicture}
Причем [draw=blue] — рисует такого цвета обводку, а fill — заполняет пространство
А теперь сделаем стиль универсальным на блок
\begin{tikzpicture}
[place/.style={circle,draw=blue!50,fill=blue!20,thick},
transition/.style={rectangle,draw=black!50,fill=black!20,thick}]
\node at ( 0,2) [place] {};
\node at ( 0,1) [place] {};
\node at ( 0,0) [place] {};
\node at ( 1,1) [transition] {};
\node at (-1,1) [transition] {};
\end{tikzpicture}
просто один будет называться place а второй transition и теперь название этихстилей ставим в описании node.
Размеры SHAPE
Можно задать переменную inner sep=2mm в блоке — и это сделает отступ вокруг текста 2mm. Или:
[place/.style={circle,draw=blue!50,fill=blue!20,thick,
inner sep=0pt,minimum size=6mm},
т.е прямо в стиль и это даст эффект, что размер будет не меньше 4мм, пока в него влезает текст.

Имена SHAPEs
Очень пригодятся имена SHAPEs для того,чтобы иметь привязки и потом на них ссылаться.
\begin{tikzpicture}
\node (waiting 1) at ( 0,2) [place] {};
\node (critical 1) at ( 0,1) [place] {};
\node (semaphore) at ( 0,0) [place] {};
\node (leave critical) at ( 1,1) [transition] {};
\node (enter critical) at (-1,1) [transition] {};
\end{tikzpicture}
имена будут в круглых скобочках, причем порядок написания не имеет значения. Это все определения одного \path
Нативное размещение SHAPEs
Вместо указания координат, можно указывать влево, вправо, ниже, выше. Такого ума можно набраться в библиотеке: \usetikzlibrary {positioning}
\usetikzlibrary {positioning}
\begin{tikzpicture}
\node[place] (waiting) {};
\node[place] (critical) [below=of waiting] {}; % ниже waitinig
\node[place] (semaphore) [below=of critical] {}; % ниже critical
\node[transition] (leave critical) [right=of critical] {}; % справа от critical
\node[transition] (enter critical) [left=of critical] {}; % слева от critical
\end{tikzpicture}
Объекты размещаются по координатной сетке.
Метки объектов по сторонам света
Все объекты TIKZ получают метки по сторонам света:
- north
- south
- west
- east
- north east
- north west
- south east
- south west
\node [red,above] at (semaphore.north) {$s\le 3$};
\end{tikzpicture}
напишет node красного цвета red над above северной меткой объекта semaphore.
но в библиотеке есть вариант с label, который сделает тоже самое.
\node[place] (semaphore) [below=of critical,
label=above:$s\le3$] {};
Памятка, как label работает:
\tikz
\node [circle,draw,label=60:$60^\circ$,label=below:$-90^\circ$] {my circle};

И немного подольем красочки: label={[red]below:$-90^\circ$} и будет метка красная, но чтобы небыло конфлика поставим все это дело в {}.
Коннекторы это просто
\draw [->] (enter critical.east) -- (critical.west);
\draw [->] (waiting.west) .. controls +(left:5mm) and +(up:5mm)
.. (enter critical.north);
т.е. \draw [в какую сторону стрелу] (координата откуда) -- (координата куда);
Краткий комментарий к .. CONTROLS ..
Это вставка вместо оператора рисования - -, которая позволяет поставить несколько контрольных точек относительно некоторого центра вращения и сказать куда они сдвигаются и насколько:
\draw[->](waiting.west) ..controls +(left:15mm) and +(up:15mm) .. (enter critical.north);

Умность библиотеки tirz
Можно не указывать стороны света в метках, от сделает это автоматически
\draw [->] (enter critical) -- (critical);
\draw [->] (waiting) .. controls +(left:5mm) and +(up:5mm)
.. (enter critical);
будет тоже самое.
Совершенствуем стрелочки до предела (to [in out])
Замечательный оператор to, который укажет под каким углом выйти и под каким углом войти стрелке.
Схема такая же, только вместо наших - - и .. controls .. появляется еще один оператор to [out=,in=]
in=220 — выглядит еще причудлевее.
\draw[->](waiting) to [out=0, in=180] (leave critical)

Команда bend right left
изгиб кривой.
\draw[->](leave critical) to [bend left=150] (semaphore)

но лучше загибать bend left=45, правда лучше.
Теперь еще один элемент EDGE
край - ребро, как угодно, но эта штука действует как внутри \path так и самостоятельно. Т.е. можно задавать свои особые наконечники и цвета для edge.
\node[transition] (enter critical) [left=of critical] {}
edge [->] (critical)
edge [<-,bend left=45] (waiting)
edge [->,bend right=45] (semaphore);
буквально: там где нарисовал node от неё начинаю рисовать edges.
- не завершая
nodeточкой с запятой пишемedge - [здесь команды куда стрела, как гнуть]
- (куда соединяем)
- теперь текущая точка опять в пункте
node - продолжаем рисовать дальше от той же точки
Вот такой казус может получиться:
\begin{tikzpicture}
\node (c) at (0,0) {};
\node (n) at (0,1) {}
edge [bend right=45] (w);
\node (s) at (0,-1) {}
edge [bend right=45] (e);
\node (w) at (-1,0) {}
edge [bend right=45] (s);
\node (e) at (1,0) {}
edge [->,bend right=45] (n);
\end{tikzpicture}

Но если рисовать по задумке:
\begin{tikzpicture}
\node (c) at (0,0) {};
\node (n) at (0,1) {};
\node (w) at (-1,0) {}
edge [bend left=45] (n);
\node (s) at (0,-1) {}
edge [bend left=45] (w);
\node (e) at (1,0) {}
edge [bend left=45] (s)
edge [bend right=45] (n);
\end{tikzpicture}
то получим ->

И все это упакуем в стили
[bend angle=45,
pre/.style={<-,shorten <=1pt,>={Stealth[round]},semithick},
post/.style={->,shorten >=1pt,>={Stealth[round]},semithick}]
вот такая штука позволит дальше в коде писать просто:
edge [pre] (critical) и edge [post,bend right] (waiting) и TIKZ все поймет.
Метки на линиях
\begin{tikzpicture}[auto,bend right]
\node (a) at (0:1) {$0^\circ$};
\node (b) at (120:1) {$120^\circ$};
\node (c) at (240:1) {$240^\circ$};
\draw (a) to node {1} node [swap] {1'} (b)
(b) to node {2} node [swap] {2'} (c)
(c) to node {3} node [swap] {3'} (a);
\end{tikzpicture}

- NODE — нарисовали метки в узлах через оператор
at, т.е. поместить в … конкретную точку - DRAW — рисует через оператор
to, т.е. от одной точки к другой, а на пути его рисования мы размещаем другие NODE и говорим с какой стороны их рисовать относительно линии. - SWAP — это нарисовать зеркально
- на пути DRAW, NODEs может быть сколько угодно, главное их всех разместить правильно, а то все в одну точку вляпаются.
Декоративные линии (\usetikzlibrary {decorations.pathmorphing})
Собственно любую линию можно нарисовать, просто отдельно нужно изучить особенности этой библиотеки.
\usetikzlibrary {decorations.pathmorphing}
\begin{tikzpicture}
\draw [->,decorate,
decoration={snake,amplitude=.4mm,segment length=2mm,post length=1mm}]
(0,0) -- (3,0);
\end{tikzpicture}
получится вот такая кривулина: 
И продолжая тему кривулины или любой другой линии, если мне нужно разместить текст, то делаю в разрыве DRAW вставку NODE:
node [above,text width=3cm,align=center,midway]
{
replacement of the \textcolor{red}{capacity} by
\textcolor{red}{two places}
}
- above — выше над линией
- text width=3cm — ширина текста 3см
- align-center — текст выравнять по центру
- midway — в центре линии (у него еще есть братья:
- near start — pos=0.25.
- near end — pos=0.75.
- very near start — pos=0.125.
- very near end — pos=0.875.
- at start — pos=0.
- at end — pos=1
BACKGROUND или слои и фон под картинкой
Нам поможет библиотека fit и background
fit — дает координаты всех узлов
background — размещает на разных слоях рисунки
Еще нам понадобятся знания об окружении SCOPE — это просто окружение чего-то, такие своеобразные скобки, в которых будут действовать правила, которые мы установим, а за пределами SCOPE все возвращается в исходные установки.
\begin{tikzpicture}[ultra thick]
\begin{scope}[red]
\draw (0mm,10mm) -- (10mm,10mm);
\draw (0mm,8mm) -- (10mm,8mm);
\end{scope}
\draw (0mm,6mm) -- (10mm,6mm);
\begin{scope}[green]
\draw (0mm,4mm) -- (10mm,4mm);
\draw (0mm,2mm) -- (10mm,2mm);
\draw[blue] (0mm,0mm) -- (10mm,0mm);
\end{scope}
\end{tikzpicture}
этот пример на линиях все показал

а про background мы просто добавим в конце такой код:
\begin{scope}[on background layer]
\node [fill=black!30,fit=(waiting) (critical) (semaphore)
(leave critical) (enter critical)] {};
\end{scope}
on background layer— на каком слое разместить, т.е. под рисунком\node— рисуем nodefill— заполняем ее цветомfit— перечисляем все внутренние node по которым определяем координаты
Настройки стандартных библиотек для рисования сетей PETRI
\begin{tikzpicture}
[node distance=1.3cm,on grid,>={Stealth[round]},bend angle=45,auto,
every place/.style= {minimum size=6mm,thick,draw=blue!75,fill=blue!20},
every transition/.style={thick,draw=black!75,fill=black!20},
red place/.style= {place,draw=red!75,fill=red!20},
every label/.style= {red}]
т.е. там уже все определено, поэтому нарисуем все, что уже пытались с использованием библиотеки:
\usetikzlibrary {arrows.meta,petri,positioning}
\node [place,tokens=1] (w1) {};
\node [place] (c1) [below=of w1] {};
\node [place] (s) [below=of c1,label=above:$s\le 3$] {};
\node [place] (c2) [below=of s] {};
\node [place,tokens=1] (w2) [below=of c2] {};
\node [transition] (e1) [left=of c1] {}
edge [pre,bend left] (w1)
edge [post,bend right] (s)
edge [post] (c1);
\node [transition] (e2) [left=of c2] {}
edge [pre,bend right] (w2)
edge [post,bend left] (s)
edge [post] (c2);
\node [transition] (l1) [right=of c1] {}
edge [pre] (c1)
edge [pre,bend left] (s)
edge [post,bend right] node[swap] {2} (w1);
\node [transition] (l2) [right=of c2] {}
edge [pre] (c2)
edge [pre,bend right] (s)
edge [post,bend left] node {2} (w2);
а это ее более кудрявый друг:
\usetikzlibrary {arrows.meta,petri,positioning}
\begin{scope}[xshift=6cm]
\node [place,tokens=1] (w1') {};
\node [place] (c1') [below=of w1'] {};
\node [red place] (s1') [below=of c1',xshift=-5mm]
[label=left:$s$] {};
\node [red place,tokens=3] (s2') [below=of c1',xshift=5mm]
[label=right:$\bar s$] {};
\node [place] (c2') [below=of s1',xshift=5mm] {};
\node [place,tokens=1] (w2') [below=of c2'] {};
\node [transition] (e1') [left=of c1'] {}
edge [pre,bend left] (w1')
edge [post] (s1')
edge [pre] (s2')
edge [post] (c1');
\node [transition] (e2') [left=of c2'] {}
edge [pre,bend right] (w2')
edge [post] (s1')
edge [pre] (s2')
edge [post] (c2');
\node [transition] (l1') [right=of c1'] {}
edge [pre] (c1')
edge [pre] (s1')
edge [post] (s2')
edge [post,bend right] node[swap] {2} (w1');
\node [transition] (l2') [right=of c2'] {}
edge [pre] (c2')
edge [pre] (s1')
edge [post] (s2')
edge [post,bend left] node {2} (w2');
\end{scope}
и на финише фон:
\begin{scope}[on background layer]
\node (r1) [fill=black!10,rounded corners,fit=(w1)(w2)(e1)(e2)(l1)(l2)] {};
\node (r2) [fill=black!10,rounded corners,fit=(w1')(w2')(e1')(e2')(l1')(l2')] {};
\end{scope}
\draw [shorten >=1mm,->,thick,decorate,
decoration={snake,amplitude=.4mm,segment length=2mm,
pre=moveto,pre length=1mm,post length=2mm}]
(r1) -- (r2) node [above=1mm,midway,text width=3cm,align=center]
{replacement of the \textcolor{red}{capacity} by \textcolor{red}{two places}};
\end{tikzpicture}
получим такую красоту:

7.7.13 - Графики в TIKZ для Latex
Дружелюбный функционал для полной графики в Latex. Картинки, иконки, графики и пр. Очень мощный пакет в котором можно нарисовать все.
Установка пакета
\usepackage{tikz}
Использование пакета
Окружение {tikzpicture} или команды \tikzpicture и \endtikzpicture

\documentclass{article} % say
\usepackage{tikz}
\begin{document}
We are working on
\begin{tikzpicture}
\draw (-1.5,0) -- (1.5,0);
\draw (0,-1.5) -- (0,1.5);
\end{tikzpicture}.
\end{document}
Нарисует точки в координатах и проведет через них кривую

\begin{tikzpicture}
\filldraw [gray] (0,0) circle [radius=2pt]
(1,1) circle [radius=2pt]
(2,1) circle [radius=2pt]
(2,0) circle [radius=2pt];
\draw (0,0) .. controls (1,1) and (2,1) .. (2,0);
\end{tikzpicture}
Цвет
filldraw [gray] — зальет фигуру серым цветом
Кривые
.. controls — укажет контрольные точки для кривой Безье.
Окружность
circle [radius=10pt] — нарисует окружность
нарисуем эллипс
\tikz \draw (0,0) ellipse [x radius=20pt, y radius=10pt];
Поворот рисунка
\draw[rotate=30] — развернет рисунок на 30гр.
нарисуем квадраты
\draw (0,0) rectangle (0.5,0.5);
\draw (-0.5,-0.5) rectangle (-1,-1);
Нарисуем сетку
\tikz \draw[step=2pt] (0,0) grid (10pt,10pt);
нарисует сетку козявочку 

\begin{tikzpicture}
\draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4);
\draw (-1.5,0) -- (1.5,0);
\draw (0,-1.5) -- (0,1.5);
\draw (0,0) circle [radius=1cm];
\end{tikzpicture}
в draw — определим шаг, цвет и толщину линий
Установим настройку стилей по умолчанию
Глобально в переменной Ra grid
\tikzset{Ra grid/.style={help lines,color=blue!50}}
или локально в переменной Karl's grid

\begin{tikzpicture}
[Karl's grid/.style ={help lines,color=#1!50},
Karl's grid/.default=blue]
\draw[Karl's grid] (0,0) grid (1.5,2);
\draw[Karl's grid=red] (2,0) grid (3.5,2);
\end{tikzpicture}
Толщина линий
- ultra thin
- very thin
- thin
- semithick
- thick
- very thick
- ultra thick
\draw[ultra thin] (-1.5,1.1) -- (1.5,1.1);
\draw[very thin] (-1.5,1.6) -- (1.5,1.6);
\draw[thin] (-1.5,2.1) -- (1.5,2.1);
\draw[semithick] (-1.5,2.6) -- (1.5,2.6);
\draw[very thick] (-1.5,3.1) -- (1.5,3.1);
\draw[ultra thick] (-1.5,3.6) -- (1.5,3.6);

\begin{tikzpicture}[line width=5pt] — любая толщина
Стиль линии
- loosely dashed,
- densely dashed,
- loosely dotted,
- densely dotted
\draw[loosely dashed, ultra thick] (-1.5,-3.6) -- (1.5,-3.6);
\draw[densely dashed, ultra thick] (-1.5,-3.1) -- (1.5,-3.1);
\draw[loosely dotted, ultra thick] (-1.5,-2.6) -- (1.5,-2.6);
\draw[densely dotted, ultra thick] (-1.5,-2.1) -- (1.5,-2.1);

dash pattern — можно определить сложный паттерн
Нарисуем дугу
arc[start angle=10, end angle=80, radius=10pt]
Элипсоидная дуга
\tikz \draw (0,0)
arc [start angle=0, end angle=315,
x radius=1.75cm, y radius=1cm];
Масштабирование
\begin{tikzpicture}[scale=3]
\draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4);
\draw (-1.5,0) -- (1.5,0);
\draw (0,-1.5) -- (0,1.5);
\draw (0,0) circle [radius=1cm];
\draw (3mm,0mm) arc [start angle=0, end angle=30, radius=3mm];
\end{tikzpicture}
после определения окружения, ставим [scale=3]
Клиппинг
или обрезание рисунка
\clip (-0.1,-0.2) rectangle (1.1,0.75);
две точки на рисунке для обрезки прямоугольником, обрезать можно любой фигурой
\begin{tikzpicture}[scale=3]
\clip (-0.1,-0.2) rectangle (1.1,0.75);
\draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4);
\draw (-1.5,0) -- (1.5,0);
\draw (0,-1.5) -- (0,1.5);
\draw (0,0) circle [radius=1cm];
\draw (3mm,0mm) arc [start angle=0, end angle=30, radius=3mm];
\end{tikzpicture}

Основные команды рисования
\path[draw, clip] или \path[clip] или \path[draw] — братья по смыслу и к ним же \draw[clip]
Параболы, синусы и изгибы
% чертит параболу в квадрате
\tikz \draw (0,0) rectangle (1,1) (0,0) parabola (1,1);
% чертит параболу и изгиб, по дороге поменяем размерность координат x и y
\tikz \draw[x=1pt,y=1pt] (0,0) parabola bend (4,16) (6,12);
A sine \tikz \draw[x=1ex,y=1ex] (0,0) sin (1.57,1); curve.
Нарисует прямо в тексте кривулину. A sine (-tikz- diagram) curve.
А вот эта штука покажет, что такое sin и cos на самом деле:
\tikz \draw[x=3.57ex,y=1ex] (0,0) sin (4,1) cos (6,-14) sin (8,12)

да,именно так — sin поднимаемся, cos — опускаемся
Закрасить пространство
\fill[green!20!white] (0,0) -- (3mm,0mm)
arc [start angle=0, end angle=30, radius=3mm] -- (0,0);
% или сразу рисуем и красим
\filldraw[fill=green!20!white, draw=green!50!black] (0,0) -- (3mm,0mm)
arc [start angle=0, end angle=30, radius=3mm] -- cycle;
Замыкание контуров
\begin{tikzpicture}[line width=5pt]
\draw (0,0) -- (1,0) -- (1,1) -- (0,0);
\draw (2,0) -- (3,0) -- (3,1) -- cycle;
\useasboundingbox (0,1.5); % make bounding box higher
\end{tikzpicture}
cycle — плавно замкнет контур, похожа на последнюю команду -- (0,0) но работает лучше
Градиент
Команды shade и shadedraw
\begin{tikzpicture}[rounded corners,ultra thick]
\shade[top color=yellow,bottom color=black] (0,0) rectangle +(2,1);
\shade[left color=yellow,right color=black] (3,0) rectangle +(2,1);
\shadedraw[inner color=yellow,outer color=black,draw=yellow] (6,0) rectangle +(2,1);
\shade[ball color=green] (9,.5) circle (.5cm);
\end{tikzpicture}

Координаты точек
(x,y) — с указанием размерности или по умолчанию в см.
(30:1cm) — полярные координаты 30 градусов и 1 см.
Относительные перемещения
+(x,y) — переместиться относительно последней точки на x и y
++(x,y) — переместить указатель, но ничего не чертить, чертит только команда --.
\begin{tikzpicture}[scale=3]
\clip (-0.1,-0.2) rectangle (1.1,0.75);
\draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4);
\draw (-1.5,0) -- (1.5,0);
\draw (0,-1.5) -- (0,1.5);
\draw (0,0) circle [radius=1cm];
\filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm)
arc [start angle=0, end angle=30, radius=3mm] -- cycle;
\draw[red,very thick] (30:1cm) -- +(0,-0.5);
\draw[blue,very thick] (30:1cm) ++(0,-0.5) -- (0,0);
\end{tikzpicture}

Определяем свои команды
\begin{tikzpicture}
\def\rectanglepath{-- ++(1cm,0cm) -- ++(0cm,1cm) -- ++(-1cm,0cm) -- cycle}
\draw (0,0) \rectanglepath;
\draw (1.5,0) \rectanglepath;
\end{tikzpicture}
нарисует два квадратика
или идентично:
\tikz \draw (0,0) rectangle +(1,1) (1.5,0) rectangle +(1,1);
1,{tan(30)}) — так тоже умеет. Любую функцию для расчета координат.
Координаты по пересекающимся линиям
\path [name path=upward line] (1,0) -- (1,1);
\path [name path=sloped line] (0,0) -- (30:1.5cm);
% Рисуем невидимые пути. \path без атрибутов, просто перемещает указатель
% (добавить библиотеку `\usetikzlibrary{intersections}' после загрузки tikz)
\draw [name intersections={of=upward line and sloped line, by=x}] % нашли точку пересечения и назвали ее x
[very thick,orange] (1,0) -- (x); % нарисовали линию от (1,0) до точки пересечения
Стрелки
\draw[->] (-1.5,0) -- (1.5,0);
\draw[->] (0,-1.5) -- (0,1.5);
->, <-, <->, <<-, ->>
или использовать специальную библиотеку Documentation arrow
\usetikzlibrary {arrows.meta}
\begin{tikzpicture}[>=Stealth]
Облать видимости
\begin{tikzpicture}[ultra thick]
\draw (0,0) -- (0,1);
\begin{scope}[thin]
\draw (1,0) -- (1,1);
\draw (2,0) -- (2,1);
\end{scope}
\draw (3,0) -- (3,1);
\end{tikzpicture}
Окружение {scope}
Преобразования
xshift=2pt — смещает все точки на 2pt по x
\begin{tikzpicture}[even odd rule,rounded corners=2pt,x=10pt,y=10pt]
\filldraw[fill=yellow!80!black] (0,0) rectangle (1,1)
[xshift=5pt,yshift=5pt] (0,0) rectangle (1,1)
[rotate=30] (-1,-1) rectangle (2,2);
\end{tikzpicture}
Самое интересное во всем этом процессе, что когда ты пишешь эти строки и видишь, как все это происходит по настоящему в твоем Latex документе — приходишь в восторг!
xshift и yshift смещают по осям, shift={(1,0)} смещает в точку shift={+(0,0)} или относительную точку.
rotate или rotate around вращают объект относительно точки
scale, xscale, yscale — масштабирует xscale=-1 схлопывает фигуру
xslant, yslant — наклоняет
cm — опция для произвольных преобразований по матрице
Повторения и циклы
Можно использовать независимый пакет для \foreach или он автоматически подключен в Tikz
Синтаксис команды:
\foreach ⟨variable⟩ in {⟨list of values⟩} ⟨commands⟩
Пример:
\foreach \x in {1,2,3} {$x =\x$, }
x=1, x=2, x=3,
\begin{tikzpicture}[scale=3]
\clip (-0.1,-0.2) rectangle (1.1,1.51);
\draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4);
\filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm)
arc [start angle=0, end angle=30, radius=3mm] -- cycle;
\draw[->] (-1.5,0) -- (1.5,0);
\draw[->] (0,-1.5) -- (0,1.5);
\draw (0,0) circle [radius=1cm];
\foreach \x in {-1cm,-0.5cm,0.5cm,1cm}
\draw [red](\x,-1pt) -- (\x,1pt);
\foreach \y in {-1cm,-0.5cm,0.5cm,1cm}
\draw [blue](-1pt,\y) -- (1pt,\y);
\end{tikzpicture}
Поставил меточки на осях координат

\tikz \foreach \x in {1,...,10}
\draw (\x,0) circle (0.4cm);
еще вариант для диапазона значений: цикл в цикле
\begin{tikzpicture}
\foreach \x in {1,2,...,5,7,8,...,12}
\foreach \y in {1,...,5}
{
\draw (\x,\y) +(-.5,-.5) rectangle ++(.5,.5);
\draw (\x,\y) node{\x,\y};
}
\end{tikzpicture}

Nodes
\begin{tikzpicture}
\draw (0,0) rectangle (2,2);
\draw (0.5,0.5) node [fill=yellow!80!black]
{Text at \texttt{node 1}}
-- (1.5,1.5) node {Text at \texttt{node 2}};
\end{tikzpicture}
любой текст или все что нам нужно можно вставить в Node и поместить в нужную точку координат рисунка
Фон можно закрасить [fill=white]

Якоря по сторонам света
На всех рисунках есть якоря со сторонами света:
- north
- south
- east
- west
и их комбинации anchor=south west и т.д.
above rigth тоже, что south west
below=1pt — можно задавать смещение
\usetikzlibrary {intersections}
\begin{tikzpicture}[scale=3]
\clip (-2,-0.2) rectangle (2,0.8);
\draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4);
\filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm)
arc [start angle=0, end angle=30, radius=3mm] -- cycle;
\draw[->] (-1.5,0) -- (1.5,0) coordinate (x axis);
\draw[->] (0,-1.5) -- (0,1.5) coordinate (y axis);
\draw (0,0) circle [radius=1cm];
\draw[very thick,red]
(30:1cm) -- node[left=1pt,fill=white] {$\sin \alpha$} (30:1cm |- x axis);
\draw[very thick,blue]
(30:1cm |- x axis) -- node[below=2pt,fill=white] {$\cos \alpha$} (0,0);
\path [name path=upward line] (1,0) -- (1,1);
\path [name path=sloped line] (0,0) -- (30:1.5cm);
\draw [name intersections={of=upward line and sloped line, by=t}]
[very thick,orange] (1,0) -- node [right=1pt,fill=white]
{$\displaystyle \tan \alpha \color{black}=
\frac{{\color{red}\sin \alpha}}{\color{blue}\cos \alpha}$} (t);
\draw (0,0) -- (t);
\foreach \x/\xtext in {-1, -0.5/-\frac{1}{2}, 1}
\draw (\x cm,1pt) -- (\x cm,-1pt) node[anchor=north,fill=red!20] {$\xtext$};
\foreach \y/\ytext in {-1, -0.5/-\frac{1}{2}, 0.5/\frac{1}{2}, 1}
\draw (1pt,\y cm) -- (-1pt,\y cm) node[anchor=east,fill=red!20] {$\ytext$};
\end{tikzpicture}

Текст по контуру
\begin{tikzpicture}
\draw (0,0) .. controls (6,1) and (9,1) ..
node[near start,sloped,above] {near start}
node {midway}
node[very near end,sloped,below] {very near end} (12,0);
\end{tikzpicture}

Полностью пример
\begin{tikzpicture}
[scale=3,line cap=round,
% Styles
axes/.style=,
important line/.style={very thick},
information text/.style={rounded corners,fill=red!10,inner sep=1ex}]
% Colors
\colorlet{anglecolor}{green!50!black}
\colorlet{sincolor}{red}
\colorlet{tancolor}{orange!80!black}
\colorlet{coscolor}{blue}
% The graphic
\draw[help lines,step=0.5cm] (-1.4,-1.4) grid (1.4,1.4);
\draw (0,0) circle [radius=1cm];
\begin{scope}[axes]
\draw[->] (-1.5,0) -- (1.5,0) node[right] {$x$} coordinate(x axis);
\draw[->] (0,-1.5) -- (0,1.5) node[above] {$y$} coordinate(y axis);
\foreach \x/\xtext in {-1, -.5/-\frac{1}{2}, 1}
\draw[xshift=\x cm] (0pt,1pt) -- (0pt,-1pt) node[below,fill=white] {$\xtext$};
\foreach \y/\ytext in {-1, -.5/-\frac{1}{2}, .5/\frac{1}{2}, 1}
\draw[yshift=\y cm] (1pt,0pt) -- (-1pt,0pt) node[left,fill=white] {$\ytext$};
\end{scope}
\filldraw[fill=green!20,draw=anglecolor] (0,0) -- (3mm,0pt)
arc [start angle=0, end angle=30, radius=3mm];
\draw (15:2mm) node[anglecolor] {$\alpha$};
\draw[important line,sincolor]
(30:1cm) -- node[left=1pt,fill=white] {$\sin \alpha$} (30:1cm |- x axis);
\draw[important line,coscolor]
(30:1cm |- x axis) -- node[below=2pt,fill=white] {$\cos \alpha$} (0,0);
\path [name path=upward line] (1,0) -- (1,1);
\path [name path=sloped line] (0,0) -- (30:1.5cm);
\draw [name intersections={of=upward line and sloped line, by=t}]
[very thick,orange] (1,0) -- node [right=1pt,fill=white]
{$\displaystyle \tan \alpha \color{black}=
\frac{{\color{red}\sin \alpha}}{\color{blue}\cos \alpha}$} (t);
\draw (0,0) -- (t);
\draw[xshift=1.85cm]
node[right,text width=6cm,information text]
{
The {\color{anglecolor} angle $\alpha$} is $30^\circ$ in the
example ($\pi/6$ in radians). The {\color{sincolor}sine of
$\alpha$}, which is the height of the red line, is
\[
{\color{sincolor} \sin \alpha} = 1/2.
\]
By the Theorem of Pythagoras ...
};
\end{tikzpicture}
Для node задали ширину текста text width=6cm
Макросы
\usetikzlibrary {angles,quotes}
\begin{tikzpicture}[scale=3]
\coordinate (A) at (1,0);
\coordinate (B) at (0,0);
\coordinate (C) at (30:1cm);
\draw (A) -- (B) -- (C)
pic [draw=green!50!black, fill=green!20, angle radius=9mm,
"$\alpha$"] {angle = A--B--C};
\end{tikzpicture}
Команда pic создает макрос для последующего использования кода.
7.8 - Пакет Xcolor и colortbl
Пакет xcolor и colortbl - управление цветами в LaTeX
Установка и базовое использование
\usepackage{xcolor} % Основной пакет для работы с цветами
\usepackage[table]{xcolor} % Альтернативный вариант с загрузкой colortbl
% или
\usepackage{colortbl} % Пакет для цветных таблиц
Цветовые модели
Пакет поддерживает несколько цветовых моделей:
| Модель | Компоненты | Диапазон значений |
|---|---|---|
rgb | red, green, blue | [0, 1] для каждого |
cmyk | cyan, magenta, yellow, black | [0, 1] для каждого |
gray | оттенки серого | [0, 1] |
HTML | RRGGBB | 000000 до FFFFFF |
RGB | Red, Green, Blue | 0-255 для каждого |
Предопределенные цвета
Базовые цвета:
red, green, blue, cyan, magenta, yellow, black, white, gray, darkgray, lightgray
Дополнительные цвета:
brown, lime, olive, orange, pink, purple, teal, violet
Расширенные палитры:
\usepackage[dvipsnames]{xcolor} % 68 CMYK цветов
\usepackage[svgnames]{xcolor} % 151 RGB цвет
\usepackage[x11names]{xcolor} % 317 RGB цветов
Основные команды
Определение цветов
\definecolor{myred}{rgb}{1,0,0} % Чистый красный
\definecolor{mygray}{gray}{0.5} % Серый 50%
\definecolor{myblue}{HTML}{1F77B4} % Синий в HEX
Изменение существующих цветов
\colorlet{lightblue}{blue!20} % Светло-синий (20% от blue)
\colorlet{darkred}{red!80!black} % Темно-красный
Использование цветов
\textcolor{red}{Красный текст} % Цвет текста
\colorbox{yellow}{Желтый фон} % Фон текста
\fcolorbox{blue}{white}{Рамка} % Рамка и фон
Работа с таблицами (colortbl)
\begin{tabular}{|>{\columncolor{yellow!20}}c|c|}
\hline
\rowcolor{blue!10}
Заголовок 1 & Заголовок 2 \\
\hline
Ячейка 1 & \cellcolor{green!20}Ячейка 2 \\
\hline
\end{tabular}
Смешивание цветов
\color{red!50!blue} % Фиолетовый (50% красного + 50% синего)
\color{green!40!white!60} % Светло-зеленый
Прозрачность (требует pdfTeX или LuaTeX)
\textcolor{red!50}{Полупрозрачный текст}
Примеры использования
Цветной текст с рамкой:
\fcolorbox{black}{yellow!30}{
\textcolor{blue!80!black}{
Важное сообщение!
}
}
Градиентный фон:
\colorlet{startcolor}{red!20}
\colorlet{endcolor}{red!60}
\colorlet{middlecolor}{red!40}
\begin{tabular}{|p{3cm}|}
\arrayrulecolor{white}
\hline
\rowcolor{startcolor} Строка 1 \\
\rowcolor{middlecolor} Строка 2 \\
\rowcolor{endcolor} Строка 3 \\
\hline
\end{tabular}
Цветные математические формулы:
\[
\textcolor{blue}{E} = \textcolor{red}{m}\textcolor{green}{c^2}
\]
\[
\colorbox{yellow!20}{
\color{blue}
\int_a^b f(x)dx
}
\]
Советы
- Для документов, которые будут печататься, используйте CMYK цвета
- Для веб-документов лучше подходят RGB/HTML цвета
- Используйте мягкие цвета (!20-!40) для фонов
- Сохраняйте контраст между текстом и фоном
- Для сложных таблиц используйте
\rowcolorsизxcolor
\rowcolors{1}{blue!10}{white} % Чередование цветов строк
\begin{tabular}{cc}
A & B \\
C & D \\
E & F \\
\end{tabular}
Этот пакет предоставляет полный контроль над цветами в вашем LaTeX документе, от простого окрашивания текста до сложного оформления таблиц и математических формул.
7.9 - Пакет longtable
Пакет Longtable
Размещение пакета
https://ctan.org/pkg/longtable
Официальная документация
https://mirror.macomnet.net/pub/CTAN/macros/latex/required/tools/longtable.pdf
Установка
\usepackage{longtable} %собственно сам пакет для работы с таблицами
\usepackage{xcolor} %чтобы работать с цветами
\usepackage{colortbl} %чтобы работать с цветными таблицами
Особенности
Полная приемственность от tabular и tabularx, поэтому можно только им и пользоваться.
Очень понадобятся первоначальные настройки для формата таблицы
\newcolumntype{C}[1]{>{\columncolor{white}\ttfamily\centering\arraybackslash}p{#1cm}}
\newcolumntype{R}[1]{>{\columncolor{white}\ttfamily\raggedleft\arraybackslash}p{#1cm}}
\newcolumntype{L}[1]{>{\columncolor{white}\ttfamily\raggedright\arraybackslash}p{#1cm}}
\newcolumntype{B}[1]{>{\columncolor{white}\ttfamily\bfseries\raggedright\arraybackslash}p{#1cm}}
\renewcommand{\tabcolsep}{0.05cm}
\renewcommand{\arraystretch}{1.7}
\newcolumntype похожа на \newcommand но только для настройки таблиц. Работает со всеми пакетами расширяющие стандартый пакет таблиц: xtab, xtabular, tabularx и longtable.
https://ctan.org/pkg/tabularx https://mirror.truenetwork.ru/CTAN/macros/latex/required/tools/tabularx.pdf
оттуда и возьмем описание команд:
\arraybackslash
\raggedright, \raggedleft, \centering — после этих команд изменяется поведение команды \\ и \\*, вот, чтобы этого не произошло и применяем команду \arraybackslash.
>{\raggedright\arraybackslash}X
\newcolumntype
определяет новые параметры колонки и назначает их переменной Y или какую напишем, но только из одной буквы. Мне алфавита хватало всегда.
\newcolumntype{Y}{>{\small\raggedright\arraybackslash}X}
после знака {> пишем любые команды для определения шрифта, цвета, выравнивания и т.д. Обычно это удобно связывать с шириной колонки и передавать значение через переменную в p{#1}.
Количество переменных может быть любое, главное в них самому не запутаться.
После определения новых типов колонок их можно использовать в заголовке описания таблицы наравне с lcrpm
\tabularxcolumn
Изменяет тип колонки X
\newcommand{\tabularxcolumn}[1]{p{#1}} — соответствует \parbox[t] — и определено по умолчанию
\renewcommand{\tabularxcolumn}[1]{>{\small}m{#1}} — соответствует \parbox[m] — контент выравнивается по центру и типа так я могу переопределить, но у меня ничего не получилось, зато мои настройки \newcolumn работают шикарно.
ширина колонки
Умный Latex по умолчанию всегда пытается создать одинаковые колонки с размером \hsize, но мы можем переопределить пропорционально ширину каждой колонки. Первая будет половина от стандартной ширины, а вторая в 3 раза больше.
{>{\hsize=.5\hsize\linewidth=\hsize}X >{\hsize=1.5\hsize\linewidth=\hsize}X}
Дальше tabularx упрощает работы со сносками. Но я на этом пакете заканчиваю и перехожу к longtable.
Сделал себе мастер таблицу и закатал в yasnippet
# -*- mode: snippet -*-
# name: longtable
# key: longtable
# --
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%LONGTABLE
\begin{center}
\rowcolors{2}{gray!10}{white} \\arrayrulecolor{gray!20} %раскрасим в два цвета строки
\begin{longtable}{c|c} %описание таблицы
%%%%%%%%%%%%%%% заголовок на первой странице
\caption[Название таблицы короткое]{Название таблицы длинное\label{tab:}}\\\
\rowcolor{blue!40} %раскрасим заголовок таблицы
\multicolumn{1}{c}{Наименование} % название первой колонки
& \multicolumn{1}{c}{Описание} % название второй колонки
% при большем количестве колонок последнюю строчку повторить столько же раз
% готовый раздел скопировать в раздел Заголовок на второй странице
\endfirsthead % конец заголовка
%%%%%%%%%%%%%%%%% конец заголовка на первой странице
%%%%%%%%%%%%%%% Заголовок на второй странице
\caption{продолжение таблицы на следующей странице}\\\
\rowcolor{blue!40}
\multicolumn{1}{c}{Наименование}
& \multicolumn{1}{c}{Описание}
\endhead %конец заголовка
%%%%%%%%%%%%%%%%% конец заголовка на второй странице
%%%%%%%%%%%%%%%%%%%%% BODY TABLE
Первый & Второй\\\\
Третий & Четвертый\\\\
%%%%%%%%%%%%%%%%%%%%%
\end{longtable}
\end{center}

Команды для высоты строк и отступов между колонками
\renewcommand{\tabcolsep}{0.05cm}
\renewcommand{\arraystretch}{1.7}
- первая определит отступ между колонками
- вторая высоту строк в таблице
Собственно мне всего перечисленного хватало практически на 90% всех таблиц.
Длина таблицы на странице
По умолчанию длина таблицы 20 строк, но можно изменить с помощью команты
\setcounter{LTchunksize}{10}
и будет 10!
Изменить нумерацию таблиц
\renewcommand\LTcaptype{⟨counter ⟩}
Header & Footer
- У таблицы могут быть первый Header и после его описания нужно поставить
\endfirsthead - После определения заголовков на 2-й и следующих таблицах поставить
\endhead. - Если таблица на одной странице, то пункт 2 не нужен.
\endfootтакже заканчивает описание последней строки таблицы на странице\endlastfootописывает последнюю строку таблицы
\сaption
\caption{...} команда эквивалентна \multicolumn{n}{c}{\parbox{\LTcapwidth}{…}}
она просто объединяет все колонки и пишется как полноценная строка таблицы.
\caption[Опциональное имя, используется в списке таблиц]{Полноценное имя таблицы\label{long}}.
\multicolumn
объединяет колонки \multicolumn{numcols}{cols}{text}
- количество объединяемых колонок
- формат колонок
lcrmp - Собственно текст в этой ячейке с применением всех возможных комманд и боксов, а также
\multirowдля объединения строк. Но для нее нужно подключить пакет\usepackage{multirow}
\kill
делаем строку для определения ширины столбцов и вместо \\ ставим \kill. Строка не будет отображаться в таблице, но ширину настроит.
Выравнивание таблицы на странице
LTleft и LTright
\setlength\LTleft\parindent
\setlength\LTright\fill
устанавливаем отступ для всей таблицы слева и справа, но один параметр нужно сотавлять тягучим \fill
\setlength\LTleft{0pt}
\setlength\LTright{0pt}
\begin{longtable}{@{\extracolsep{...}}...}
\extracolsep — делает резиновым столбец.
Сводная таблица
Параметры
| \LTleft | Glue to the left of the table. | (\fill) |
|---|---|---|
| \LTright | Glue to the right of the table. | (\fill) |
| \LTpre | Glue before the table. | (\bigskipamount) |
| \LTpost | Glue after the table. | (\bigskipamount) |
| \LTcapwidth | The width of a parbox containing the caption. | (4in) |
| \LTchunksize | The number of rows per chunk. | (20) |
Optional arguments to \begin{longtable}
| none | Position as specified by \LTleft and \LTright. |
|---|---|
| [c] | Centre the table. |
| [l] | Place the table flush left. |
| [r] | Place the table flush right. |
Commands to end table rows
| \ | Specifies the end of a row |
|---|---|
| \\[⟨dim⟩] | Ends row, then adds vertical space (as in the tabular environment). |
| \\* | The same as \ but disallows a page break after the row. |
| \tabularnewline | Alternative to \\ for use in the scope of \raggedright and similar commands that redefine \\. |
| \kill | Row is ‘killed’, but is used in calculating widths. |
| \endhead | Specifies rows to appear at the top of every page. |
| \endfirsthead | Specifies rows to appear at the top of the first page. |
| \endfoot | Specifies rows to appear at the bottom of every page. |
| \endlastfoot | Specifies rows to appear at the bottom of the last page. |
Longtable caption commands
| \caption{⟨caption⟩} | Caption ‘Table ?: ⟨caption⟩’, and a ‘⟨caption⟩’ entry in the list of tables. |
|---|---|
| \caption[⟨lot⟩]{⟨caption⟩} | Caption ‘Table ?: ⟨caption⟩’, and a ‘⟨lot⟩’ entry in the list of tables. |
| \caption[]{⟨caption⟩} | Caption ‘Table ?: ⟨caption⟩’, but no entry in the list of tables. |
| \caption*{⟨caption⟩} | Caption ‘⟨caption⟩’, but no entry in the list of tables. |
Commands available at the start of a row
| \pagebreak | Force a page break. |
|---|---|
| \pagebreak[⟨val ⟩] | A ‘hint’ between 0 and 4 of the desirability of a break. |
| \nopagebreak | Prohibit a page break. |
| \nopagebreak[⟨val ⟩] | A ‘hint’ between 0 and 4 of the undesirability of a break. |
| \newpage | Force a page break. |
Footnote commands available inside longtable
| \footnote | Footnotes, but may not be used in the table head & foot. |
|---|---|
| \footnotemark | Footnotemark, may be used in the table head & foot. |
| \footnotetext | Footnote text, use in the table body. |
Setlongtables
| \setlongtables | Obsolete command. Does nothing now. |
|---|
Multirow замолвите слово
Объединяет строки в таблице
Подключить через команду
\usepackage{multirow}
\multirow[〈vpos 〉]{〈nrows 〉}[〈bigstruts 〉]{〈width 〉}[〈vmove 〉]{〈text 〉}
- vpos —
tcbвыравнивает текст в общей ячейке по [t] [c] [b] (необязательный параметр) - nrows — количество строк
- bigstruts — это распорки или больше похоже на заполнение текста (я не использовал)
- width — ширина ячейки с текстом. Обычно (*), но если используем \multirow то не все колонки могут быть заполнены текстом
- vmove — это как \raisebox — поднимает текст вверх или вниз. Удобная штука. Можно отрицательные и положительные значения.
- text — собственно сам текст
\multicolumn{2}{c}{\multirow{3}{*}{Multi-multi}} — с multirow использовать только в таком порядке, а не наоборот.
В этом пакете еще есть утилиты для работы с большими скобками на объединенные строки.
7.10 - Newfont
Удивительное путешествие в мир создания интегрированных шрифтов в Latex
История началась с французской компании, которая попросила меня написать несколько документаций на свои изделия.
Так как я сначала подумал,что отделаюсь легким испугом, то первую работу сделал в XARA. Замечательный редактор, но когда в моем документе перевалило за 50 страниц, я понял, что ошибся с выбором инструмента.
Потом было несколько документов по 4-8 страниц. Что не составило проблем сделать в XARA.
Но когда дело дошло до очередного 80-ти страничного документа, я решил просто сделать в Latex.
Эта компания использовала свои фирменные шрифты, поэтому шрифты скачал в интернет, подключил модуль \usepackage{fontspec} и вуаля!!!
\setmainfont{AllRoundGothic-Book}[
BoldFont = AllRoundGothic-Bold ,
ItalicFont = AllRoundGothic-BookOblique ]
\setsansfont{AllRoundGothic-XLig}
\setmonofont{Calibri}[
Extension = .ttf ,
BoldFont = Calibri_bold] % задаёт \sffamily, шрифт без засечек
Настроил цвета через пакет \usepackage{xcolor}
%%%%%%%%% COLOR %%%%%%%%%%%%%%%5
\definecolor{BleuProfond}{RGB}{7,29,73}%#071D49
\definecolor{BleuLBA}{RGB}{65,182,230}
\definecolor{GrisA}{RGB}{37,40,42}
\definecolor{GrisC}{RGB}{178,180,178}
Подключил нужные раскладки и настроил свои fontfamily
\newfontfamily\boldfont{AllRoundGothic-Bold}
\newfontfamily\demifont{AllRoundGothic-Demi}
\newfontfamily\demifontwhite{AllRoundGothic-Demi}[Color = white]
\newfontfamily\mediumfont{AllRoundGothic-Medium}
\newfontfamily\boldfontbleu{AllRoundGothic-Bold}[Color = BleuProfond]
\newfontfamily\boldfontlba{AllRoundGothic-Bold}[Color = BleuLBA]
\newfontfamily\boldfontwhite{AllRoundGothic-Bold}[Color = white]
\newfontfamily\lc[Scale=MatchLowercase]{AllRoundGothic-Demi}[Color = BleuProfond]
\newfontfamily\uc[Scale=MatchUppercase]{AllRoundGothic-Demi}
\newfontfamily\ac[Scale=MatchAveragecase]{AllRoundGothic-Demi}
\newfontfamily\numamco{Calibri}
Собственно все!
Дальше рутина по созданию стиля страницы. Очень приятный XELATEX с которым мы достаточно быстро справились с поставленной задачей (убрал только привычный мне %\usepackage{hyperref}), потому-что на него странно ругался компилятор. (вычислил эксперементально).
Но все мои познания подключения шрифтов начались тогда, когда заказчик попросил сделать оглавление кликабельное с возможностью переходить по ссылкам на страницы.
Оказывается не XELATEX не LUALATEX при всей своей красоте поддержки TrueType шрифтов напрямую, отказываются работать с \usepackage[xetex]{hyperref} даже в таком варианте.
Копирую шрифты в папку проекта
Есть варианты создать свою структуру и прописать настройки к ней, но в этом варианте я ограничиваюсь настройкой в рабочей директории.
Подключать буду три шрифта:
- AllRoundGothic-Bold.ttf
- AllRoundGothic-Book.ttf
- AllRoundGothic-Demi.ttf
Подготовительные мероприятия
Нахожу в Latex (T1-WGL4.enc) на Manjaro он спрятался в /opt/texlive/2024/texmf-dist/fonts/enc/ttf2pk/base
Его тоже копирую в рабочуюдиректорию, чтобы ничего не потерялось. Для кирилических шрифтов копируем T2A.enc, он находится по соседству: /opt/texlive/2024/texmf-dist/fonts/enc/t2.
Теперь все готово для подключения.
Создаю TeX Font Metrics (tfm)
Файлы с расширением tfm хранят необработанные шрифты, а файлы vpl виртуальные шрифты.
ttf2tfm AllRoundGothic-Demi.ttf -q -T T1-WGL4.enc -v ecAllRoundGothic-Demi.vpl recAllRoundGothic-Demi.tfm >> ttfonts.map
ttf2tfm AllRoundGothic-Bold.ttf -q -T T1-WGL4.enc -v ecAllRoundGothic-Bold.vpl recAllRoundGothic-Bold.tfm >> ttfonts.map
ttf2tfm AllRoundGothic-Book.ttf -q -T T1-WGL4.enc -v ecAllRoundGothic-Book.vpl recAllRoundGothic-Dook.tfm >> ttfonts.map
Можно посмотреть в ttfont.map, должно получиться что-то вроде:
recAllRoundGothic-Bold AllRoundGothic-Bold.ttf Encoding=T1-WGL4.enc
recAllRoundGothic-Book AllRoundGothic-Book.ttf Encoding=T1-WGL4.enc
recAllRoundGothic-Demi AllRoundGothic-Demi.ttf Encoding=T1-WGL4.enc
Чтобы создать наклонные версии обычного и жирного шрифта, команду следует расширить следующим образом:
ttf2tfm AllRoundGothic-Book.ttf -q -T T1-WGL4.enc -s .167 -v ecAllRoundGothic-Book.vpl recAllRoundGothic-Dook.tfm >> ttfonts.map
Но я так не делал, потому-что было не нужно.
Создаю Virtual Fonts (vf)
vptovf ecAllRoundGothic-Demi.vpl ecAllRoundGothic-Demi.vf ecAllRoundGothic-Demi.tfm
vptovf ecAllRoundGothic-Bold.vpl ecAllRoundGothic-Bold.vf ecAllRoundGothic-Bold.tfm
vptovf ecAllRoundGothic-Book.vpl ecAllRoundGothic-Book.vf ecAllRoundGothic-Book.tfm
Но если бы я создавал какой-нибудь times, то нужно было создавать по всем законам толстые, наклонные и т.д.
vptovf ectimes.vpl ectimes.vf ectimes.tfm
vptovf ectimesi.vpl ectimesi.vf ectimesi.tfm
vptovf ectimesbd.vpl ectimesbd.vf ectimesbd.tfm
vptovf ectimesbi.vpl ectimesbi.vf ectimesbi.tfm
vptovf ectimeso.vpl ectimeso.vf ectimeso.tfm
vptovf ectimesbdo.vpl ectimesbdo.vf ectimesbdo.tfm
Что имеем по итогу?
-rw-r--r-- 1 edge edge 555 ноя 12 16:31 ecAllRoundGothic-Bold.log
-rw-r--r-- 1 edge edge 1792 ноя 12 16:26 ecAllRoundGothic-Bold.tfm
-rw-r--r-- 1 edge edge 1784 ноя 12 16:26 ecAllRoundGothic-Bold.vf
-rw-r--r-- 1 edge edge 22500 ноя 12 16:19 ecAllRoundGothic-Bold.vpl
-rw-r--r-- 1 edge edge 1780 ноя 12 16:26 ecAllRoundGothic-Book.tfm
-rw-r--r-- 1 edge edge 1784 ноя 12 16:26 ecAllRoundGothic-Book.vf
-rw-r--r-- 1 edge edge 22365 ноя 12 16:20 ecAllRoundGothic-Book.vpl
-rw-r--r-- 1 edge edge 1788 ноя 12 16:25 ecAllRoundGothic-Demi.tfm
-rw-r--r-- 1 edge edge 1784 ноя 12 16:25 ecAllRoundGothic-Demi.vf
-rw-r--r-- 1 edge edge 22434 ноя 12 16:21 ecAllRoundGothic-Demi.vpl
del *.vpl они нам больше не нужны. Из них создали *.vf
Дальше размещаем по структурам каталогов Latex для постоянного использования или ничего не делаем, а все храним в рабочей папке. И все будет работать.
Вместо заключения
В latex вставляем такие простые вещи:
\font\myfont=ecAllRoundGothic-Bold
\font\mybigfont=ecAllRoundGothic-Bold at 36pt
\font\bookfont=ecAllRoundGothic-Book
\font\demifont=ecAllRoundGothic-Demi
\myfont Hello, I am being typeset in AllRoundGothic
\mybigfont Me too...
или назначаем по умолчанию, как описывал раньше.
Но, получаем:

Для постоянного использования шрифта
Создаем файл .fd я этого не делал, но из образца записываю. Там подключали times.
\ProvidesFile{t1tnr.fd}[Put your description of font here]
\DeclareFontFamily{T1}{tnr}{}
\DeclareFontShape{T1}{tnr}{b}{n}{<->ectimesbd}{}
\DeclareFontShape{T1}{tnr}{b}{sl}{<-> ectimesbdo}{}
\DeclareFontShape{T1}{tnr}{b}{it}{<-> ectimesbi}{}
\DeclareFontShape{T1}{tnr}{m}{n}{<-> ectimes}{}
\DeclareFontShape{T1}{tnr}{m}{sl}{<-> ectimeso}{}
\DeclareFontShape{T1}{tnr}{m}{it}{<-> ectimesi}{}
\DeclareFontShape{T1}{tnr}{bx}{n}{<->ssub * tnr/b/n}{}
\DeclareFontShape{T1}{tnr}{bx}{sl}{<->ssub * tnr/b/sl}{}
\DeclareFontShape{T1}{tnr}{bx}{it}{<->ssub * tnr/b/it}{}
\endinput
Затем использование в документе будет выглядеть:
documentclass{article}
\begin{document}
\usefont{T1}{tnr}{m}{sl}
Hello, I am being typeset in Times New Roman Slanted
\end{document}
Или прописать прямо в преамбуле
\documentclass{article}
\renewcommand{\encodingdefault}{T1}
\renewcommand{\rmdefault}{tnr}
\begin{document}
Hello, I am being typeset in \textsl{Times New Roman Slanted}
\end{document}
Проверяем:
pdftex story
This is pdfTeX, Version 3.141592653-2.6-1.40.26 (TeX Live 2024) (preloaded format=pdftex)
restricted \write18 enabled.
entering extended mode
(/opt/texlive/2024/texmf-dist/tex/plain/knuth-lib/story.tex [1{/opt/texlive/202
4/texmf-var/fonts/map/pdftex/updmap/pdftex.map}])
*\bye
Подключение шрифтов Adobe (afm)
Создаем afm шрифты
ttf2afm -e T1-WGL4.enc -o rectimes.afm times.ttf
ttf2afm -e T1-WGL4.enc -o rectimesi.afm timesi.ttf
ttf2afm -e T1-WGL4.enc -o rectimesbd.afm timesbd.ttf
ttf2afm -e T1-WGL4.enc -o rectimesbi.afm timesbi.ttf
Создаем tfm и map
afm2tfm rectimes.afm -T T1-WGL4.enc rectimes.tfm >>winfonts.map
afm2tfm rectimesi.afm -T T1-WGL4.enc rectimesi.tfm >>winfonts.map
afm2tfm rectimesbd.afm -T T1-WGL4.enc rectimesbd.tfm >>winfonts.map
afm2tfm rectimesbi.afm -T T1-WGL4.enc rectimesbi.tfm >>winfonts.map
afm2tfm rectimes.afm -T T1-WGL4.enc -s .167 rectimeso.tfm >>winfonts.map
afm2tfm rectimesbd.afm -T T1-WGL4.enc -s .167 rectimesbdo.tfm >>winfonts.map
Редактируем map файл
rectimes TimesNewRomanPSMT " T1Encoding ReEncodeFont " <times.ttf T1-WGL4.enc
rectimesi TimesNewRomanPS-ItalicMT " T1Encoding ReEncodeFont " <timesi.ttf T1-WGL4.enc
rectimesbd TimesNewRomanPS-BoldMT " T1Encoding ReEncodeFont " <timesbd.ttf T1-WGL4.enc
rectimesbi TimesNewRomanPS-BoldItalicMT " T1Encoding ReEncodeFont " <timesbi.ttf T1-WGL4.enc
rectimeso TimesNewRomanPSMT " .167 SlantFont T1Encoding ReEncodeFont " <times.ttf T1-WGL4.enc
rectimesbdo TimesNewRomanPS-BoldMT " .167 SlantFont T1Encoding ReEncodeFont " <timesbd.ttf T1-WGL4.enc
Далее можно разложить по правильным директориям или оставить в рабочей дирректории.
У Latex есть много своих встроенных шрифтов
Подключаем
\usepackage{DejaVuSans}
\renewcommand*\familydefault{\sfdefault}
и пользуемся без геммороя.
7.11 - Pdfpages
Подключение пакета
Для установки пакета в преамбуле документа пишем:
\usepackage[⟨options ⟩]{pdfpages}
Родная документация
https://mirror.macomnet.net/pub/CTAN/macros/latex/contrib/pdfpages/pdfpages.pdf
Сам пакет на SPAN
Опции при подключении
⟨option⟩
- final: режим по умолчанию, вставляет страницы в документ
- draft: не вставляет страницу, но вставляет ссылку в боксе
- demo: вставляет пустую страницу
- nodemo: отключает демо
Вставка документа
\includepdf[⟨key=val ⟩]{⟨filename⟩}
Вставляет файл где укажешь.
Key=val могут быть различными.
Если нужно вставить избранные страницы, используем ключ page
pages={3,5,6,8})
pages={4-9}
pages={3,{},8-11,15}
nup — укладывает логические страницы на лист (что-то вроде микространиц) nup=⟨xnup⟩x⟨ynup⟩
landscape=false — по умолчанию, но можно развернуть, если нужно
и еще куча всяких опций для какого-то боловства. Мне пока хватает этого.
7.12 - Titleps
Оформление стилей страниц, заголовков и оглавления. Продвинутый пакет. Оставляю его для настроек различных стилей документов.
Совместно с TITLESEC бомбическая штука по настройке стилей страниц. Обзор документации.
Пакет TITLEPS
Установка пакета
Для установки пакета в преамбуле документа пишем:
\usepackage[pagestyles]{titlesec}
Страница репозитория
Документация
https://mirror.truenetwork.ru/CTAN/macros/latex/contrib/titlesec/titleps.pdf
Определение стиля страницы
\newpagestyle{⟨name⟩}[⟨global-style⟩]{⟨commands⟩}
\renewpagestyle{⟨name⟩}[⟨global-style⟩]{⟨commands⟩}
Они их почему-то называют верхние и нижние команды.
Установка для HEADER и FOOTER
\sethead[⟨even-left⟩][⟨even-center⟩][⟨even-right⟩] {⟨odd-left⟩}{⟨odd-center⟩}{⟨odd-right⟩}
\setfoot[⟨even-left⟩][⟨even-center⟩][⟨even-right⟩] {⟨odd-left⟩}{⟨odd-center⟩}{⟨odd-right⟩}
А теперь по-порядку.
Все
Первая группа комманд
– \thechapter, \thesection, \thesubsection. . . --- печатают номера заголовков
– \chaptertitle, \sectiontitle, \subsectiontitle. . . --- печатают наименования заголовков
– (только для titlesec) \ifthechapter{⟨true⟩}{⟨false⟩}, \ifthesection{⟨true⟩}{⟨false⟩}, \ifthesubsection{⟨true⟩}{⟨false⟩}. . . --- проверяют где сейчас находится страница
– любые другие команды
Вторая группа комманд
относится ко всему, что есть на странице: - \thepage - другие не включенные в первую группу
Установка MARKSов
\settitlemarks{⟨level-name⟩,⟨sublevel-name⟩,⟨subsublevel-name⟩...}
\settitlemarks*{⟨level-name⟩,⟨sublevel-name⟩,⟨subsublevel-name⟩...}
Устанавливает, какие команды ...title должны быть определены и когда выдаются метки; допускается любое количество уровней (1, 2, 3…). Например, \settitlemarks{chapter,section}
Установка RULES
\headrule
\footrule
\setheadrule{⟨length⟩}
\setfootrule{⟨length⟩}
линии будут проведены под или над калантитулом
Установка отступов RULES
\makeheadrule
\makefootrule
\renewcommand{\makeheadrule}{\rule[-.3\baselineskip]{\linewidth}{⟨dim⟩}}
Этот пример из документации создаст две линнии в HEADER
\renewcommand{\makeheadrule}{%
\makebox[0pt][l]{\rule[.7\baselineskip]{\linewidth}{0.8pt}}%
\color[named]{Red}%
\rule[-.3\baselineskip]{\linewidth}{0.4pt}}
\markboth and \markleft
В документации целая дискуссия по поводу не нужности \markboth и что достаточно \markleft.
Пока не вдаюсь в подробности, но в пакете есть функция \setmarkboth{⟨code-to-use⟩}, чтобы переопределить markboth.
Headline/footline ширина
\widenhead[⟨even-left⟩][⟨even-right⟩]{⟨odd-left⟩}{⟨odd-right⟩}
\widenhead*{⟨even-right/odd-left⟩}{⟨even-left/odd-right⟩}
Этот параметр соответственно добавляет ширину header и footer-ов.
\widenhead*{0pt}{6pc}
тоже самое
\widenhead[6pc][0pt]{0pt}{6pc}
nopatches — это опция в преамбуле пакета для самостоятельной тонкой настройки с помощью \sectionmark.
Marks
Марксы можно получить 4 способами:
- top marks
- first marks
- botttom marks
- next top marks
7.13 - Titlesec
Оформление стилей страниц, заголовков и оглавления. Продвинутый пакет. Оставляю его для настроек различных стилей документов.
Обзор документации.
Пакет TITLESEC
Подключение пакета
Для установки пакета в преамбуле документа пишем:
\usepackage[explicit]{titlesec}
Родная документация
https://mirror.macomnet.net/pub/CTAN/macros/latex/contrib/titlesec/titlesec.pdf
Сам пакет на SPAN
команда explicit мне будет нужна, чтобы в настройках заголовков указывать {#1} для подстановки в нужное место.
В пакете есть так называемые простые настройки и продвинутые.
Простые настройки
Что можно изменять в формате
Для настройки формата заголовка используем три параметра:
- Тип шрифта
rm sf tt md bf up it sl scпо умолчанию в заголовках стоит\bf. - Размер шрифта
big medium small tiny - Выравнивание заголовка
raggedleft center raggedright compact— задает более компактный вид и уменьшает пробелыuppercase— выведет все буквы заглавными (говорят не всегда работает)
Основные команды в простом режиме
titlelabel
\titlelabel{⟨label-format ⟩}
Эта команда изменяет формат метки заголовка
\titlelabel{\thetitle\quad}
т.е можно настроить буквенный вывод, изменить длину пробела, поставить точку и т.д.
titleformat
\titleformat*{⟨command ⟩}{⟨format⟩}
Собственно сам формат заголовка.
command — это \section, \subsection и т.д.
format — соответственно, все, что было сказано выше. Размер шрифта, семейство шрифта и выравнивание.
\titleformat*{\section}{\Large\sf}
Собственно для простой настройки и все!!!
Продвинутые настройки
titleformat
\titleformat{⟨command ⟩}[⟨shape⟩]{⟨format⟩}{⟨label ⟩}{⟨sep⟩}{⟨before-code⟩}[⟨after-code⟩]
command:
это:
- \part,
- \chapter,
- \section,
- \subsection,
- \subsubsection,
- \paragraph,
- \subparagraph.
shape:
это:
- hang — значение по умолчанию (висящая метка)
- block — заголовок помещает в блок. Можно добавлять рисунки и прочее.
- display — помещает метку в отдельный абзац.
\titleformat{\section}[display]
{\fontsize{120}{20}\boldfont}
{\vbox{\hfil\thesection}\hfil}{0em}
{\LARGE\uppercase{#1}}
\titlespacing{\section} {0pc}{20.5ex plus .1ex minus .2ex}{30.5ex minus .1ex}[0pc]

Вот так получится.
- runin — в документации пишут, что как стандартный параграф, но особо не заметил разницы. Наверно бесполезная вещь.
\titleformat{\subsection}[runin]
{\fontsize{44}{10}\boldfont}
{\thesection}{0.5em}
{\LARGE\uppercase{#1}}
\titlespacing{\section} {0pc}{20.5ex plus .1ex minus .2ex}{30.5ex minus .1ex}[0pc]

Использую пакет fontspec для большей красоты настроек. fontsize оттуда.
- leftmargin — тяжело понять, лучше увидеть. Все выравнивает по левому краю.
\titleformat{\subsection}[leftmargin]
{\boldfont}
{\thesection}{1.5em}
{\Large\uppercase{#1}}
\titlespacing{\subsection} {-15pc}{2.5ex plus .1ex minus .2ex}{3.5ex minus .1ex}[5pc]
...
\subsection{Subsection test two line}

И еще одна интересная заметка для заголовка: если я меняю первый параметр в \titlespacing на 3pc то получится:

- rightmargin — как leftmargin, но только вправо. Но у меня результата не получилось. Все улетает за пределы страницы.
titlespasing изменил третий параметр в отрицательную величину, и добился результата.
- drop/wrap — реально оборачивает текст вокруг заголовка
\titleformat{\subsection}[wrap]
{\Large\boldfont}
{\thesection}{1.5em}
{\uppercase{#1}}
\titlespacing{\subsection}{2pc}{4.5ex plus .1ex minus .2ex}{8.5ex plus .2ex minus .1ex}[2pc]
но нужно правильно настроить 3-й параметр в \titlespacing я для своего заголовка поставил 8.5ex, в общем подбираем экспериментально.
Но получилось:

\titlespacing{\subsection}{12pc}{8.5ex plus .1ex minus .2ex}{8.5ex plus .2ex minus .1ex}[6pc]
поменял настройки на 12pc и заголовок стал выглядеть приятнее,
для сравнения если я поставлю drop то будет перенос строк по другому режиму: см. ниже:

- frame — также переносит метку в отдельный параграф как display, но еще рисует рамку

format
Все что угодно из латекса. Ставится перед заголовком и действует на метку и заголовок. Цвет, шрифт, размер и пр.
\titleformat{\section}[display]
{\color{red}\fontsize{120}{20}\boldfont}
{\vbox{\hfil\thesection}\hfil}{0em}
{\LARGE\uppercase{#1}}
label
метка раздела. Чтобы все работало корректно лучше ставить, если предусмотрено стилем. Т.к., когда будет применяться команда заголовка со *, то номер подавится автоматически.
\thesection
\thesubsection
\thesubsubsection
...
sep
отступ от метки. Тоже нельзя оставлять пустым. 0pt но поставь.
before-code
самая звездная штука. В нее можно поставить вообще все и в качестве аргумента вляпать #1 как текст заголовка.
\titleformat{\section}
{\LARGE\boldfontwhite}
{}{.5em}
{\colorbox{BleuLBA}{\parbox{21cm}{\rule[-5pt]{0pt}{21pt}\hspace{1.5cm}\thesection\, \uppercase{#1}}}}
это я сделал для французов в синей рамочке белыми буквами. Но тут есть одна ошибка. Надеюсь с ней разобраться. Это номер заголовка.

after-code
тоже самое, что и before, только код ставит после заголовка. Любой!
chaptertitlename
изменяет название главы по умолчанию
\renewcommand{\chaptertitlename}{Новое название главы}
titlespacing
\titlespacing*{⟨command ⟩}{⟨left⟩}{⟨before-sep⟩}{⟨after-sep⟩}[⟨right-sep⟩]
Нужная команда для настроек пространства заголовка
Версия со звездочкой убирает отступ абзаца, следующего за заголовком, за исключением случаев удаления, переноса и запуска, где эта возможность не имеет смысла.
command
команда заголовка \section и т.д.
left
обязательный параметр, может быть положительный и отрицательный делает отступ заголовка влево и вправо.
Помогает при настройке с параметром drop и wrap.
before-sep
буквально вертикаьный отступ перед заголовком
after-sep
двигает текст после заголовка вертикально и горизонтально. Важен при настройке текста с обтеканием.
right-sep
необязательный параметр для установки отступа справа для установок с hang, block и display. Помогает залезать в правое поле. Это \beforetitleunit и \aftertitleunit тонкие настройки клея в заголовках. Я не использую.
А теперь я добился того, ради чего затевал этот конспект. Я настроил заголовок без ошибок:
%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%5000
\titleformat{\section} [hang]
{\LARGE\boldfontwhite}
{\llap{\colorbox{BleuLBA}{\parbox{2cm}{\rule[-5pt]{0pt}{21pt}\filleft\thesection}}}}{0em}
{\colorbox{BleuLBA}{\parbox{21cm}{\rule[-5pt]{0pt}{21pt}\filright \uppercase{#1}}}}
\titlespacing{\section} {0pc}{2.5ex plus .1ex minus .2ex}{3.5ex minus .1ex}[0pc]
Результат смотрим ниже:

Дополнительные команды выравнивания
\filright \filcenter \filleft \fillast \filinner \filouter
в принципе благодаря им очень хорошо настроил и решил свою задачу выше.
Они заполняют пространство перед или после заголовкаа, в зависимости от названия.
\wordsep — пространство между слов в заголовке
indentafter noindentafter — обходит настройки отступов страницы
rigidchapters rubberchapters — регулирует пространство между титулом главы и текстом.
bottomtitles nobottomtitles nobottomtitles*
Устанавливаем минимальное пространство внизу страницы, чтобы заголовок не переносился на новую страницу.
\renewcommand{\bottomtitlespace}{⟨length ⟩}
aftersep largestsep
По умолчанию, когда есть два последовательных заголовка, между ними используется пространство ⟨after-sep⟩ от первого. Иногда это нежелательное поведение, особенно когда пространство ⟨before-sep⟩ намного больше, чем пространство ⟨after-sep⟩ (в противном случае предпочтительнее выглядит значение по умолчанию).
pageatnewline — этот странный параметр насильно разрывает заголовок на разные страницы, хотя по умолчанию команды \\ \\* подавлены.
\nostruts nostruts — подавляет умничество latex при изменении высоты пространства в заголовках.
RULES
Добавляет линии под заголовками и не только.
\titleline[⟨align⟩]{⟨horizontal material ⟩}
\titlerule[⟨height ⟩]
\titlerule*[⟨width ⟩]{⟨text ⟩}
Можно добавить прямо в текст и получить результат для одного заголовка:
\section{Title first}
\label{sec:title-first}
\titlerule[.8pt]%
\vspace{1pt}%
\titlerule
или можно эту же конструкцию добавить в настройки \titleformat.

calcwidth — изменяет формат переноса строк для режима wrap
PAGE STYLES
\assignpagestyle{⟨command ⟩}{⟨pagestyle⟩}
...
\assignpagestyle{\chapter}{empty}
любой главе или странице можно назначить стиль по умолчанию.
Breaks
\sectionbreak \subsectionbreak \subsubsectionbreak \paragraphbreak \subparagraphbreak \⟨section⟩break
\newcommand{\sectionbreak}{\clearpage}
или
\newcommand{\sectionbreak}{%
\addpenalty{-300}%
\vspace*{0pt}}
эта утилита настраивает автоматический разрыв страниц при достижения заданных параметров в разделах.
\chaptertolists — изменяет отступы перед заголовками
\newcommand{\chaptertolists}{}
а этот будет пустой
Команды в преамбуле
explicit
позволяет указывать в titleformat #1 как место для текста заголовка
\titleformat{\section}
{..}
{\thesection}{..}{#1.}
newparttoc oldparttoc
используется если \part была переопределена, помогает настроить TOC
clearempty
Изменяет поведение \cleardoublepage, чтобы на пустых страницах использовался стиль пустой страницы.
toctitles
Изменяет поведение необязательного аргумента в заголовках разделов, так что он устанавливает только заголовки в квадратных скобках, а не записи оглавления, которые будут основаны на полном заголовке.
newlinetospace
Заменяет каждое вхождение символов \ или \* в заголовках на пробел в заголовках и записях оглавления.
Расширенные настройки
⟨key⟩=⟨value⟩, ⟨key⟩=⟨value⟩, ⟨key⟩, ⟨key⟩,...
Первый аргумент как \titleformat, так и \titlespaceing имеет расширенный синтаксис, который позволяет устанавливать разные форматы в зависимости от контекста.
name=Допустимые значения: \chapter, \section и т. д.page=Допустимые значения: odd или even.numberlessБесполезный ключ. В этом нет необходимости, если вы не хотите установить разные нумерованные (без этого ключа) и ненумерованные (с безномерными) варианты.
\titleformat{name=\section,page=even}[leftmargin]
{\filleft\scshape}{\thesection}{.5em}{}
\titleformat{name=\section,page=odd}[rightmargin]
{\filright\scshape}{\thesection}{.5em}{}
Создание новыхуровней заголовков
\titleclass{⟨name ⟩}{⟨class ⟩} \titleclass{⟨name⟩}{⟨class⟩}[⟨super-level-cmd ⟩]
Существует три класса:
page— это часть книги, на одной странице,top— это \chapter, который начинает страницу и помещает заголовок вверху,straightпредназначен для заголовков в середине текста.
В первом случае \titleclass{\part}{straight} заменяется просто класс.
Во втором случае, можно создать новые подуровни:
\titleclass{\subchapter}{straight}[\chapter] %новый класс
\newcounter{subchapter} %новый счетчик
\renewcommand{\thesubchapter}{\Alph{subchapter}} %буквенный счетчик
уровни секций изменяются автоматически
Глава 0 – уровень \section — 1 уровень и т.д.
loadonly
Обнулит все настройки уровней и позволит создавать свои уровни с нуля.
\titleclass
\titleclass{⟨name ⟩}[⟨start-level-num ⟩]{⟨class ⟩}
добавляет высшего уровня заголовок (0) или (-1) и дальше создаем сои новые уровни.
FootNotes
В заголовки можно добавлять ссылки footnotes, но чтобы они не показывались в оглавлении нужно в преамбулу добавить:
\usepackage[stable]{footmisc}
Номер заголовка в BOX
Полезная вещь. Особенно когда колдуешь с отступами за пределы печатаемой области или работаешь с цветами.
\titleformat{\section}
{..}
{\makebox[2em]{\thesection}}{..}{..}
или
\titleformat{\section} [hang]
{\LARGE\boldfontwhite}
{\llap{\colorbox{BleuLBA}{\parbox{2cm}{\rule[-5pt]{0pt}{21pt}\filleft\thesection}}}}{0em}
{\colorbox{BleuLBA}{\parbox{21cm}{\rule[-5pt]{0pt}{21pt}\filright \uppercase{#1}}}}
Подавляет нумерацию заголовков
\setcounter{secnumdepth}{0}
или
\newenvironment{exercises}
{\setcounter{secnumdepth}{0}}
{\setcounter{secnumdepth}{2}}
или
\newenvironment{exercises}
{\setcounter{secnumdepth}{0}%
\addtocontents{toc}{\protect\setcounter{tocdepth}{0}\ignorespaces}}
{\setcounter{secnumdepth}{2}%
\addtocontents{toc}{\protect\setcounter{tocdepth}{2}\ignorespaces}}
Как пометить заголовки со сзвездочкой
\newcommand{\secmark}{}
\newenvironment{advanced}
{\renewcommand{\secmark}{*}}
{}
\titleformat{\section} {..}
{\thesection\secmark\quad}{..}{..}
В документе пишим
\begin{advanced}
\section{...} ...
\end{advanced}
Этот раздел будет со звездочкой.
Крутой код по настройке стилей страниц
\documentclass[14pt,a4paper,twoside]{extbook}
\usepackage[utf8]{inputenc} %
\usepackage[T1]{fontenc}
\usepackage{lmodern} %
\usepackage[pagestyles]{titlesec}
\usepackage[x11names]{xcolor} %
\usepackage{theorem}
\newtheorem{worked example}{Worked Example}[chapter]
\newtheorem{solution}{SOLUTION}[chapter]
%\usepackage{anyfontsize}
\usepackage{amsfonts}
\usepackage{textcomp}
\usepackage{enumerate}
\setlength\headheight{21pt}
\newcommand{\hsp}{\hspace{20pt}}
\newcommand{\ntl}{\newline \newline}
\titleformat{\chapter}[hang]{\fontsize{50}{60}\bfseries\color[rgb]{0,0.5,0.75}}{\thechapter\hsp\fontsize{90}{60}\selectfont\textcolor{black}{|}\hsp}{0pt}{\thispagestyle{empty}\Huge\bfseries}
\titleformat{\section}{\large\bfseries}{}{0pt}{\textcolor[rgb]{0,0.5,0.75}{Topic \thesection} \ }[{\titlerule[0.8pt]}]
\usepackage{blindtext}
\newpagestyle{mine}{%
\setlength\fboxsep{10pt}
\sethead[\bfseries\llap{\colorbox{SteelBlue3}{\parbox{\dimexpr\marginparsep + \marginparwidth\relax}{\hspace{20pt}\color{white}\thepage\vphantom{|}}}}%
\colorbox{SlateGray2!40}{\parbox{\dimexpr\linewidth-2\fboxsep}{~\thechapter~|\hspace{0.75em}\chaptertitle}}][][]%
{}{}{\bfseries\colorbox{SlateGray2!40}{\parbox{\dimexpr\linewidth-2\fboxsep}{\thesection~|\hspace{0.75em}\sectiontitle}}%
\rlap{\colorbox{SteelBlue3}{\parbox{\dimexpr\marginparsep + \marginparwidth\relax}{\hspace{20pt}\color{white}\thepage\vphantom{|}}}}}
\setfoot{}{}{}
}
\pagestyle{mine}
\begin{document}
\chapter{{NUMBER}}%\textcolor{black}
\section{BIDMAS.}
\blindtext[10]
\end{document}
Выдает шикарную вещь:

7.14 - Пакет fontenc - Управление кодировками шрифтов в LaTeX
Загрузка шрифтов в Latex. Package titlesec
Пакет fontenc - Управление кодировками шрифтов в LaTeX
Введение
Пакет fontenc является критически важным для правильного отображения текста в LaTeX-документах, особенно при работе с не-ASCII символами (кириллицей, диакритическими знаками и др.).
Установка и базовое использование
\usepackage[<кодировки>]{fontenc}
Основные кодировки
Для латинских алфавитов:
T1- Расширенная латинская кодировка (поддержка акцентов, лигатур)OT1- Базовая кодировка TeX (устаревшая)
Для кириллицы:
T2A- Основная кириллическая кодировкаT2B- Альтернативная кириллическая кодировкаT2C- Дополнительная кириллическая кодировка
Примеры комбинаций:
\usepackage[T1,T2A]{fontenc} % Латинские и кириллические символы
\usepackage[T1]{fontenc} % Только латинские символы
Полный список поддерживаемых кодировок
| Кодировка | Описание |
|---|---|
| OT1 | Базовая кодировка TeX |
| T1 | Расширенная латинская |
| T2A | Основная кириллица |
| T2B | Альтернативная кириллица |
| T2C | Дополнительная кириллица |
| LY1 | Улучшенная кодировка для LaTeX |
| … | Другие специализированные кодировки |
Команды пакета
Основные команды:
\fontencoding{<кодировка>}- Переключает текущую кодировку шрифта\selectfont- Применяет изменения кодировки
Пример использования команд:
{\fontencoding{T1}\selectfont Текст в T1 кодировке}
{\fontencoding{T2A}\selectfont Текст в T2A кодировке}
Практические примеры
Пример 1: Базовое использование
\usepackage[T1,T2A]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[english,russian]{babel}
\begin{document}
Латинские символы: Café, naïve
Кириллические символы: Пример русского текста
\end{document}
Пример 2: Смешение кодировок в документе
{\fontencoding{T1}\selectfont
This text uses T1 encoding for proper hyphenation of words like "naïve".}
{\fontencoding{T2A}\selectfont
Этот текст использует кодировку T2A для корректного отображения кириллицы.}
Пример 3: Определение нового кодированного шрифта
\DeclareFontFamily{T2A}{cmr}{}
\DeclareFontShape{T2A}{cmr}{m}{n}{<-> ecrm1000}{}
Проблемы и решения
Проблема 1: Неправильное отображение кириллицы
Решение:
\usepackage[T2A]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[russian]{babel}
Проблема 2: Разрывы слов с диакритическими знаками
Решение:
\usepackage[T1]{fontenc} % Для правильного разрыва слов типа "naïve"
Проблема 3: Конфликты кодировок
Решение: Явное указание кодировок:
\usepackage[T1,T2A]{fontenc}
Совместимость с другими пакетами
С inputenc:
\usepackage[T1,T2A]{fontenc}
\usepackage[utf8]{inputenc} % Рекомендуется всегда использовать utf8
С babel:
\usepackage[T1,T2A]{fontenc}
\usepackage[english,russian]{babel}
С современными шрифтовыми пакетами (fontspec):
\usepackage{fontspec} % Для XeLaTeX/LuaLaTeX
% fontenc не нужен при использовании fontspec
Расширенные возможности
Определение собственных кодировок:
\DeclareFontEncoding{XYZ}{}{}
\DeclareErrorFont{XYZ}{cmr}{m}{n}{10}
Настройка подстановок шрифтов:
\DeclareFontSubstitution{T2A}{cmr}{m}{n}
Рекомендации
- Для документов с кириллицей всегда используйте:
\usepackage[T2A]{fontenc} - Для документов с европейскими языками:
\usepackage[T1]{fontenc} - Для многоязычных документов:
\usepackage[T1,T2A]{fontenc} - При использовании XeLaTeX/LuaLaTeX вместо
fontencиспользуйтеfontspec
Заключение
Пакет fontenc обеспечивает критически важную функциональность для правильного отображения текста в различных языках. Правильная настройка кодировок шрифтов предотвращает множество проблем с отображением символов и переносом слов.
7.15 - Пакет fontspec - Управление кодировками шрифтов в XeLaTeX
Введение в fontspec
Пакет fontspec предоставляет мощную систему выбора и настройки шрифтов для движков XeTeX и LuaTeX. Он заменяет традиционный подход с использованием fontenc и inputenc, предлагая прямую работу со шрифтами системы через Unicode.
Основные возможности
- Доступ к любым системным шрифтам (OTF, TTF)
- Полная поддержка Unicode
- Гибкое управление начертаниями шрифтов
- Настройка параметров шрифтов
- Работа с OpenType-функциями
Установка и загрузка
\usepackage{fontspec} % В преамбуле документа
Основные команды
1. Установка основного шрифта
\setmainfont{<название шрифта>}[<опции>]
Пример:
\setmainfont{TeX Gyre Termes}[
Path = /usr/local/texlive/texmf-local/fonts/opentype/,
Extension = .otf,
UprightFont = *-regular,
BoldFont = *-bold,
ItalicFont = *-italic,
BoldItalicFont = *-bolditalic
]
2. Установка моноширинного шрифта
\setmonofont{<название шрифта>}[<опции>]
3. Установка шрифта без засечек
\setsansfont{<название шрифта>}[<опции>]
4. Временное изменение шрифта
\newfontfamily\<команда>{<название шрифта>}[<опции>]
Пример:
\newfontfamily\cyrillicfont{PT Serif}
\newfontfamily\cyrillicfontsf{PT Sans}
\newfontfamily\cyrillicfonttt{PT Mono}
Основные опции шрифтов
Пути и файлы
| Опция | Описание |
|---|---|
Path | Путь к файлам шрифтов |
Extension | Расширение файлов |
UprightFont | Обычное начертание |
BoldFont | Полужирное начертание |
ItalicFont | Курсивное начертание |
BoldItalicFont | Полужирный курсив |
Характеристики шрифта
| Опция | Описание |
|---|---|
Ligatures | Управление лигатурами |
Numbers | Стиль цифр |
Scale | Масштабирование |
Color | Цвет шрифта |
WordSpace | Межсловные пробелы |
OpenType-функции
| Опция | Описание |
|---|---|
Renderer | Рендерер (Basic/Node) |
Script | Скрипт (Cyrillic, Latin и др.) |
Language | Язык |
FeatureFile | Файл с OpenType-фичами |
Примеры конфигураций
Базовая настройка для русского/английского
\usepackage{polyglossia}
\setmainlanguage{russian}
\setotherlanguage{english}
\setmainfont{PT Serif}[
Ligatures=TeX,
Extension=.ttf,
UprightFont=*-Regular,
BoldFont=*-Bold,
ItalicFont=*-Italic,
BoldItalicFont=*-BoldItalic
]
\setsansfont{PT Sans}[
Ligatures=TeX,
Extension=.ttf,
UprightFont=*-Regular,
BoldFont=*-Bold,
ItalicFont=*-Italic,
BoldItalicFont=*-BoldItalic
]
\setmonofont{PT Mono}[
Scale=0.9,
Extension=.ttf,
UprightFont=*-Regular
]
Использование разных шрифтов для разных языков
\usepackage{polyglossia}
\setdefaultlanguage{russian}
\setotherlanguage{english}
\defaultfontfeatures{Ligatures=TeX}
\setmainfont{EB Garamond}[
Language=English,
Script=Latin
]
\newfontfamily\cyrillicfont{PT Serif}[
Language=Russian,
Script=Cyrillic
]
OpenType-фичи
Включение дополнительных возможностей
\setmainfont{Some Font}[
RawFeature={
+ss01; % Альтернативные глифы
+onum; % Старостильные цифры
+frac; % Дроби
+c2sc; % Капитель из прописных
}
]
Доступные OpenType-фичи
+liga- стандартные лигатуры+dlig- декоративные лигатуры+tnum- табличные цифры+pnum- пропорциональные цифры+smcp- капитель из строчных+c2sc- капитель из прописных+frac- дроби+ss01-+ss20- альтернативные наборы глифов
Работа с математическими шрифтами
\usepackage{unicode-math} % Должен загружаться после fontspec
\setmathfont{TeX Gyre Termes Math}
\setmathfont{XITS Math}[range={\mathcal,\mathbfcal}]
\setmathfont{STIX Two Math}[range={\mathscr}]
Продвинутые техники
Динамическое изменение шрифтов
\newfontfamily\headfont{Helvetica Neue}[Scale=1.2]
\newcommand{\heading}[1]{{\headfont\Large #1}}
Использование символов за пределами Unicode BMP
\newfontface\emojifont{Segoe UI Emoji}[Renderer=Harfbuzz]
\newcommand{\showemoji}[1]{{\emojifont #1}}
Вертикальное выравнивание
\newfontfamily\vertfont{SomeFont}[Vertical=RotatedGlyphs]
Решение проблем
Шрифт не находится
\setmainfont{Arial}[
Path=/Users/username/Library/Fonts/,
Extension=.ttf
]
Конфликты кодировок
\usepackage{fontspec}
% Не загружать fontenc или inputenc!
Проблемы с переносами
\usepackage{polyglossia}
\setmainlanguage{russian}
\setmainfont{Some Font}[Language=Russian]
Заключение
Пакет fontspec предоставляет:
- Полный доступ к системным шрифтам
- Гибкую систему настройки шрифтов
- Поддержку современных OpenType-возможностей
- Удобную работу с многоязычными документами
- Интеграцию с математическими шрифтами через
unicode-math
Для максимальной эффективности используйте fontspec в сочетании с:
polyglossiaдля языковой поддержкиunicode-mathдля математических шрифтовmicrotypeдля улучшенной типографики
8 - opensearch
Неудивительно, что разработчики часто используют поисковые системы, такие как OpenSearch, в качестве бэкенда для поисковых приложений — например, для Википедии или интернет-магазинов. Он обеспечивает отличную производительность и может масштабироваться в зависимости от потребностей приложения.
Ещё один популярный, но менее очевидный сценарий использования — анализ логов. В этом случае логи приложения загружаются в OpenSearch, а мощные функции поиска и визуализации помогают выявлять проблемы. Например, неисправный веб-сервер может выдавать ошибку 500 в 0,5% случаев, что сложно заметить без графика в реальном времени, отображающего все HTTP-статусы за последние четыре часа. С помощью OpenSearch Dashboards можно создавать такие визуализации на основе данных из OpenSearch.
Компоненты
OpenSearch — это не только поисковый движок. В его состав также входят:
- OpenSearch Dashboards — интерфейс для визуализации данных OpenSearch.
- Data Prepper — серверный сборщик данных, способный фильтровать, обогащать, преобразовывать, нормализовать и агрегировать данные для последующего анализа и визуализации.
- Клиенты — языковые API, позволяющие взаимодействовать с OpenSearch на популярных языках программирования.
Сценарии использования
OpenSearch поддерживает множество сценариев, например:
- Наблюдаемость (Observability) — визуализация событий на основе данных с помощью Piped Processing Language (PPL) для исследования, обнаружения и запросов к данным в OpenSearch.
- Поиск — выбор оптимального метода поиска для вашего приложения: от стандартного лексического поиска до диалогового поиска на базе машинного обучения (ML).
- Машинное обучение — интеграция ML-моделей в приложения на OpenSearch.
- Анализ безопасности — расследование, обнаружение, анализ и реагирование на угрозы, которые могут повлиять на успех организации и её онлайн-операции.
Следующие шаги
- Ознакомьтесь с [Введением в OpenSearch](Introduction to OpenSearch), чтобы изучить основные концепции OpenSearch.
8.1 - Введение в Opensearch
Введение в OpenSearch
Термин распределённая означает, что OpenSearch можно запускать на нескольких компьютерах. Поиск и аналитика подразумевают, что после загрузки данных в OpenSearch их можно искать и анализировать. Независимо от типа данных, их можно хранить и исследовать с помощью OpenSearch.
Документ
Документ — это единица хранения информации (текстовой или структурированной). В OpenSearch документы хранятся в формате JSON.
Документ можно представить несколькими способами:
- В базе данных студентов документ может представлять одного учащегося.
- При поиске информации OpenSearch возвращает документы, соответствующие запросу.
- Документ аналогичен строке в традиционной реляционной базе данных.
Например, в школьной базе данных документ может представлять студента и содержать следующие данные:
| ID | Имя | GPA | Год выпуска |
|---|---|---|---|
| 1 | John Doe | 3.89 | 2022 |
Вот как этот документ выглядит в формате JSON:
{
"name": "John Doe",
"gpa": 3.89,
"grad_year": 2022
}
Вы узнаете, как назначаются идентификаторы документов, в разделе Индексация документов.
Индекс
Индекс — это коллекция документов.
Индекс можно рассматривать несколькими способами:
- В базе данных студентов индекс представляет всех учащихся в базе.
- При поиске информации запрос выполняется к данным внутри индекса.
- Индекс соответствует таблице в традиционной реляционной базе данных.
Например, в школьной базе данных индекс может содержать всех студентов школы:
| ID | Имя | GPA | Год выпуска |
|---|---|---|---|
| 1 | John Doe | 3.89 | 2022 |
| 2 | Jonathan Powers | 3.85 | 2025 |
| 3 | Jane Doe | 3.52 | 2024 |
| … | … | … | … |
Кластеры и узлы
OpenSearch разработан как распределённая поисковая система, что означает возможность работы на одном или нескольких узлах — серверах, хранящих данные и обрабатывающих поисковые запросы. Кластер OpenSearch — это совокупность таких узлов.
Вы можете запустить OpenSearch локально на ноутбуке (системные требования минимальны), но также можно масштабировать кластер до сотен мощных серверов в дата-центре.
В одноузловом кластере (например, развёрнутом на ноутбуке) одна машина выполняет все задачи:
- управляет состоянием кластера,
- индексирует данные и обрабатывает поисковые запросы,
- выполняет предварительную обработку данных перед индексацией.
Однако по мере роста кластера обязанности можно распределить:
- Узлы с быстрыми дисками и большим объёмом ОЗУ подходят для индексации и поиска.
- Узлы с мощными CPU, но малым дисковым пространством, могут управлять состоянием кластера.
В каждом кластере выбирается главный узел (cluster manager node), который координирует операции на уровне кластера (например, создание индекса). Узлы взаимодействуют между собой: если запрос направлен к одному узлу, он может запрашивать данные у других узлов, агрегировать их ответы и возвращать итоговый результат.
Подробнее о других типах узлов см. в разделе Формирование кластера.
Шарды (Shards)
OpenSearch разделяет индексы на шарды. Каждый шард хранит подмножество всех документов индекса, как показано на следующей диаграмме:

Шарды используются для равномерного распределения данных между узлами кластера. Например:
- Индекс размером 400 ГБ может быть слишком большим для обработки на одном узле
- Если разделить его на 10 шардов по 40 ГБ каждый, OpenSearch сможет распределить их между 10 узлами
- Каждый шард будет обрабатываться независимо
Рассмотрим кластер с двумя индексами:
- Индекс 1 разделён на 2 шарда
- Индекс 2 разделён на 4 шарда
Эти шарды распределены между двумя узлами, как показано на схеме:

Хотя каждый шард является частью индекса OpenSearch, технически он представляет собой полноценный индекс Lucene. Это важно учитывать, потому что:
- Каждый экземпляр Lucene - это отдельный процесс
- Каждый процесс потребляет ресурсы CPU и памяти
- Слишком большое количество шардов может перегрузить кластер
Рекомендации по работе с шардами:
- Не стоит разделять индекс на чрезмерное количество шардов
- Например, деление индекса 400 ГБ на 1000 шардов создаст ненужную нагрузку
- Оптимальный размер шарда - от 10 до 50 ГБ
Первичные и реплицированные шарды
В OpenSearch шарды могут быть двух типов:
- Первичные (primary) - оригинальные шарды
- Реплики (replica) - копии шардов
По умолчанию OpenSearch создаёт по одной реплике для каждого первичного шарда. Таким образом:
- Если индекс разделён на 10 шардов, будет создано 10 реплик
- В примере из предыдущего раздела (2 индекса):
- Индекс 1: 2 шарда + 2 реплики
- Индекс 2: 4 шарда + 4 реплики

Функции реплик:
- Резервное копирование на случай сбоя узла
- Реплики размещаются на разных узлах от первичных шардов
- Ускорение обработки поисковых запросов
- Для нагрузок с интенсивным поиском можно создать несколько реплик
Инвертированный индекс
OpenSearch использует структуру данных под названием инвертированный индекс, которая:
- Сопоставляет слова с документами, где они встречаются
- Пример для двух документов:
- Документ 1: “Красота в глазах смотрящего”
- Документ 2: “Красавица и чудовище”
Инвертированный индекс будет выглядеть так:
| Слово | Документы |
|---|---|
| красота | 1 |
| в | 1 |
| глазах | 1 |
| смотрящего | 1 |
| красавица | 2 |
| и | 2 |
| чудовище | 2 |
Дополнительно OpenSearch хранит:
- Позиции слов в документах
- Это позволяет выполнять поиск по фразам
Релевантность
При поиске OpenSearch:
- Сопоставляет слова запроса с документами
- Присваивает каждому документу оценку релевантности
Факторы оценки:
- Частота термина (TF):
- Чем чаще слово встречается в документе, тем выше оценка
- Обратная частота документа (IDF):
- Редкие слова имеют больший вес (например, “аксолотль” vs “синий”)
- Нормализация по длине:
- Более короткие документы получают преимущество
OpenSearch использует алгоритм BM25 для расчёта релевантности и сортировки результатов.
Следующие шаги
Узнайте, как быстро установить OpenSearch, в разделе Быстрый старт установки.
8.1.1 - Быстрый старт установки
Для быстрого запуска OpenSearch и OpenSearch Dashboards используйте контейнеры Docker. Полное руководство по установке доступно в разделе Установка и обновление OpenSearch.
Предварительные требования:
- Установите Docker и Docker Compose на локальную машину
Запуск кластера
Настройка системы
Перед запуском рекомендуется:- Отключить подкачку памяти для повышения производительности:
sudo swapoff -a - Увеличить максимальное количество memory maps:Добавьте строку:
sudo vi /etc/sysctl.confПримените изменения:vm.max_map_count=262144sudo sysctl -p
- Отключить подкачку памяти для повышения производительности:
Получение файла конфигурации
Загрузите образецdocker-compose.yml:- Через cURL:
curl -O https://raw.githubusercontent.com/opensearch-project/documentation-website/3.1/assets/examples/docker-compose.yml - Через wget:
wget https://raw.githubusercontent.com/opensearch-project/documentation-website/3.1/assets/examples/docker-compose.yml
- Через cURL:
Запуск кластера
Перейдите в директорию с файлом и выполните:docker compose up -dПроверьте статус контейнеров:
docker compose psОжидаемый вывод:
NAME COMMAND SERVICE STATUS PORTS opensearch-dashboards "./opensearch-dashbo…" opensearch-dashboards running 0.0.0.0:5601->5601/tcp opensearch-node1 "./opensearch-docker…" opensearch-node1 running 0.0.0.0:9200->9200/tcp, 9300/tcp, 0.0.0.0:9600->9600/tcp, 9650/tcp opensearch-node2 "./opensearch-docker…" opensearch-node2 running 9200/tcp, 9300/tcp, 9600/tcp, 9650/tcpПроверка работы
Выполните тестовый запрос к API:curl https://localhost:9200 -ku admin:ВАШ_ПАРОЛЬУспешный ответ:
{ "name": "opensearch-node1", "cluster_name": "opensearch-cluster", "version": { "distribution": "opensearch", "number": "2.6.0" }, "tagline": "The OpenSearch Project: https://opensearch.org/" }Доступ к Dashboards
Откройте в браузере:http://localhost:5601/
Логин:admin
Пароль: указан вOPENSEARCH_INITIAL_ADMIN_PASSWORDфайла docker-compose.yml
Примечания:
- Для безопасности отключается проверка хоста (
-k) при использовании демо-сертификатов - Все команды предполагают работу в Linux-окружении
- Пароль администратора задаётся при первом запуске
Распространённые проблемы
Рассмотрите эти типичные проблемы и способы их решения, если контейнеры не запускаются или завершаются неожиданно.
Необходимость прав sudo для Docker команд
Проблема:
Требуется использовать sudo для выполнения Docker команд.
Решение:
Добавьте пользователя в группу docker:
sudo usermod -aG docker $USER
Подробнее: Post-installation steps for Linux
Ошибка: “-bash: docker-compose: command not found”
Ситуация:
При использовании Docker Desktop.
Решение:
Используйте команду без дефиса:
docker compose
См. документацию Docker Compose
Ошибка: “docker: ‘compose’ is not a docker command”
Ситуация:
При использовании Docker Engine.
Решение:
Установите Docker Compose отдельно и используйте команду с дефисом:
docker-compose
Ошибка: “max virtual memory areas vm.max_map_count [65530] is too low”
Симптомы:
В логах сервиса появляется сообщение:
opensearch-node1 | ERROR: [1] bootstrap checks failed
opensearch-node1 | [1]: max virtual memory areas vm.max_map_count [65530] is too low...
Решение:
Увеличьте значение vm.max_map_count (см. раздел “Важные системные настройки”):
sudo sysctl -w vm.max_map_count=262144
Альтернативные способы установки
Помимо Docker, OpenSearch можно установить:
- На различные дистрибутивы Linux
- На Windows
Полные руководства: Установка и обновление OpenSearch
Дальнейшее изучение
После успешного развёртывания кластера рекомендуется изучить:
Следующие шаги
Ознакомьтесь с разделом Взаимодействие с OpenSearch, чтобы узнать как отправлять запросы в систему.
8.1.2 - Взаимодействие с OpenSearch
На этой странице рассматривается REST API. Список доступных клиентов для языков программирования вы найдёте в разделе Клиенты.
REST API OpenSearch
REST API предоставляет гибкий способ взаимодействия с кластерами OpenSearch. Через API вы можете:
- Изменять настройки OpenSearch
- Управлять индексами
- Проверять состояние кластера
- Получать статистику
- И многое другое
Для отправки запросов можно использовать:
- Командную строку (cURL)
- Консоль Dev Tools в OpenSearch Dashboards
- Любой язык программирования с поддержкой HTTP-запросов
Отправка запросов через терминал
Формат запросов зависит от использования плагина безопасности.
Без плагина безопасности:
curl -X GET "http://localhost:9200/_cluster/health"
С плагином безопасности (требуются учётные данные):
curl -X GET "https://localhost:9200/_cluster/health" -ku admin:ВАШ_ПАРОЛЬ
По умолчанию:
- Логин:
admin - Пароль: задаётся в параметре
OPENSEARCH_INITIAL_ADMIN_PASSWORDфайла docker-compose.yml
Форматирование ответа:
Для удобочитаемого JSON добавьте параметр pretty:
curl -X GET "https://localhost:9200/_cluster/health?pretty"
Запросы с телом:
Укажите заголовок Content-Type и передайте данные через параметр -d:
curl -X GET "https://localhost:9200/students/_search?pretty" \
-H 'Content-Type: application/json' \
-d '{
"query": {
"match_all": {}
}
}'
Отправка запросов через Dev Tools
Консоль Dev Tools в OpenSearch Dashboards использует упрощённый синтаксис:
- Откройте Dashboards:
https://localhost:5601/ - Перейдите: Management > Dev Tools
- Введите запрос (например):
GET _cluster/health - Отправьте запрос:
- Клик по иконке ▶
- Ctrl+Enter (Cmd+Enter на Mac)
В документации OpenSearch запросы чаще всего приводятся в формате Dev Tools.
Дополнительно:
Индексация документов
Для добавления JSON-документа в индекс OpenSearch (индексации документа) отправьте HTTP-запрос со следующим форматом:
PUT https://<хост>:<порт>/<имя-индекса>/_doc/<идентификатор-документа>
Пример индексации документа о студенте:
PUT /students/_doc/1
{
"name": "Иван Иванов",
"gpa": 4.5,
"grad_year": 2023
}
После выполнения запроса:
- OpenSearch создаст индекс
students(если не существует) - Сохранит документ с указанным ID (
1) - Если ID не указан - сгенерирует его автоматически
Динамическое маппинг
OpenSearch автоматически определяет типы полей на основе JSON-структуры документа.
Просмотр схемы полей:
GET /students/_mapping
Пример ответа:
{
"students": {
"mappings": {
"properties": {
"gpa": {"type": "float"},
"grad_year": {"type": "long"},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
Особенности типов:
- Числовые значения:
float,long - Текстовые поля:
- Основное поле (
text): для полнотекстового поиска (с анализом) - Подполе (
keyword): для точного поиска по терминам
- Основное поле (
Важно: Для изменения типов (например, преобразования grad_year в дату) требуется пересоздание индекса с явным указанием маппинга.
Поиск документов
Базовый запрос (возвращает все документы):
GET /students/_search
{
"query": {
"match_all": {}
}
}
Пример ответа:
{
"took": 12,
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"hits": [
{
"_index": "students",
"_id": "1",
"_score": 1,
"_source": {
"name": "Иван Иванов",
"gpa": 4.5,
"grad_year": 2023
}
}
]
}
}
Ключевые элементы ответа:
took: время выполнения (мс)hits.total: количество найденных документовhits.hits: массив результатов_score: релевантность документа
Дополнительные материалы:
Обновление документов
В OpenSearch документы неизменяемы, но их можно обновить, полностью заменив содержимое или изменив отдельные поля.
Полное обновление (переиндексация)
Используйте Index Document API для полного обновления:
PUT /students/_doc/1
{
"name": "Иван Иванов",
"gpa": 4.7, // Обновлённое значение
"grad_year": 2023,
"address": "ул. Ленина, 123" // Новое поле
}
Частичное обновление
Используйте Update Document API для изменения отдельных полей:
POST /students/_update/1/
{
"doc": {
"gpa": 4.7,
"address": "ул. Ленина, 123"
}
}
Удаление данных
Удаление документа
DELETE /students/_doc/1
Удаление индекса
DELETE /students
Настройка индексов
Маппинги и параметры
Индексы настраиваются через:
- Маппинги - определяют типы полей
- Параметры - настройки индекса (количество шардов и т.д.)
Пример создания индекса с явными настройками:
PUT /students
{
"settings": {
"index.number_of_shards": 1
},
"mappings": {
"properties": {
"name": {"type": "text"},
"grad_year": {"type": "date"}
}
}
}
Проверка маппинга:
GET /students/_mapping
Важно:
- Типы полей нельзя изменить после создания
- Для изменения требуется пересоздание индекса
Дополнительные материалы
Следующие шаги
Ознакомьтесь с разделом Загрузка данных в OpenSearch для изучения способов импорта данных.
8.1.3 - Загрузка данных в OpenSearch
Существует несколько способов импорта данных:
Добавление отдельных документов
См. раздел Индексация документовМассовая загрузка документов
См. раздел Пакетная индексацияИспользование Data Prepper
Серверного сборщика данных OpenSearch для обработки перед анализомДругие инструменты
См. Инструменты OpenSearch
Пакетная индексация
Для массовой загрузки используйте Bulk API:
POST _bulk
{ "create": { "_index": "students", "_id": "2" } }
{ "name": "Алексей Петров", "gpa": 4.2, "grad_year": 2025 }
{ "create": { "_index": "students", "_id": "3" } }
{ "name": "Мария Смирнова", "gpa": 4.8, "grad_year": 2024 }
Работа с тестовыми данными
OpenSearch предоставляет демонстрационный набор данных электронной коммерции.
Шаги для создания тестового индекса:
Скачайте файлы:
# Маппинг полей curl -O https://raw.githubusercontent.com/.../ecommerce-field_mappings.json # Данные для загрузки curl -O https://raw.githubusercontent.com/.../ecommerce.ndjsonПримените схему полей:
curl -H "Content-Type: application/json" -X PUT "https://localhost:9200/ecommerce" \ -ku admin:ПАРОЛЬ --data-binary "@ecommerce-field_mappings.json"Загрузите данные:
curl -H "Content-Type: application/x-ndjson" -X POST "https://localhost:9200/ecommerce/_bulk" \ -ku admin:ПАРОЛЬ --data-binary "@ecommerce.ndjson"
Пример поиска:
GET ecommerce/_search
{
"query": {
"match": {
"customer_first_name": "Светлана"
}
}
}
Визуализация данных
Инструкции по работе с визуализациями см. в руководстве по OpenSearch Dashboards.
Дополнительные материалы
Следующие шаги
Изучите раздел Поиск по данным для получения информации о возможностях поиска.
8.1.4 - Поиск данных в OpenSearch
OpenSearch предлагает несколько методов поиска:
- Query DSL - основной язык запросов для сложных поисковых сценариев
- Query string - упрощённый синтаксис для параметров запроса
- SQL - традиционный язык запросов для реляционных данных
- PPL (Piped Processing Language) - язык для задач observability
- DQL (Dashboards Query Language) - текстовый язык фильтрации в Dashboards
Подготовка данных
Перед началом загрузим тестовые данные о студентах:
POST _bulk
{ "create": { "_index": "students", "_id": "1" } }
{ "name": "Иван Петров", "gpa": 4.5, "grad_year": 2023}
{ "create": { "_index": "students", "_id": "2" } }
{ "name": "Алексей Смирнов", "gpa": 4.2, "grad_year": 2025 }
{ "create": { "_index": "students", "_id": "3" } }
{ "name": "Мария Иванова", "gpa": 4.8, "grad_year": 2024 }
Базовые запросы
Получение всех документов:
GET /students/_search
Эквивалентно:
GET /students/_search
{
"query": { "match_all": {} }
}
Структура ответа:
took- время выполнения (мс)timed_out- флаг превышения таймаута_shards- статистика по шардамhits- результаты поиска:total- общее количество совпаденийmax_score- максимальная релевантностьhits- массив документов с оценкой релевантности
Query string поиск
Пример поиска по имени:
GET /students/_search?q=name:john
вернет ответ:
{
"took": 18,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.9808291,
"hits": [
{
"_index": "students",
"_id": "1",
"_score": 0.9808291,
"_source": {
"name": "John Doe",
"grade": 12,
"gpa": 3.89,
"grad_year": 2022,
"future_plans": "John plans to be a computer science major"
}
}
]
}
}
Полнотекстовый поиск (Query DSL)
Поиск с анализом текста:
GET /students/_search
{
"query": {
"match": {
"name": "иван" # Найдёт "Иван Петров" и "Мария Иванова"
}
}
}
{
"took": 13,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.9808291,
"hits": [
{
"_index": "students",
"_id": "1",
"_score": 0.9808291,
"_source": {
"name": "Иван Петров",
"gpa": 3.89,
"grad_year": 2022
}
}
]
}
}
Поиск по ключевым словам
Точное совпадение (без анализа):
GET /students/_search
{
"query": {
"match": {
"name.keyword": "john doe" # Только полное совпадение
}
}
}
{
"took": 19,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.9808291,
"hits": [
{
"_index": "students",
"_id": "1",
"_score": 0.9808291,
"_source": {
"name": "John Doe",
"gpa": 3.89,
"grad_year": 2022
}
}
]
}
}
Фильтры
Точное значение:
GET students/_search
{
"query": {
"bool": {
"filter": [
{ "term": { "grad_year": 2023 }}
]
}
}
}
Диапазон значений:
GET students/_search
{
"query": {
"bool": {
"filter": [
{ "range": { "gpa": { "gt": 4.0 }}}
]
}
}
}
Составные запросы
Комбинация условий:
GET students/_search
{
"query": {
"bool": {
"must": [
{ "match": { "name": "иван" } },
{ "range": { "gpa": { "gte": 4.0 } } },
{ "term": { "grad_year": 2023 }}
]
}
}
}
Расширенные возможности
OpenSearch поддерживает современные методы поиска:
- k-NN (поиск ближайших соседей)
- Семантический поиск
- Мультимодальный поиск
- Гибридный поиск
Дополнительные материалы
8.1.5 - Начало работы с безопасностью в OpenSearch
Демонстрационная конфигурация безопасности
Наиболее простой способ начать работу с безопасностью OpenSearch - использовать демонстрационную конфигурацию. OpenSearch включает полезные скрипты, в том числе:
install_demo_configuration.sh(для Linux/macOS)install_demo_configuration.bat(для Windows)
Расположение скрипта:plugins/opensearch-security/tools/
Действия скрипта:
- Создает демонстрационные сертификаты для TLS-шифрования на транспортном и REST-уровнях
- Настраивает тестовых пользователей, роли и привязки ролей
- Конфигурирует плагин безопасности для использования внутренней базы данных аутентификации
- Обновляет
opensearch.ymlбазовой конфигурацией для запуска кластера
Важно! Демонстрационные сертификаты и пароли по умолчанию не должны использоваться в production. Перед развертыванием в продакшене их необходимо заменить на собственные.
Настройка демонстрационной конфигурации
Перед запуском скрипта:
- Установите переменную окружения с надежным паролем администратора:
export OPENSEARCH_INITIAL_ADMIN_PASSWORD=<ваш_надежный_пароль> - Проверьте надежность пароля с помощью инструмента Zxcvbn
Запуск скрипта:
./plugins/opensearch-security/tools/install_demo_configuration.sh
Проверка конфигурации:
curl -k -XGET -u admin:<пароль> https://<ip-opensearch>:9200
Ожидаемый ответ:
{
"name": "smoketestnode",
"cluster_name": "opensearch",
"version": {
"distribution": "opensearch",
"number": "2.13.0"
},
"tagline": "The OpenSearch Project: https://opensearch.org/"
}
Настройка OpenSearch Dashboards
Добавьте в opensearch_dashboards.yml следующую конфигурацию:
opensearch.hosts: [https://localhost:9200]
opensearch.ssl.verificationMode: none
opensearch.username: kibanaserver
opensearch.password: kibanaserver
opensearch.requestHeadersWhitelist: [authorization, securitytenant]
opensearch_security.multitenancy.enabled: true
opensearch_security.multitenancy.tenants.preferred: [Private, Global]
opensearch_security.readonly_mode.roles: [kibana_read_only]
opensearch_security.cookie.secure: false # Отключено для HTTP
Запуск Dashboards:
yarn start --no-base-path
После запуска в логах появятся строки:
[info][listening] Server running at http://localhost:5601
[info][server][OpenSearchDashboards][http] http server running at http://localhost:5601
Доступ через браузер: http://localhost:5601
Логин: admin
Пароль: значение из OPENSEARCH_INITIAL_ADMIN_PASSWORD
Управление пользователями и ролями
1. Добавление пользователей
Способы:
- Редактирование
internal_users.yml - Использование API
- Через интерфейс OpenSearch Dashboards
Пример добавления пользователя в internal_users.yml:
test-user:
hash: "$2y$12$CkxFoTAJKsZaWv/m8VoZ6ePG3DBeBTAvoo4xA2P21VCS9w2RYumsG"
backend_roles:
- "test-backend-role"
- "kibanauser"
description: "Тестовый пользователь"
Генерация хеша пароля:
./plugins/opensearch-security/tools/hash.sh
Введите пароль (например, secretpassword), скопируйте полученный хеш.
2. Создание ролей
Формат roles.yml:
<имя_роли>:
cluster_permissions:
- <разрешение_кластера>
index_permissions:
- index_patterns:
- <шаблон_индекса>
allowed_actions:
- <разрешения_индекса>
Пример роли для доступа к индексу:
human_resources:
index_permissions:
- index_patterns:
- "humanresources"
allowed_actions:
- "READ"
3. Привязка пользователей к ролям
Формат roles_mapping.yml:
<имя_роли>:
users:
- <имя_пользователя>
backend_roles:
- <имя_роли>
Пример привязки:
human_resources:
backend_roles:
- "test-backend-role"
kibana_user:
backend_roles:
- "kibanauser"
Применение изменений конфигурации
После изменения файлов необходимо загрузить конфигурацию в security index:
./plugins/opensearch-security/tools/securityadmin.sh \
-cd "config/opensearch-security" \
-icl \
-key "../kirk-key.pem" \
-cert "../kirk.pem" \
-cacert "../root-ca.pem" \
-nhnv
Дальнейшие шаги
- Ознакомьтесь с Рекомендациями по безопасности OpenSearch
- Изучите Обзор конфигурации безопасности для кастомизации под ваши задачи
Примечания:
- Все команды предполагают выполнение из корневой директории OpenSearch
- Для production-окружений обязательно замените демонстрационные сертификаты
- Регулярно обновляйте пароли администраторов
8.1.6 - Основные концепции OpenSearch
Базовые понятия
Документ
Базовая единица информации в OpenSearch, хранимая в формате JSON. Представляет собой структурированные данные в виде пар “ключ-значение”.
Индекс
Коллекция логически связанных документов. Аналог таблицы в реляционных БД.
JSON (JavaScript Object Notation)
Текстовый формат для хранения данных, использующий структуру ключ-значение. Основной формат представления данных в OpenSearch.
Маппинг
Схема индекса, определяющая:
- Типы полей документов
- Способы индексации и хранения
- Параметры анализа текста
Архитектура кластера
Узел (Node)
Отдельный сервер, являющийся частью кластера OpenSearch.
Кластер
Совокупность узлов, работающих как единая система.
Управляющий узел (Cluster Manager)
Специальный узел, координирующий кластерные операции:
- Создание/удаление индексов
- Балансировка нагрузки
- Мониторинг состояния узлов
Шард (Shard)
Часть индекса, содержащая подмножество его данных. Индексы разделяются на шарды для:
- Горизонтального масштабирования
- Распределения нагрузки
Типы шардов:
- Первичный (Primary) - основной шард с данными
- Реплика (Replica) - копия первичного шарда для:
- Отказоустойчивости
- Повышения производительности поиска
Структуры данных и хранение
Doc Values
Оптимизированная on-disk структура для:
- Сортировки
- Агрегации
- Доступа к значениям полей
Инвертированный индекс
Структура данных, отображающая термины на документы, которые их содержат. Основа полнотекстового поиска.
Lucene
Библиотека поиска, лежащая в основе OpenSearch. Отвечает за:
- Индексацию
- Хранение
- Поиск данных
Сегмент (Segment)
Неизменяемая единица хранения данных внутри шарда. Особенности:
- Создается при операции refresh
- Объединяется в процессе merge
- Оптимизирован для быстрого поиска
Операции с данными
Ингestion
Процесс добавления данных в OpenSearch. Включает:
- Прием данных
- Парсинг
- Подготовку к индексации
Индексация
Процесс организации данных для эффективного поиска:
- Анализ текста
- Построение инвертированного индекса
- Хранение документов
Пакетная индексация
Массовая загрузка документов через Bulk API:
- Высокая производительность
- Минимизация сетевых издержек
- Атомарность операций
Анализ текста
Текстовый анализ
Процесс преобразования неструктурированного текста в последовательность терминов для индексации.
Компоненты анализатора:
Character Filter
Обрабатывает сырой текст:- Удаление/замена символов
- HTML-разметка
Tokenizer
Разбивает текст на токены (слова) с метаданными:- Позиция
- Длина
- Смещение
Token Filter
Модифицирует токены:- Приведение к нижнему регистру
- Удаление стоп-слов
- Добавление синонимов
- Стемминг
Типы анализаторов:
Analyzer
Полный конвейер обработки (character filter → tokenizer → token filter)Normalizer
Только character filter (без токенизации)
Стемминг
Приведение слов к базовой форме (например: “running” → “run”)
Поиск и запросы
Типы запросов:
- Query DSL - основной язык сложных запросов
- Query String - упрощенный синтаксис для URL
- DQL - язык фильтрации в Dashboards
- PPL - язык для observability с pipe-синтаксисом
Контексты выполнения:
Query Context
Оценивает релевантность (как хорошо документ соответствует запросу)Filter Context
Проверяет точное соответствие (да/нет) без расчета релевантности
Типы поиска:
Полнотекстовый
С учетом морфологии и вариаций словПо ключевым словам
Точное совпадение (без анализа)
Агрегации
Механизм анализа и суммирования данных:
- Метрики (avg, sum)
- Бакетизация (histogram, date_histogram)
- Вложенные агрегации
Жизненный цикл обновлений
Транзакционный лог (translog)
- Операция записывается в translog
- Гарантия durability через fsync
- Подтверждение клиенту
In-memory буфер
- Данные добавляются в буфер Lucene
- Еще не видны для поиска
Refresh
- Сброс буфера в сегменты
- Данные становятся видимыми для поиска
- Без гарантии durability
Flush
- Запись сегментов на диск (fsync)
- Очистка translog
- Гарантия сохранности данных
Merge
- Объединение мелких сегментов
- Оптимизация:
- Уменьшение количества файлов
- Освобождение места
- Улучшение производительности
Критические операции
Translog
Журнал операций для гарантии сохранности данных. Особенности:
- Записывается синхронно перед подтверждением
- Ограничен по размеру
- Очищается после flush
Refresh
Периодическая операция (по умолчанию каждые 1с):
- Делает данные доступными для поиска
- Создает новые сегменты
- Не гарантирует сохранность при сбое
Flush
Операция записи на диск:
- Обеспечивает durability
- Выполняется автоматически при:
- Достижении лимита translog
- Плановом обслуживании
Merge
Фоновая оптимизация:
- Управляется политикой слияния
- Регулирует:
- Частоту слияний
- Максимальный размер сегментов
- Параллелизм операций
8.2 - Install and upgrade OpenSearch
OpenSearch и OpenSearch Dashboards доступны на любом совместимом хосте, который поддерживает Docker (таких как Linux, MacOS или Windows). Кроме того, вы можете установить оба продукта на различных дистрибутивах Linux и на Windows.
Скачайте OpenSearch для вашей предпочтительной платформы, а затем выберите один из следующих руководств по установке.
| OpenSearch | OpenSearch Dashboards |
|---|---|
| Docker | Docker |
| Helm | Helm |
| Tarball | Tarball |
| RPM | RPM |
| Debian | Debian |
| Ansible playbook | |
| Windows | Windows |
После установки OpenSearch ознакомьтесь с его настройкой для вашего развертывания.
Для получения дополнительной информации об обновлении вашего кластера OpenSearch смотрите руководство по обновлению.
Для информации об инструментах обновления смотрите инструменты обновления, миграции и сравнения OpenSearch.
Для установки плагинов смотрите раздел Установка плагинов.
8.2.1 - Установка OpenSearch
Рекомендации по файловой системе
Избегайте использования сетевой файловой системы для хранения узлов в рабочем процессе в производственной среде. Использование сетевой файловой системы для хранения узлов может вызвать проблемы с производительностью в вашем кластере из-за таких факторов, как условия сети (например, задержка или ограниченная пропускная способность) или скорости чтения/записи. Вам следует использовать твердотельные накопители (SSD), установленные на хосте, для хранения узлов, где это возможно.
Совместимость с Java
Распределение OpenSearch для Linux поставляется с совместимой версией JDK Adoptium Java в каталоге jdk. Чтобы узнать версию JDK, выполните команду ./jdk/bin/java -version. Например, архив OpenSearch 1.0.0 поставляется с Java 15.0.1+9 (не LTS), OpenSearch 1.3.0 поставляется с Java 11.0.14.1+1 (LTS), а OpenSearch 2.0.0 поставляется с Java 17.0.2+8 (LTS). OpenSearch тестируется со всеми совместимыми версиями Java.
| Версия OpenSearch | Совместимые версии Java | Встроенная версия Java |
|---|---|---|
| 1.0–1.2.x | 11, 15 | 15.0.1+9 |
| 1.3.x | 8, 11, 14 | 11.0.25+9 |
| 2.0.0–2.11.x | 11, 17 | 17.0.2+8 |
| 2.12.0+ | 11, 17, 21 | 21.0.5+11 |
Чтобы использовать другую установку Java, установите переменную окружения OPENSEARCH_JAVA_HOME или JAVA_HOME на расположение установки Java. Например:
export OPENSEARCH_JAVA_HOME=/path/to/opensearch-3.1.0/jdk
Сетевые требования
Следующие порты необходимо открыть для компонентов OpenSearch.
| Номер порта | Компонент OpenSearch |
|---|---|
| 443 | OpenSearch Dashboards в AWS OpenSearch Service с шифрованием в пути (TLS) |
| 5601 | OpenSearch Dashboards |
| 9200 | OpenSearch REST API |
| 9300 | Внутреннее взаимодействие узлов и транспорт, поиск по кластерам |
| 9600 | Анализатор производительности |
Важные настройки
Для рабочих нагрузок в производственной среде убедитесь, что настройка Linux vm.max_map_count установлена как минимум на 262144. Даже если вы используете образ Docker, установите это значение на хост-машине. Чтобы проверить текущее значение, выполните следующую команду:
cat /proc/sys/vm/max_map_count
Чтобы увеличить значение, добавьте следующую строку в файл /etc/sysctl.conf:
vm.max_map_count=262144
Затем выполните команду sudo sysctl -p, чтобы перезагрузить настройки.
Для рабочих нагрузок Windows вы можете установить vm.max_map_count, выполнив следующие команды:
wsl -d docker-desktop
sysctl -w vm.max_map_count=262144
Пример файла docker-compose.yml
Файл docker-compose.yml также содержит несколько ключевых настроек:
bootstrap.memory_lock: true
Эта настройка отключает свопинг (вместе с memlock). Свопинг может значительно снизить производительность и стабильность, поэтому вы должны убедиться, что он отключен на производственных кластерах.
Включение настройки bootstrap.memory_lock заставит JVM зарезервировать всю необходимую память. Руководство по настройке сборки мусора Java SE Hotspot VM документирует резервирование 1 гигабайта (ГБ) нативной памяти для метаданных классов по умолчанию. В сочетании с кучей Java это может привести к ошибке из-за нехватки нативной памяти на ВМ с меньшим объемом памяти, чем эти требования. Чтобы предотвратить ошибки, ограничьте размер резервируемой памяти с помощью -XX:CompressedClassSpaceSize или -XX:MaxMetaspaceSize и установите размер кучи Java, чтобы убедиться, что у вас достаточно системной памяти.
OPENSEARCH_JAVA_OPTS: -Xms512m -Xmx512m
Эта настройка устанавливает размер кучи Java (рекомендуем использовать половину системной ОЗУ).
OpenSearch по умолчанию использует -Xms1g -Xmx1g для выделения памяти кучи, что имеет приоритет над конфигурациями, указанными с использованием процентной нотации (-XX:MinRAMPercentage, -XX:MaxRAMPercentage). Например, если вы установите OPENSEARCH_JAVA_OPTS=-XX:MinRAMPercentage=30 -XX:MaxRAMPercentage=70, предустановленные значения -Xms1g -Xmx1g переопределят эти настройки. При использовании OPENSEARCH_JAVA_OPTS для определения выделения памяти убедитесь, что вы используете нотацию -Xms и -Xmx.
nofile: 65536
Эта настройка устанавливает лимит в 65536 открытых файлов для пользователя OpenSearch.
port: 9600
Эта настройка позволяет вам получить доступ к Анализатору производительности на порту 9600.
Не объявляйте одни и те же параметры JVM в нескольких местах, так как это может привести к непредсказуемому поведению или сбою запуска службы OpenSearch. Если вы объявляете параметры JVM с помощью переменной окружения, такой как OPENSEARCH_JAVA_OPTS=-Xms3g -Xmx3g, то вам следует закомментировать любые ссылки на этот параметр JVM в config/jvm.options. Напротив, если вы определяете параметры JVM в config/jvm.options, то не следует определять эти параметры JVM с помощью переменных окружения.
Важные системные свойства
OpenSearch имеет ряд системных свойств, перечисленных в следующей таблице, которые вы можете указать в файле config/jvm.options или в переменной OPENSEARCH_JAVA_OPTS, используя нотацию аргументов командной строки -D.
| Свойство | Описание |
|---|---|
opensearch.xcontent.string.length.max=<value> | По умолчанию OpenSearch не накладывает ограничений на максимальную длину строковых полей JSON/YAML/CBOR/Smile. Чтобы защитить ваш кластер от потенциальных атак типа “отказ в обслуживании” (DDoS) или проблем с памятью, вы можете установить это свойство на разумный предел (максимум 2,147,483,647), например, -Dopensearch.xcontent.string.length.max=5000000. |
| `opensearch.xcontent.fast_double_writer=[true | false]` |
opensearch.xcontent.name.length.max=<value> | По умолчанию OpenSearch не накладывает ограничений на максимальную длину имен полей JSON/YAML/CBOR/Smile. Чтобы защитить ваш кластер от потенциальных DDoS или проблем с памятью, вы можете установить это свойство на разумный предел (максимум 2,147,483,647), например, -Dopensearch.xcontent.name.length.max=50000. |
opensearch.xcontent.depth.max=<value> | По умолчанию OpenSearch не накладывает ограничений на максимальную глубину вложенности для документов JSON/YAML/CBOR/Smile. Чтобы защитить ваш кластер от потенциальных DDoS или проблем с памятью, вы можете установить это свойство на разумный предел (максимум 2,147,483,647), например, -Dopensearch.xcontent.depth.max=1000. |
opensearch.xcontent.codepoint.max=<value> | По умолчанию OpenSearch накладывает ограничение в 52428800 на максимальный размер YAML-документов (в кодовых точках). Чтобы защитить ваш кластер от потенциальных DDoS или проблем с памятью, вы можете изменить это свойство на разумный предел (максимум 2,147,483,647). Например, -Dopensearch.xcontent.codepoint.max=5000000. |
8.2.1.1 - Docker
Docker значительно упрощает процесс настройки и управления вашими кластерами OpenSearch. Вы можете загружать официальные образы из Docker Hub или Amazon Elastic Container Registry (Amazon ECR) и быстро развернуть кластер, используя Docker Compose и любой из примеров файлов Docker Compose, включенных в этот гид. Опытные пользователи OpenSearch могут дополнительно настроить свое развертывание, создав собственный файл Docker Compose.
Контейнеры Docker являются портативными и будут работать на любом совместимом хосте, который поддерживает Docker (таких как Linux, MacOS или Windows). Портативность контейнера Docker предлагает гибкость по сравнению с другими методами установки, такими как RPM или ручная установка из Tarball, которые требуют дополнительной конфигурации после загрузки и распаковки.
Этот гид предполагает, что вы уверенно работаете с интерфейсом командной строки (CLI) Linux. Вы должны понимать, как вводить команды, перемещаться между директориями и редактировать текстовые файлы. Для получения помощи по Docker или Docker Compose обратитесь к официальной документации на их веб-сайтах.
Установка Docker и Docker Compose
Посетите страницу Get Docker для получения рекомендаций по установке и настройке Docker для вашей среды. Если вы устанавливаете Docker Engine с помощью CLI, то по умолчанию Docker не будет иметь никаких ограничений на доступные ресурсы хоста. В зависимости от вашей среды вы можете настроить ограничения ресурсов в Docker. См. раздел Runtime options with Memory, CPUs, and GPUs для получения информации.
Пользователи Docker Desktop должны установить использование памяти хоста на минимум 4 ГБ, открыв Docker Desktop и выбрав Settings → Resources.
Docker Compose — это утилита, которая позволяет пользователям запускать несколько контейнеров с одной командой. Вы передаете файл Docker Compose при его вызове. Docker Compose читает эти настройки и запускает запрашиваемые контейнеры. Docker Compose устанавливается автоматически с Docker Desktop, но пользователи, работающие в командной строке, должны установить Docker Compose вручную. Вы можете найти информацию о установке Docker Compose на официальной странице Docker Compose GitHub.
Если вам нужно установить Docker Compose вручную и ваш хост поддерживает Python, вы можете использовать pip для автоматической установки пакета Docker Compose.
Настройка важных параметров хоста
Перед установкой OpenSearch с использованием Docker настройте следующие параметры. Это самые важные настройки, которые могут повлиять на производительность ваших сервисов, но для дополнительной информации смотрите раздел о важных системных настройках.
Настройки для Linux
Для среды Linux выполните следующие команды:
Отключите производительность памяти с помощью свопинга для улучшения производительности:
sudo swapoff -aУвеличьте количество доступных для OpenSearch карт памяти:
# Отредактируйте файл конфигурации sysctl sudo vi /etc/sysctl.conf # Добавьте строку для определения желаемого значения # или измените значение, если ключ существует, # а затем сохраните изменения. vm.max_map_count=262144 # Перезагрузите параметры ядра с помощью sysctl sudo sysctl -p # Проверьте, что изменение было применено, проверив значение cat /proc/sys/vm/max_map_count
Настройки для Windows
Для рабочих нагрузок Windows, использующих WSL через Docker Desktop, выполните следующие команды в терминале, чтобы установить vm.max_map_count:
wsl -d docker-desktop
sysctl -w vm.max_map_count=262144
Запуск OpenSearch в контейнере Docker
Официальные образы OpenSearch размещены на Docker Hub и Amazon ECR. Если вы хотите просмотреть образы, вы можете загружать их по отдельности, используя команду docker pull, как в следующих примерах.
Docker Hub:
docker pull opensearchproject/opensearch:3
docker pull opensearchproject/opensearch-dashboards:3
Amazon ECR:
docker pull public.ecr.aws/opensearchproject/opensearch:3
docker pull public.ecr.aws/opensearchproject/opensearch-dashboards:3
Чтобы загрузить конкретную версию OpenSearch или OpenSearch Dashboards, отличную от последней доступной версии, измените тег образа, где он упоминается (либо в командной строке, либо в файле Docker Compose). Например, opensearchproject/opensearch:3.1.0 загрузит версию OpenSearch 3.1.0. Чтобы загрузить последнюю версию, используйте opensearchproject/opensearch:latest. Обратитесь к официальным репозиториям образов для доступных версий.
Перед тем как продолжить, вы должны убедиться, что Docker работает корректно, развернув OpenSearch в одном контейнере.
Запуск OpenSearch в контейнере Docker
- Выполните следующую команду:
# Эта команда сопоставляет порты 9200 и 9600, устанавливает тип обнаружения на "single-node" и запрашивает самый новый образ OpenSearch
docker run -d -p 9200:9200 -p 9600:9600 -e "discovery.type=single-node" opensearchproject/opensearch:latest
Для OpenSearch версии 2.12 или выше установите новый пользовательский пароль администратора перед установкой, используя следующую команду:
docker run -d -p 9200:9200 -p 9600:9600 -e "discovery.type=single-node" -e "OPENSEARCH_INITIAL_ADMIN_PASSWORD=<custom-admin-password>" opensearchproject/opensearch:latest
- Отправьте запрос на порт 9200. Имя пользователя и пароль по умолчанию —
admin.
curl https://localhost:9200 -ku admin:<custom-admin-password>
Вы должны получить ответ, который выглядит следующим образом:
{
"name" : "a937e018cee5",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "GLAjAG6bTeWErFUy_d-CLw",
"version" : {
"distribution" : "opensearch",
"number" : "<version>",
"build_type" : "<build-type>",
"build_hash" : "<build-hash>",
"build_date" : "<build-date>",
"build_snapshot" : false,
"lucene_version" : "<lucene-version>",
"minimum_wire_compatibility_version" : "7.10.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "The OpenSearch Project: https://opensearch.org/"
}
- Перед остановкой работающего контейнера отобразите список всех работающих контейнеров и скопируйте идентификатор контейнера для узла OpenSearch, который вы тестируете. В следующем примере идентификатор контейнера —
a937e018cee5:
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a937e018cee5 opensearchproject/opensearch:latest "./opensearch-docker…" 19 minutes ago Up 19 minutes 0.0.0.0:9200->9200/tcp, 9300/tcp, 0.0.0.0:9600->9600/tcp, 9650/tcp wonderful_boyd
- Остановите работающий контейнер, передав идентификатор контейнера в команду
docker stop.
docker stop <containerId>
Помните, что команда
docker container lsне отображает остановленные контейнеры. Если вы хотите просмотреть остановленные контейнеры, используйте командуdocker container ls -a. Вы можете удалить ненужные контейнеры вручную с помощью командыdocker container rm <containerId_1> <containerId_2> <containerId_3> [...](укажите все идентификаторы контейнеров, которые вы хотите остановить, разделенные пробелами), или, если вы хотите удалить все остановленные контейнеры, вы можете использовать более короткую командуdocker container prune.
Развертывание кластера OpenSearch с использованием Docker Compose
Хотя технически возможно создать кластер OpenSearch, создавая контейнеры по одной команде за раз, гораздо проще определить вашу среду в YAML-файле и позволить Docker Compose управлять кластером. В следующем разделе содержатся примеры YAML-файлов, которые вы можете использовать для запуска предопределенного кластера с OpenSearch и OpenSearch Dashboards. Эти примеры полезны для тестирования и разработки, но не подходят для производственной среды. Если у вас нет опыта работы с Docker Compose, вам может быть полезно ознакомиться со спецификацией Docker Compose для получения рекомендаций по синтаксису и форматированию перед внесением изменений в структуры словарей в примерах.
Файл YAML, который определяет среду, называется файлом Docker Compose. По умолчанию команды docker-compose сначала проверяют вашу текущую директорию на наличие файла, который соответствует любому из следующих имен:
docker-compose.ymldocker-compose.yamlcompose.ymlcompose.yaml
Если ни один из этих файлов не существует в вашей текущей директории, команда docker-compose завершится с ошибкой.
Вы можете указать пользовательское местоположение и имя файла при вызове docker-compose с помощью флага -f:
# Используйте относительный или абсолютный путь к файлу.
docker compose -f /path/to/your-file.yml up
Если вы впервые запускаете кластер OpenSearch с использованием Docker Compose, используйте следующий пример файла docker-compose.yml. Сохраните его в домашнем каталоге вашего хоста и назовите его docker-compose.yml. Этот файл создает кластер, который содержит три контейнера: два контейнера, работающих с сервисом OpenSearch, и один контейнер, работающий с OpenSearch Dashboards. Эти контейнеры общаются через мостовую сеть под названием opensearch-net и используют два тома, по одному для каждого узла OpenSearch. Поскольку этот файл явно не отключает демонстрационную конфигурацию безопасности, устанавливаются самоподписанные TLS-сертификаты, и создаются внутренние пользователи с именами и паролями по умолчанию.
Установка пользовательского пароля администратора
Начиная с OpenSearch 2.12, для настройки демонстрационной конфигурации безопасности требуется пользовательский пароль администратора. Выполните одно из следующих действий:
Перед запуском
docker-compose.ymlустановите новый пользовательский пароль администратора, используя следующую команду:export OPENSEARCH_INITIAL_ADMIN_PASSWORD=<custom-admin-password>Создайте файл
.envв той же папке, что и ваш файлdocker-compose.yml, с переменнойOPENSEARCH_INITIAL_ADMIN_PASSWORDи значением надежного пароля.
Требования к паролям
OpenSearch по умолчанию обеспечивает высокую безопасность паролей, используя библиотеку оценки прочности паролей zxcvbn, разработанную компанией Dropbox.
Эта библиотека оценивает пароли на основе энтропии, а не жестких правил сложности, используя следующие рекомендации:
Сосредоточьтесь на энтропии, а не только на правилах: Вместо того чтобы просто добавлять цифры или специальные символы, придавайте приоритет общей непредсказуемости. Длинные пароли, состоящие из случайных слов или символов, обеспечивают более высокую энтропию, что делает их более безопасными, чем короткие пароли, соответствующие традиционным правилам сложности.
Избегайте общих шаблонов и слов из словаря: Библиотека zxcvbn обнаруживает распространенные шаблоны и слова из словаря, что помогает предотвратить использование легко угадываемых паролей.
Следуя этим рекомендациям, вы сможете создать более надежные пароли, которые обеспечат лучшую защиту ваших учетных записей и данных в OpenSearch.
Sample docker-compose.yml
services:
opensearch-node1: # This is also the hostname of the container within the Docker network (i.e. https://opensearch-node1/)
image: opensearchproject/opensearch:latest # Specifying the latest available image - modify if you want a specific version
container_name: opensearch-node1
environment:
- cluster.name=opensearch-cluster # Name the cluster
- node.name=opensearch-node1 # Name the node that will run in this container
- discovery.seed_hosts=opensearch-node1,opensearch-node2 # Nodes to look for when discovering the cluster
- cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2 # Nodes eligible to serve as cluster manager
- bootstrap.memory_lock=true # Disable JVM heap memory swapping
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # Set min and max JVM heap sizes to at least 50% of system RAM
- OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_INITIAL_ADMIN_PASSWORD} # Sets the demo admin user password when using demo configuration, required for OpenSearch 2.12 and later
ulimits:
memlock:
soft: -1 # Set memlock to unlimited (no soft or hard limit)
hard: -1
nofile:
soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536
hard: 65536
volumes:
- opensearch-data1:/usr/share/opensearch/data # Creates volume called opensearch-data1 and mounts it to the container
ports:
- 9200:9200 # REST API
- 9600:9600 # Performance Analyzer
networks:
- opensearch-net # All of the containers will join the same Docker bridge network
opensearch-node2:
image: opensearchproject/opensearch:latest # This should be the same image used for opensearch-node1 to avoid issues
container_name: opensearch-node2
environment:
- cluster.name=opensearch-cluster
- node.name=opensearch-node2
- discovery.seed_hosts=opensearch-node1,opensearch-node2
- cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2
- bootstrap.memory_lock=true
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m"
- OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_INITIAL_ADMIN_PASSWORD}
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
- opensearch-data2:/usr/share/opensearch/data
networks:
- opensearch-net
opensearch-dashboards:
image: opensearchproject/opensearch-dashboards:latest # Make sure the version of opensearch-dashboards matches the version of opensearch installed on other nodes
container_name: opensearch-dashboards
ports:
- 5601:5601 # Map host port 5601 to container port 5601
expose:
- "5601" # Expose port 5601 for web access to OpenSearch Dashboards
environment:
OPENSEARCH_HOSTS: '["https://opensearch-node1:9200","https://opensearch-node2:9200"]' # Define the OpenSearch nodes that OpenSearch Dashboards will query
networks:
- opensearch-net
volumes:
opensearch-data1:
opensearch-data2:
networks:
opensearch-net:
Если вы переопределяете настройки opensearch_dashboards.yml, используя переменные окружения в вашем файле Compose, используйте все заглавные буквы и заменяйте точки на подчеркивания. Например, для opensearch.hosts используйте OPENSEARCH_HOSTS.
Это поведение отличается от переопределения настроек opensearch.yml, где преобразование заключается только в изменении оператора присваивания. Например, discovery.type: single-node в opensearch.yml определяется как discovery.type=single-node в docker-compose.yml.
Запуск и управление контейнерами OpenSearch с использованием Docker Compose
Создайте и запустите контейнеры в фоновом режиме из домашнего каталога вашего хоста (содержащего
docker-compose.yml):docker compose up -dПроверьте, что сервисные контейнеры запустились корректно:
docker compose psЕсли контейнер не удалось запустить, вы можете просмотреть логи сервиса:
# Если вы не укажете имя сервиса, docker compose покажет логи всех узлов docker compose logs <serviceName>Проверьте доступ к OpenSearch Dashboards, подключившись к http://localhost:5601 из браузера. Для OpenSearch версии 2.12 и выше вы должны использовать ваш настроенный логин и пароль. Для более ранних версий логин и пароль по умолчанию —
admin. Мы не рекомендуем использовать эту конфигурацию на хостах, доступных из публичного интернета, пока вы не настроите конфигурацию безопасности вашего развертывания.Помните, что
localhostне может быть доступен удаленно. Если вы развертываете эти контейнеры на удаленном хосте, вам нужно установить сетевое соединение и заменитьlocalhostна IP-адрес или DNS-запись, соответствующую хосту.Остановите работающие контейнеры в вашем кластере:
docker compose down
Команда
docker compose downостановит работающие контейнеры, но не удалит Docker-тома, которые существуют на хосте. Если вам не важны содержимое этих томов, используйте опцию-v, чтобы удалить все тома, например:docker compose down -v
Настройка OpenSearch
В отличие от RPM-распределения OpenSearch, которое требует значительного объема конфигурации после установки, запуск кластеров OpenSearch с помощью Docker позволяет вам определить среду еще до создания контейнеров. Это возможно как при использовании Docker, так и при использовании Docker Compose.
Пример команды Docker
Рассмотрим следующую команду:
docker run \
-p 9200:9200 -p 9600:9600 \
-e "discovery.type=single-node" \
-v /path/to/custom-opensearch.yml:/usr/share/opensearch/config/opensearch.yml \
opensearchproject/opensearch:latest
Разберем каждую часть команды:
- Сопоставляет порты 9200 и 9600 (HOST_PORT:CONTAINER_PORT).
- Устанавливает
discovery.typeвsingle-node, чтобы проверки загрузки не завершились неудачей для этого развертывания с одним узлом. - Использует флаг
-v, чтобы передать локальный файл с именемcustom-opensearch.ymlв контейнер, заменяя файлopensearch.yml, включенный в образ. - Запрашивает образ
opensearchproject/opensearch:latestиз Docker Hub. - Запускает контейнер.
Если вы сравните эту команду с примером файла docker-compose.yml, вы можете заметить некоторые общие настройки, такие как сопоставление портов и ссылка на образ. Однако эта команда только развертывает один контейнер, работающий с OpenSearch, и не создает контейнер для OpenSearch Dashboards. Более того, если вы хотите использовать пользовательские TLS-сертификаты, пользователей или роли, или определить дополнительные тома и сети, то эта “однострочная” команда быстро становится непрактичной. Вот где полезность Docker Compose становится очевидной.
Использование Docker Compose
Когда вы строите свой кластер OpenSearch с помощью Docker Compose, вам может быть проще передавать пользовательские файлы конфигурации с вашего хоста в контейнер, вместо того чтобы перечислять каждую отдельную настройку в docker-compose.yml. Аналогично тому, как в примере команды docker run был смонтирован том с хоста в контейнер с помощью флага -v, файлы Compose могут указывать тома для монтирования как подопцию для соответствующей службы. Следующий сокращенный YAML-файл демонстрирует, как смонтировать файл или директорию в контейнер:
services:
opensearch-node1:
volumes:
- opensearch-data1:/usr/share/opensearch/data
- ./custom-opensearch.yml:/usr/share/opensearch/config/opensearch.yml
opensearch-node2:
volumes:
- opensearch-data2:/usr/share/opensearch/data
- ./custom-opensearch.yml:/usr/share/opensearch/config/opensearch.yml
opensearch-dashboards:
volumes:
- ./custom-opensearch_dashboards.yml:/usr/share/opensearch-dashboards/config/opensearch_dashboards.yml
Обратите внимание, что в этом примере каждый узел OpenSearch использует один и тот же файл конфигурации, что упрощает управление настройками. Для получения более подробной информации о использовании томов и синтаксисе обратитесь к официальной документации Docker по томам.
Пример файла Docker Compose для разработки
Если вы хотите создать свой собственный файл compose на основе примера, ознакомьтесь с следующим образцом файла docker-compose.yml. Этот образец создает два узла OpenSearch и один узел OpenSearch Dashboards с отключенным плагином безопасности. Вы можете использовать этот образец в качестве отправной точки, просматривая Настройка основных параметров безопасности.
services:
opensearch-node1:
image: opensearchproject/opensearch:latest
container_name: opensearch-node1
environment:
- cluster.name=opensearch-cluster # Название кластера
- node.name=opensearch-node1 # Название узла, который будет работать в этом контейнере
- discovery.seed_hosts=opensearch-node1,opensearch-node2 # Узлы, которые будут использоваться для обнаружения кластера
- cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2 # Узлы, которые могут служить менеджерами кластера
- bootstrap.memory_lock=true # Отключить свопинг памяти кучи JVM
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # Установить минимальный и максимальный размеры кучи JVM не менее 50% от системной оперативной памяти
- "DISABLE_INSTALL_DEMO_CONFIG=true" # Предотвращает выполнение встроенного демо-скрипта, который устанавливает демо-сертификаты и конфигурации безопасности в OpenSearch
- "DISABLE_SECURITY_PLUGIN=true" # Отключает плагин безопасности
ulimits:
memlock:
soft: -1 # Установить memlock на неограниченное (без мягкого или жесткого ограничения)
hard: -1
nofile:
soft: 65536 # Максимальное количество открытых файлов для пользователя opensearch - установить не менее 65536
hard: 65536
volumes:
- opensearch-data1:/usr/share/opensearch/data # Создает том с именем opensearch-data1 и монтирует его в контейнер
ports:
- 9200:9200 # REST API
- 9600:9600 # Анализатор производительности
networks:
- opensearch-net # Все контейнеры будут присоединены к одной и той же сети Docker bridge
opensearch-node2:
image: opensearchproject/opensearch:latest
container_name: opensearch-node2
environment:
- cluster.name=opensearch-cluster # Название кластера
- node.name=opensearch-node2 # Название узла, который будет работать в этом контейнере
- discovery.seed_hosts=opensearch-node1,opensearch-node2 # Узлы, которые будут использоваться для обнаружения кластера
- cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2 # Узлы, которые могут служить менеджерами кластера
- bootstrap.memory_lock=true # Отключить свопинг памяти кучи JVM
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # Установить минимальный и максимальный размеры кучи JVM не менее 50% от системной оперативной памяти
- "DISABLE_INSTALL_DEMO_CONFIG=true" # Предотвращает выполнение встроенного демо-скрипта, который устанавливает демо-сертификаты и конфигурации безопасности в OpenSearch
- "DISABLE_SECURITY_PLUGIN=true" # Отключает плагин безопасности
ulimits:
memlock:
soft: -1 # Установить memlock на неограниченное (без мягкого или жесткого ограничения)
hard: -1
nofile:
soft: 65536 # Максимальное количество открытых файлов для пользователя opensearch - установить не менее 65536
hard: 65536
volumes:
- opensearch-data2:/usr/share/opensearch/data # Создает том с именем opensearch-data2 и монтирует его в контейнер
networks:
- opensearch-net # Все контейнеры будут присоединены к одной и той же сети Docker bridge
opensearch-dashboards:
image: opensearchproject/opensearch-dashboards:latest
container_name: opensearch-dashboards
ports:
- 5601:5601 # Привязка порта хоста 5601 к порту контейнера 5601
expose:
- "5601" # Открыть порт 5601 для веб-доступа к OpenSearch Dashboards
environment:
- 'OPENSEARCH_HOSTS=["http://opensearch-node1:9200","http://opensearch-node2:9200"]' # Указать узлы OpenSearch для Dashboards
- "DISABLE_SECURITY_DASHBOARDS_PLUGIN=true" # Отключает плагин безопасности в OpenSearch Dashboards
networks:
- opensearch-net
volumes:
opensearch-data1: {} # Создает том opensearch-data1
opensearch-data2: {} # Создает том opensearch-data2
networks:
opensearch-net: {} # Создает сеть opensearch-net
Настройка основных параметров безопасности
Перед тем как сделать ваш кластер OpenSearch доступным для внешних хостов, рекомендуется ознакомиться с конфигурацией безопасности развертывания. Вы можете вспомнить из первого примера файла docker-compose.yml, что, если не отключить плагин безопасности, установив DISABLE_SECURITY_PLUGIN=true, встроенный скрипт применит стандартную демо-конфигурацию безопасности к узлам в кластере. Поскольку эта конфигурация используется для демонстрационных целей, стандартные имена пользователей и пароли известны. Поэтому мы рекомендуем создать собственные файлы конфигурации безопасности и использовать тома для передачи этих файлов в контейнеры. Для получения конкретных рекомендаций по настройке безопасности OpenSearch смотрите Конфигурация безопасности.
Чтобы использовать свои собственные сертификаты в конфигурации, добавьте все необходимые сертификаты в раздел томов файла compose:
volumes:
- ./root-ca.pem:/usr/share/opensearch/config/root-ca.pem
- ./admin.pem:/usr/share/opensearch/config/admin.pem
- ./admin-key.pem:/usr/share/opensearch/config/admin-key.pem
- ./node1.pem:/usr/share/opensearch/config/node1.pem
- ./node1-key.pem:/usr/share/opensearch/config/node1-key.pem
Когда вы добавляете сертификаты TLS к узлам OpenSearch с помощью томов Docker Compose, вы также должны включить пользовательский файл opensearch.yml, который определяет эти сертификаты. Например:
volumes:
- ./root-ca.pem:/usr/share/opensearch/config/root-ca.pem
- ./admin.pem:/usr/share/opensearch/config/admin.pem
- ./admin-key.pem:/usr/share/opensearch/config/admin-key.pem
- ./node1.pem:/usr/share/opensearch/config/node1.pem
- ./node1-key.pem:/usr/share/opensearch/config/node1-key.pem
- ./custom-opensearch.yml:/usr/share/opensearch/config/opensearch.yml
Помните, что сертификаты, которые вы указываете в файле compose, должны совпадать с сертификатами, определенными в вашем пользовательском файле opensearch.yml. Вам следует заменить корневые, администраторские и узловые сертификаты на свои собственные. Для получения дополнительной информации смотрите Настройка сертификатов TLS.
Пример конфигурации в вашем пользовательском файле opensearch.yml может выглядеть следующим образом, добавляя сертификаты TLS и отличительное имя (DN) сертификата администратора, определяя несколько разрешений и включая подробное аудиторское логирование:
plugins.security.ssl.transport.pemcert_filepath: node1.pem
plugins.security.ssl.transport.pemkey_filepath: node1-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: root-ca.pem
plugins.security.ssl.transport.enforce_hostname_verification: false
plugins.security.ssl.http.enabled: true
plugins.security.ssl.http.pemcert_filepath: node1.pem
plugins.security.ssl.http.pemkey_filepath: node1-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem
plugins.security.allow_default_init_securityindex: true
plugins.security.authcz.admin_dn:
- CN=A,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA
plugins.security.nodes_dn:
- 'CN=N,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA'
plugins.security.audit.type: internal_opensearch
plugins.security.enable_snapshot_restore_privilege: true
plugins.security.check_snapshot_restore_write_privileges: true
plugins.security.restapi.roles_enabled: ["all_access", "security_rest_api_access"]
cluster.routing.allocation.disk.threshold_enabled: false
opendistro_security.audit.config.disabled_rest_categories: NONE
opendistro_security.audit.config.disabled_transport_categories: NONE
Полный список настроек
Для получения полного списка настроек смотрите Безопасность.
Используйте тот же процесс для указания конфигурации Backend в файле /usr/share/opensearch/config/opensearch-security/config.yml, а также для создания новых внутренних пользователей, ролей, сопоставлений, групп действий и арендаторов в соответствующих YAML-файлах.
После замены сертификатов и создания собственных внутренних пользователей, ролей, сопоставлений, групп действий и арендаторов, используйте Docker Compose для запуска кластера:
docker compose up -d
Работа с плагинами
Чтобы использовать образ OpenSearch с пользовательским плагином, вам сначала нужно создать Dockerfile. Ознакомьтесь с официальной документацией Docker для получения информации о создании Dockerfile.
FROM opensearchproject/opensearch:latest
RUN /usr/share/opensearch/bin/opensearch-plugin install --batch <pluginId>
Затем выполните следующие команды:
# Создание образа из Dockerfile
docker build --tag=opensearch-custom-plugin .
# Запуск контейнера из пользовательского образа
docker run -p 9200:9200 -p 9600:9600 -v /usr/share/opensearch/data opensearch-custom-plugin
В качестве альтернативы, вы можете удалить плагин из образа перед его развертыванием. Этот пример Dockerfile удаляет плагин безопасности:
FROM opensearchproject/opensearch:latest
RUN /usr/share/opensearch/bin/opensearch-plugin remove opensearch-security
Вы также можете использовать Dockerfile для передачи своих собственных сертификатов для использования с плагином безопасности:
FROM opensearchproject/opensearch:latest
COPY --chown=opensearch:opensearch opensearch.yml /usr/share/opensearch/config/
COPY --chown=opensearch:opensearch my-key-file.pem /usr/share/opensearch/config/
COPY --chown=opensearch:opensearch my-certificate-chain.pem /usr/share/opensearch/config/
COPY --chown=opensearch:opensearch my-root-cas.pem /usr/share/opensearch/config/
8.2.1.2 - Установка OpenSearch на Debian
Установка OpenSearch с использованием менеджера пакетов Advanced Packaging Tool (APT) значительно упрощает процесс по сравнению с методом Tarball. Несколько технических аспектов, таких как путь установки, расположение конфигурационных файлов и создание службы, управляемой systemd, обрабатываются автоматически менеджером пакетов.
В общем, установка OpenSearch из дистрибутива Debian может быть разбита на несколько шагов:
- Скачать и установить OpenSearch.
- Установить вручную из Debian-пакета или из APT-репозитория.
- (Необязательно) Протестировать OpenSearch.
- Подтвердите, что OpenSearch может работать, прежде чем применять какую-либо пользовательскую конфигурацию.
- Это можно сделать без какой-либо безопасности (без пароля, без сертификатов) или с демо-конфигурацией безопасности, которая может быть применена с помощью упакованного скрипта.
- Настроить OpenSearch для вашей среды.
- Примените основные настройки к OpenSearch и начните использовать его в вашей среде.
Дистрибутив Debian предоставляет все необходимое для запуска OpenSearch внутри дистрибутивов Linux на базе Debian, таких как Ubuntu.
Этот гид предполагает, что вы уверенно работаете с интерфейсом командной строки (CLI) Linux. Вы должны понимать, как вводить команды, перемещаться между директориями и редактировать текстовые файлы. Некоторые примеры команд ссылаются на текстовый редактор vi, но вы можете использовать любой доступный текстовый редактор.
Шаг 1: Скачивание и установка OpenSearch
Установка OpenSearch из пакета
Скачайте Debian-пакет для желаемой версии непосредственно с страницы загрузок OpenSearch. Debian-пакет можно скачать как для архитектуры x64, так и для arm64.
Из командной строки установите пакет с помощью dpkg:
Для новых установок OpenSearch 2.12 и более поздних версий необходимо определить пользовательский пароль администратора для настройки демо-конфигурации безопасности. Используйте одну из следующих команд для определения пользовательского пароля администратора:
# x64
sudo env OPENSEARCH_INITIAL_ADMIN_PASSWORD=<custom-admin-password> dpkg -i opensearch-3.1.0-linux-x64.deb
# arm64
sudo env OPENSEARCH_INITIAL_ADMIN_PASSWORD=<custom-admin-password> dpkg -i opensearch-3.1.0-linux-arm64.deb
Используйте следующую команду для версий OpenSearch 2.11 и более ранних:
# x64
sudo dpkg -i opensearch-3.1.0-linux-x64.deb
# arm64
sudo dpkg -i opensearch-3.1.0-linux-arm64.deb
После успешной установки включите OpenSearch как службу:
sudo systemctl enable opensearch
Запустите службу OpenSearch:
sudo systemctl start opensearch
Проверьте, что OpenSearch запустился корректно:
sudo systemctl status opensearch
Проверка отпечатка
Debian-пакет не подписан. Если вы хотите проверить отпечаток, проект OpenSearch предоставляет файл .sig, а также пакет .deb для использования с GNU Privacy Guard (GPG).
Скачайте желаемый Debian-пакет:
curl -SLO https://artifacts.opensearch.org/releases/bundle/opensearch/3.1.0/opensearch-3.1.0-linux-x64.deb
Скачайте соответствующий файл подписи:
curl -SLO https://artifacts.opensearch.org/releases/bundle/opensearch/3.1.0/opensearch-3.1.0-linux-x64.deb.sig
Скачайте и импортируйте GPG-ключ:
curl -o- https://artifacts.opensearch.org/publickeys/opensearch-release.pgp | gpg --import -
Проверьте подпись:
gpg --verify opensearch-3.1.0-linux-x64.deb.sig opensearch-3.1.0-linux-x64.deb
Установка OpenSearch из APT-репозитория
APT, основной инструмент управления пакетами для операционных систем на базе Debian, позволяет загружать и устанавливать Debian-пакет из APT-репозитория.
- Установите необходимые пакеты:
sudo apt-get update && sudo apt-get -y install lsb-release ca-certificates curl gnupg2
- Импортируйте публичный GPG-ключ. Этот ключ используется для проверки подписи APT-репозитория:
curl -o- https://artifacts.opensearch.org/publickeys/opensearch-release.pgp | sudo gpg --dearmor --batch --yes -o /usr/share/keyrings/opensearch-release-keyring
- Создайте APT-репозиторий для OpenSearch:
echo "deb [signed-by=/usr/share/keyrings/opensearch-release-keyring] https://artifacts.opensearch.org/releases/bundle/opensearch/3.x/apt stable main" | sudo tee /etc/apt/sources.list.d/opensearch-3.x.list
- Проверьте, что репозиторий был успешно создан:
sudo apt-get update
- С добавленной информацией о репозитории перечислите все доступные версии OpenSearch:
sudo apt list -a opensearch
- Выбор версии OpenSearch для установки
- Если не указано иное, будет установлена последняя доступная версия OpenSearch.
# Для новых установок OpenSearch 2.12 и более поздних версий необходимо определить пользовательский пароль администратора для настройки демо-конфигурации безопасности.
# Используйте одну из следующих команд для определения пользовательского пароля:
sudo env OPENSEARCH_INITIAL_ADMIN_PASSWORD=<custom-admin-password> apt-get install opensearch
# Для версий OpenSearch 2.11 и более ранних используйте следующую команду:
sudo apt-get install opensearch
- Установка конкретной версии OpenSearch
# Чтобы установить конкретную версию OpenSearch, укажите версию вручную, используя `opensearch=<version>`:
# Для новых установок OpenSearch 2.12 и более поздних версий:
sudo env OPENSEARCH_INITIAL_ADMIN_PASSWORD=<custom-admin-password> apt-get install opensearch=3.1.0
# Для версий OpenSearch 2.11 и более ранних:
sudo apt-get install opensearch=3.1.0
- Во время установки установщик предоставит вам отпечаток GPG-ключа. Убедитесь, что информация совпадает с указанной ниже:
Fingerprint: c5b7 4989 65ef d1c2 924b a9d5 39d3 1987 9310 d3fc
- Проверьте, что отпечаток ключа соответствует ожидаемому значению, чтобы гарантировать целостность и подлинность пакета.
sudo systemctl enable opensearch
- Запуск OpenSearch
Чтобы запустить OpenSearch, выполните следующую команду:
sudo systemctl start opensearch
- Проверка статуса OpenSearch
После запуска проверьте, что OpenSearch запустился корректно, с помощью следующей команды:
sudo systemctl status opensearch
Шаг 2: (Необязательно) Тестирование OpenSearch
Перед тем как продолжить с любой конфигурацией, рекомендуется протестировать вашу установку OpenSearch. В противном случае может быть сложно определить, связаны ли будущие проблемы с установочными ошибками или с пользовательскими настройками, которые вы применили после установки.
Когда OpenSearch установлен с использованием Debian-пакета, некоторые демо-настройки безопасности автоматически применяются. Это включает в себя самоподписанные TLS-сертификаты и несколько пользователей и ролей. Если вы хотите настроить их самостоятельно, смотрите раздел Настройка OpenSearch в вашей среде.
Узел OpenSearch в своей стандартной конфигурации (с демо-сертификатами и пользователями с стандартными паролями) не подходит для производственной среды. Если вы планируете использовать узел в производственной среде, вам следует, как минимум, заменить демо TLS-сертификаты на ваши собственные и обновить список внутренних пользователей и паролей. Смотрите Конфигурация безопасности для получения дополнительной информации, чтобы убедиться, что ваши узлы настроены в соответствии с вашими требованиями безопасности.
Отправка запросов на сервер
Отправьте запросы на сервер, чтобы проверить, что OpenSearch работает. Обратите внимание на использование флага --insecure, который необходим, поскольку TLS-сертификаты самоподписаны.
Отправьте запрос на порт 9200:
curl -X GET https://localhost:9200 -u 'admin:<custom-admin-password>' --insecure
Ожидаемый ответ
Вы должны получить ответ, который выглядит примерно так:
{
"name": "hostname",
"cluster_name": "opensearch",
"cluster_uuid": "QqgpHCbnSRKcPAizqjvoOw",
"version": {
"distribution": "opensearch",
"number": <version>,
"build_type": <build-type>,
"build_hash": <build-hash>,
"build_date": <build-date>,
"build_snapshot": false,
"lucene_version": <lucene-version>,
"minimum_wire_compatibility_version": "7.10.0",
"minimum_index_compatibility_version": "7.0.0"
},
"tagline": "The OpenSearch Project: https://opensearch.org/"
}
Запрос к конечной точке плагинов
Запросите конечную точку плагинов:
curl -X GET https://localhost:9200/_cat/plugins?v -u 'admin:<custom-admin-password>' --insecure
Этот запрос вернет список установленных плагинов, что также подтвердит, что OpenSearch работает корректно.
Ожидаемый ответ для запроса к конечной точке плагинов
| Name | Component | Version |
|---|---|---|
| hostname | opensearch-alerting | 3.1.0 |
| hostname | opensearch-anomaly-detection | 3.1.0 |
| hostname | opensearch-asynchronous-search | 3.1.0 |
| hostname | opensearch-cross-cluster-replication | 3.1.0 |
| hostname | opensearch-geospatial | 3.1.0 |
| hostname | opensearch-index-management | 3.1.0 |
| hostname | opensearch-job-scheduler | 3.1.0 |
| hostname | opensearch-knn | 3.1.0 |
| hostname | opensearch-ml | 3.1.0 |
| hostname | opensearch-neural-search | 3.1.0 |
| hostname | opensearch-notifications | 3.1.0 |
| hostname | opensearch-notifications-core | 3.1.0 |
| hostname | opensearch-observability | 3.1.0 |
| hostname | opensearch-performance-analyzer | 3.1.0 |
| hostname | opensearch-reports-scheduler | 3.1.0 |
| hostname | opensearch-security | 3.1.0 |
| hostname | opensearch-security-analytics | 3.1.0 |
| hostname | opensearch-sql | 3.1.0 |
Шаг 3: Настройка OpenSearch в вашей среде
Пользователи, не имеющие предварительного опыта работы с OpenSearch, могут захотеть получить список рекомендуемых настроек для начала работы с сервисом. По умолчанию OpenSearch не привязан к сетевому интерфейсу и не может быть доступен внешними хостами. Кроме того, настройки безопасности заполняются стандартными именами пользователей и паролями. Следующие рекомендации позволят пользователю привязать OpenSearch к сетевому интерфейсу, создать и подписать TLS-сертификаты, а также настроить базовую аутентификацию.
Рекомендуемые настройки
Следующие настройки позволят вам:
- Привязать OpenSearch к IP-адресу или сетевому интерфейсу на хосте.
- Установить начальные и максимальные размеры кучи JVM.
- Определить переменную окружения, указывающую на встроенный JDK.
- Настроить собственные TLS-сертификаты — сторонний центр сертификации (CA) не требуется.
- Создать администратора с пользовательским паролем.
Если вы запускали демо-скрипт безопасности, вам нужно будет вручную перенастроить настройки, которые были изменены. Обратитесь к Конфигурации безопасности для получения рекомендаций перед продолжением.
Перед внесением каких-либо изменений в конфигурационные файлы всегда полезно сохранить резервную копию. Резервный файл можно использовать для устранения любых проблем, вызванных неправильной конфигурацией.
- Открытие файла
opensearch.yml
Откройте файл opensearch.yml:
sudo vi /etc/opensearch/opensearch.yml
- Добавление следующих строк
Добавьте следующие строки в файл:
# Привязать OpenSearch к правильному сетевому интерфейсу. Используйте 0.0.0.0
# для включения всех доступных интерфейсов или укажите IP-адрес,
# назначенный конкретному интерфейсу.
network.host: 0.0.0.0
# Если вы еще не настроили кластер, установите
# discovery.type в single-node, иначе проверки загрузки
# не пройдут, когда вы попытаетесь запустить службу.
discovery.type: single-node
# Если вы ранее отключили плагин безопасности в opensearch.yml,
# обязательно включите его снова. В противном случае вы можете пропустить эту настройку.
plugins.security.disabled: false
Сохраните изменения и закройте файл
Укажите начальные и максимальные размеры кучи JVM
- Откройте файл
jvm.options:
vi /etc/opensearch/jvm.options
Измените значения для начального и максимального размеров кучи. В качестве отправной точки вы должны установить эти значения на половину доступной системной памяти. Для выделенных хостов это значение можно увеличить в зависимости от ваших рабочих требований.
Например, если у хост-машины 8 ГБ памяти, вы можете установить начальные и максимальные размеры кучи на 4 ГБ:
-Xms4g
-Xmx4g
- Сохраните изменения и закройте файл.
Настройка TLS
Сертификаты TLS обеспечивают дополнительную безопасность для вашего кластера, позволяя клиентам подтверждать личность хостов и шифровать трафик между клиентом и хостом. Для получения дополнительной информации обратитесь к разделам “Настройка сертификатов TLS” и “Генерация сертификатов”, которые включены в документацию по плагину безопасности. Для работы в среде разработки обычно достаточно самоподписанных сертификатов. Этот раздел проведет вас через основные шаги, необходимые для генерации собственных сертификатов TLS и их применения к вашему хосту OpenSearch.
- Перейдите в директорию, где будут храниться сертификаты
cd /etc/opensearch
- Удалите демонстрационные сертификаты
sudo rm -f *pem
- Сгенерируйте корневой сертификат
Это то, что вы будете использовать для подписания других сертификатов.
# Создайте закрытый ключ для корневого сертификата
sudo openssl genrsa -out root-ca-key.pem 2048
# Используйте закрытый ключ для создания самоподписанного корневого сертификата. Обязательно
# замените аргументы, переданные в -subj, чтобы они отражали ваш конкретный хост.
sudo openssl req -new -x509 -sha256 -key root-ca-key.pem -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=ROOT" -out root-ca.pem -days 730
- Создайте сертификат администратора
Этот сертификат используется для получения повышенных прав для выполнения административных задач, связанных с плагином безопасности.
# Создайте закрытый ключ для сертификата администратора
sudo openssl genrsa -out admin-key-temp.pem 2048
# Преобразуйте закрытый ключ в PKCS#8
sudo openssl pkcs8 -inform PEM -outform PEM -in admin-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out admin-key.pem
# Создайте запрос на подпись сертификата (CSR). Общим именем (CN) "A" можно пользоваться, так как этот сертификат
# используется для аутентификации повышенного доступа и не привязан к хосту.
sudo openssl req -new -key admin-key.pem -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=A" -out admin.csr
# Подпишите сертификат администратора с помощью корневого сертификата и закрытого ключа, которые вы создали ранее.
sudo openssl x509 -req -in admin.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out admin.pem -days 730
- Создайте закрытый ключ для сертификата узла
sudo openssl genrsa -out node1-key-temp.pem 2048
# Преобразуйте закрытый ключ в PKCS#8
sudo openssl pkcs8 -inform PEM -outform PEM -in node1-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out node1-key.pem
# Создайте CSR и замените аргументы, переданные в -subj, чтобы они отражали ваш конкретный хост
# Обратите внимание, что CN должен соответствовать DNS A записи для хоста — не используйте имя хоста.
sudo openssl req -new -key node1-key.pem -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=node1.dns.a-record" -out node1.csr
# Создайте файл расширений, который определяет SAN DNS имя для хоста
# Этот файл должен соответствовать DNS A записи хоста.
sudo sh -c 'echo subjectAltName=DNS:node1.dns.a-record > node1.ext'
# Подпишите сертификат узла с помощью корневого сертификата и закрытого ключа, которые вы создали ранее
sudo openssl x509 -req -in node1.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out node1.pem -days 730 -extfile node1.ext
- Удалите временные файлы, которые больше не нужны
sudo rm -f *temp.pem *csr *ext
- Убедитесь, что оставшиеся сертификаты принадлежат пользователю opensearch
sudo chown opensearch:opensearch admin-key.pem admin.pem node1-key.pem node1.pem root-ca-key.pem root-ca.pem root-ca.srl
- Добавьте эти сертификаты в
opensearch.yml
Как описано в разделе “Генерация сертификатов”. Продвинутые пользователи также могут выбрать добавление настроек с помощью скрипта.
#! /bin/bash
# Before running this script, make sure to replace the CN in the
# node's distinguished name with a real DNS A record.
echo "plugins.security.ssl.transport.pemcert_filepath: /etc/opensearch/node1.pem" | sudo tee -a /etc/opensearch/opensearch.yml
echo "plugins.security.ssl.transport.pemkey_filepath: /etc/opensearch/node1-key.pem" | sudo tee -a /etc/opensearch/opensearch.yml
echo "plugins.security.ssl.transport.pemtrustedcas_filepath: /etc/opensearch/root-ca.pem" | sudo tee -a /etc/opensearch/opensearch.yml
echo "plugins.security.ssl.http.enabled: true" | sudo tee -a /etc/opensearch/opensearch.yml
echo "plugins.security.ssl.http.pemcert_filepath: /etc/opensearch/node1.pem" | sudo tee -a /etc/opensearch/opensearch.yml
echo "plugins.security.ssl.http.pemkey_filepath: /etc/opensearch/node1-key.pem" | sudo tee -a /etc/opensearch/opensearch.yml
echo "plugins.security.ssl.http.pemtrustedcas_filepath: /etc/opensearch/root-ca.pem" | sudo tee -a /etc/opensearch/opensearch.yml
echo "plugins.security.allow_default_init_securityindex: true" | sudo tee -a /etc/opensearch/opensearch.yml
echo "plugins.security.authcz.admin_dn:" | sudo tee -a /etc/opensearch/opensearch.yml
echo " - 'CN=A,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA'" | sudo tee -a /etc/opensearch/opensearch.yml
echo "plugins.security.nodes_dn:" | sudo tee -a /etc/opensearch/opensearch.yml
echo " - 'CN=node1.dns.a-record,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA'" | sudo tee -a /etc/opensearch/opensearch.yml
echo "plugins.security.audit.type: internal_opensearch" | sudo tee -a /etc/opensearch/opensearch.yml
echo "plugins.security.enable_snapshot_restore_privilege: true" | sudo tee -a /etc/opensearch/opensearch.yml
echo "plugins.security.check_snapshot_restore_write_privileges: true" | sudo tee -a /etc/opensearch/opensearch.yml
echo "plugins.security.restapi.roles_enabled: [\"all_access\", \"security_rest_api_access\"]" | sudo tee -a /etc/opensearch/opensearch.yml
- (Необязательно) Добавление доверия к самоподписанному корневому сертификату
# Скопируйте корневой сертификат в правильную директорию
sudo cp /etc/opensearch/root-ca.pem /etc/pki/ca-trust/source/anchors/
# Добавьте доверие
sudo update-ca-trust
Настройка пользователя
Пользователи определяются и аутентифицируются OpenSearch различными способами. Один из методов, который не требует дополнительной инфраструктуры на стороне сервера, — это ручная настройка пользователей в файле internal_users.yml. В следующих шагах объясняется, как добавить нового внутреннего пользователя и как заменить пароль по умолчанию для администратора с помощью скрипта.
- Перейдите в директорию инструментов плагина безопасности
cd /usr/share/opensearch/plugins/opensearch-security/tools
- Запустите
hash.shдля генерации нового пароля
- Этот скрипт завершится с ошибкой, если путь к JDK не был определен.
# Пример вывода, если JDK не найден...
$ ./hash.sh
**************************************************************************
** Этот инструмент будет устаревшим в следующем крупном релизе OpenSearch **
** https://github.com/opensearch-project/security/issues/1755 **
**************************************************************************
which: no java in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/user/.local/bin:/home/user/bin)
WARNING: nor OPENSEARCH_JAVA_HOME nor JAVA_HOME is set, will use
./hash.sh: line 35: java: command not found
- Объявите переменную окружения при вызове скрипта, чтобы избежать проблем
OPENSEARCH_JAVA_HOME=/usr/share/opensearch/jdk ./hash.sh
- Введите желаемый пароль на запросе и запомните хэш, который будет выведен
- Откройте файл
internal_users.yml
sudo vi /etc/opensearch/opensearch-security/internal_users.yml
- Добавьте нового внутреннего пользователя и замените хэш внутри
internal_users.ymlна вывод, предоставленныйhash.shна шаге 2
Файл должен выглядеть примерно так:
---
# This is the internal user database
# The hash value is a bcrypt hash and can be generated with plugin/tools/hash.sh
_meta:
type: "internalusers"
config_version: 2
# Define your internal users here
admin:
hash: "$2y$1EXAMPLEQqwS8TUcoEXAMPLEeZ3lEHvkEXAMPLERqjyh1icEXAMPLE."
reserved: true
backend_roles:
- "admin"
description: "Admin user"
user1:
hash: "$2y$12$zoHpvTCRjjQr6h0PEaabueCaGam3/LDvT6rZZGDGMusD7oehQjw/O"
reserved: false
backend_roles: []
description: "New internal user"
# Other users
...
Применение изменений
Теперь, когда сертификаты TLS установлены, а демонстрационные пользователи были удалены или им были назначены новые пароли, последний шаг — применить изменения конфигурации. Этот последний шаг конфигурации требует вызова securityadmin.sh, пока OpenSearch работает на хосте.
Убедитесь, что OpenSearch запущен
OpenSearch должен быть запущен, чтобы securityadmin.sh мог применить изменения. Если вы внесли изменения в opensearch.yml, перезапустите OpenSearch:
sudo systemctl restart opensearch
Откройте отдельную сессию терминала на хосте и перейдите в директорию, содержащую securityadmin.sh
# Перейдите в правильную директорию
cd /usr/share/opensearch/plugins/opensearch-security/tools
Вызовите скрипт
Смотрите раздел “Применение изменений с помощью securityadmin.sh” для определения аргументов, которые вы должны передать.
# Вы можете опустить переменную окружения, если вы объявили ее в вашем $PATH.
OPENSEARCH_JAVA_HOME=/usr/share/opensearch/jdk ./securityadmin.sh -cd /etc/opensearch/opensearch-security/ -cacert /etc/opensearch/root-ca.pem -cert /etc/opensearch/admin.pem -key /etc/opensearch/admin-key.pem -icl -nhnv
Параметры скрипта:
-cd: указывает директорию конфигурации.-cacert: указывает путь к корневому сертификату.-cert: указывает путь к сертификату администратора.-key: указывает путь к закрытому ключу администратора.-icl: включает режим конфигурации.-nhnv: отключает проверку хоста и не выводит информацию о версии.
Проверка работы сервиса
OpenSearch теперь работает на вашем хосте с пользовательскими сертификатами TLS и безопасным пользователем для базовой аутентификации. Вы можете проверить внешнюю доступность, отправив API-запрос к вашему узлу OpenSearch с другого хоста.
Во время предыдущего теста вы направляли запросы на localhost. Теперь, когда сертификаты TLS были применены и новые сертификаты ссылаются на фактическую DNS-запись вашего хоста, запросы к localhost не пройдут проверку CN, и сертификат будет считаться недействительным. Вместо этого запросы должны быть отправлены на адрес, который вы указали при генерации сертификата.
Перед отправкой запросов вы должны добавить доверие к корневому сертификату на вашем клиенте. Если вы не добавите доверие, вам нужно будет использовать опцию
-k, чтобы cURL игнорировал проверку CN и корневого сертификата.
$ curl https://your.host.address:9200 -u admin:yournewpassword -k
{
"name":"hostname",
"cluster_name":"opensearch",
"cluster_uuid":"QqgpHCbnSRKcPAizqjvoOw",
"version":{
"distribution":"opensearch",
"number":<version>,
"build_type":<build-type>,
"build_hash":<build-hash>,
"build_date":<build-date>,
"build_snapshot":false,
"lucene_version":<lucene-version>,
"minimum_wire_compatibility_version":"7.10.0",
"minimum_index_compatibility_version":"7.0.0"
},
"tagline":"The OpenSearch Project: https://opensearch.org/"
}
Обновление до новой версии
Экземпляры OpenSearch, установленные с помощью dpkg или apt-get, можно легко обновить до более новой версии.
Ручное обновление с помощью DPKG
Скачайте Debian-пакет для желаемой версии обновления непосредственно со страницы загрузок OpenSearch Project.
Перейдите в директорию, содержащую дистрибутив, и выполните следующую команду:
sudo dpkg -i opensearch-3.1.0-linux-x64.deb
Обновление с помощью APT-GET
Чтобы обновить до последней версии OpenSearch с помощью apt-get, выполните:
sudo apt-get upgrade opensearch
Вы также можете обновить до конкретной версии OpenSearch:
sudo apt-get upgrade opensearch=<version>
Автоматическая перезагрузка сервиса после обновления пакета (2.13.0+)
Чтобы автоматически перезапустить OpenSearch после обновления пакета, включите opensearch.service через systemd:
sudo systemctl enable opensearch.service
8.2.2 - Установка OpenSearch Dashboards
OpenSearch Dashboards предоставляет полностью интегрированное решение для визуального изучения, обнаружения и запроса ваших данных наблюдаемости. Вы можете установить OpenSearch Dashboards с помощью одного из следующих вариантов:
- Docker
- Tarball
- RPM
- Debian
- Helm
- Windows
Совместимость с браузерами
OpenSearch Dashboards поддерживает следующие веб-браузеры:
- Chrome
- Firefox
- Safari
- Edge (Chromium)
Другие браузеры на основе Chromium также могут работать. Internet Explorer и Microsoft Edge Legacy не поддерживаются.
Совместимость с Node.js
OpenSearch Dashboards требует бинарный файл среды выполнения Node.js для работы. Один из них включен в дистрибутивные пакеты, доступные на странице загрузок OpenSearch.
OpenSearch Dashboards версии 2.8.0 и новее могут использовать версии Node.js 14, 16 и 18. Дистрибутивные пакеты для OpenSearch Dashboards версии 2.10.0 и новее включают Node.js 18 и 14 (для обратной совместимости).
Чтобы использовать бинарный файл среды выполнения Node.js, отличный от включенных в дистрибутивные пакеты, выполните следующие шаги:
Скачайте и установите Node.js; совместимые версии: >=14.20.1 <19.
Установите путь установки в переменные окружения NODE_HOME или NODE_OSD_HOME.
На UNIX, если Node.js установлен в /usr/local/nodejs, а бинарный файл среды выполнения находится по пути /usr/local/nodejs/bin/node:
export NODE_HOME=/usr/local/nodejsЕсли Node.js установлен с помощью NVM, а бинарный файл среды выполнения находится по пути /Users/user/.nvm/versions/node/v18.19.0/bin/node:
export NODE_HOME=/Users/user/.nvm/versions/node/v18.19.0 # или, если NODE_HOME используется для чего-то другого: export NODE_OSD_HOME=/Users/user/.nvm/versions/node/v18.19.0На Windows, если Node.js установлен в C:\Program Files\nodejs, а бинарный файл среды выполнения находится по пути C:\Program Files\nodejs\node.exe:
set "NODE_HOME=C:\Program Files\nodejs" # или с использованием PowerShell: $Env:NODE_HOME = 'C:\Program Files\nodejs'
Ознакомьтесь с документацией вашей операционной системы, чтобы внести постоянные изменения в переменные окружения.
Скрипт запуска OpenSearch Dashboards, bin/opensearch-dashboards, ищет бинарный файл среды выполнения Node.js, используя NODE_OSD_HOME, затем NODE_HOME, прежде чем использовать бинарные файлы, включенные в дистрибутивные пакеты. Если подходящий бинарный файл среды выполнения Node.js не найден, скрипт запуска попытается найти его в системном PATH, прежде чем завершить работу с ошибкой.
Конфигурация
Чтобы узнать, как настроить TLS для OpenSearch Dashboards, смотрите раздел Настройка TLS.
8.2.2.1 - Запуск OpenSearch Dashboards с использованием Docker
Выполните команду для загрузки образа OpenSearch Dashboards:
docker pull opensearchproject/opensearch-dashboards:2Создайте файл
docker-compose.yml, соответствующий вашей среде. Пример файла, который включает OpenSearch Dashboards, доступен на странице установки OpenSearch Docker.Так же, как и для
opensearch.yml, вы можете передать пользовательский файлopensearch_dashboards.ymlв контейнер в файле Docker Compose.Запустите команду:
docker compose upПодождите, пока контейнеры запустятся. Затем ознакомьтесь с документацией OpenSearch Dashboards.
Когда закончите, выполните команду:
docker compose down
8.2.2.2 - Установка OpenSearch Dashboards (Debian)
Установка OpenSearch Dashboards с использованием менеджера пакетов Advanced Packaging Tool (APT) значительно упрощает процесс по сравнению с методом Tarball. Например, менеджер пакетов обрабатывает несколько технических аспектов, таких как путь установки, расположение конфигурационных файлов и создание службы, управляемой systemd.
Перед установкой OpenSearch Dashboards необходимо настроить кластер OpenSearch. Обратитесь к руководству по установке OpenSearch для Debian для получения инструкций.
Данное руководство предполагает, что вы уверенно работаете с интерфейсом командной строки (CLI) Linux. Вы должны понимать, как вводить команды, перемещаться между директориями и редактировать текстовые файлы. Некоторые примеры команд ссылаются на текстовый редактор vi, но вы можете использовать любой доступный текстовый редактор.
Установка OpenSearch Dashboards из пакета
Скачайте пакет Debian для нужной версии непосредственно с страницы загрузок OpenSearch. Пакет Debian доступен для архитектур x64 и arm64.
Установите пакет с помощью
dpkgиз командной строки:Для x64:
sudo dpkg -i opensearch-dashboards-3.1.0-linux-x64.debДля arm64:
sudo dpkg -i opensearch-dashboards-3.1.0-linux-arm64.deb
После завершения установки перезагрузите конфигурацию менеджера systemd:
sudo systemctl daemon-reloadВключите OpenSearch как службу:
sudo systemctl enable opensearch-dashboardsЗапустите службу OpenSearch:
sudo systemctl start opensearch-dashboardsПроверьте, что OpenSearch запустился корректно:
sudo systemctl status opensearch-dashboards
Проверка подписи
Пакет Debian не подписан. Если вы хотите проверить подпись, проект OpenSearch предоставляет файл .sig, а также .deb пакет для использования с GNU Privacy Guard (GPG).
Скачайте нужный пакет Debian:
curl -SLO https://artifacts.opensearch.org/releases/bundle/opensearch-dashboards/3.1.0/opensearch-dashboards-3.1.0-linux-x64.debСкачайте соответствующий файл подписи:
curl -SLO https://artifacts.opensearch.org/releases/bundle/opensearch-dashboards/3.1.0/opensearch-dashboards-3.1.0-linux-x64.deb.sigСкачайте и импортируйте GPG-ключ:
curl -o- https://artifacts.opensearch.org/publickeys/opensearch-release.pgp | gpg --import -Проверьте подпись:
gpg --verify opensearch-dashboards-3.1.0-linux-x64.deb.sig opensearch-dashboards-3.1.0-linux-x64.deb
Установка OpenSearch Dashboards из репозитория APT
APT, основной инструмент управления пакетами для операционных систем на базе Debian, позволяет загружать и устанавливать пакет Debian из репозитория APT.
Установите необходимые пакеты:
sudo apt-get update && sudo apt-get -y install lsb-release ca-certificates curl gnupg2Импортируйте публичный GPG-ключ. Этот ключ используется для проверки подписи репозитория APT:
curl -o- https://artifacts.opensearch.org/publickeys/opensearch-release.pgp | sudo gpg --dearmor --batch --yes -o /usr/share/keyrings/opensearch-release-keyringСоздайте репозиторий APT для OpenSearch:
echo "deb [signed-by=/usr/share/keyrings/opensearch-release-keyring] https://artifacts.opensearch.org/releases/bundle/opensearch-dashboards/3.x/apt stable main" | sudo tee /etc/apt/sources.list.d/opensearch-dashboards-3.x.listПроверьте, что репозиторий был успешно создан:
sudo apt-get updateС добавленной информацией о репозитории, перечислите все доступные версии OpenSearch:
sudo apt list -a opensearch-dashboardsВыберите версию OpenSearch, которую хотите установить:
Если не указано иное, будет установлена последняя доступная версия OpenSearch:
sudo apt-get install opensearch-dashboardsЧтобы установить конкретную версию OpenSearch Dashboards, укажите номер версии после имени пакета:
# Укажите версию вручную с помощью opensearch=<version> sudo apt-get install opensearch-dashboards=3.1.0
После завершения установки включите OpenSearch:
sudo systemctl enable opensearch-dashboardsЗапустите OpenSearch:
sudo systemctl start opensearch-dashboardsПроверьте, что OpenSearch запустился корректно:
sudo systemctl status opensearch-dashboards
Изучение OpenSearch Dashboards
По умолчанию OpenSearch Dashboards, как и OpenSearch, связывается с localhost при первоначальной установке. В результате OpenSearch Dashboards недоступен с удаленного хоста, если конфигурация не обновлена.
Откройте файл
opensearch_dashboards.yml:sudo vi /etc/opensearch-dashboards/opensearch_dashboards.ymlУкажите сетевой интерфейс, к которому должен связываться OpenSearch Dashboards:
# Используйте 0.0.0.0, чтобы связаться с любым доступным интерфейсом. server.host: 0.0.0.0Сохраните изменения и выйдите из редактора.
Перезапустите OpenSearch Dashboards, чтобы применить изменения конфигурации:
sudo systemctl restart opensearch-dashboardsВ веб-браузере перейдите к OpenSearch Dashboards. Порт по умолчанию — 5601.
Войдите с использованием имени пользователя
adminи пароляadmin. (Для OpenSearch 2.12 и новее пароль должен быть пользовательским паролем администратора.)Посетите раздел “Начало работы с OpenSearch Dashboards”, чтобы узнать больше.
Обновление до новой версии
Экземпляры OpenSearch Dashboards, установленные с помощью dpkg или apt-get, можно легко обновить до новой версии.
Ручное обновление с помощью DPKG
Скачайте пакет Debian для желаемой версии обновления непосредственно со страницы загрузок проекта OpenSearch.
Перейдите в директорию, содержащую дистрибутив, и выполните следующую команду:
sudo dpkg -i opensearch-dashboards-3.1.0-linux-x64.deb
Обновление с помощью APT-GET
Чтобы обновить до последней версии OpenSearch Dashboards с помощью apt-get, выполните следующую команду:
sudo apt-get upgrade opensearch-dashboards
Вы также можете обновить до конкретной версии OpenSearch Dashboards, указав номер версии:
sudo apt-get upgrade opensearch-dashboards=<version>
Автоматический перезапуск службы после обновления пакета (2.13.0+)
Чтобы автоматически перезапустить OpenSearch Dashboards после обновления пакета, включите службу opensearch-dashboards.service через systemd:
sudo systemctl enable opensearch-dashboards.service
8.2.2.3 - Настройка TLS для OpenSearch Dashboards
| Настройка | Описание |
|---|---|
server.ssl.enabled | Включает SSL-соединение между сервером OpenSearch Dashboards и веб-браузером пользователя. Установите значение true для HTTPS или false для HTTP. |
server.ssl.supportedProtocols | Указывает массив поддерживаемых протоколов TLS. Возможные значения: TLSv1, TLSv1.1, TLSv1.2, TLSv1.3. По умолчанию: ['TLSv1.1', 'TLSv1.2', 'TLSv1.3']. |
server.ssl.cipherSuites | Указывает массив шифров TLS. Необязательная настройка. |
server.ssl.certificate | Если server.ssl.enabled установлено в true, указывает полный путь к действительному сертификату сервера Privacy Enhanced Mail (PEM) для OpenSearch Dashboards. Вы можете сгенерировать свой сертификат или получить его у центра сертификации (CA). |
server.ssl.key | Если server.ssl.enabled установлено в true, указывает полный путь к ключу для вашего серверного сертификата, например, /usr/share/opensearch-dashboards-1.0.0/config/my-client-cert-key.pem. Вы можете сгенерировать свой сертификат или получить его у CA. |
server.ssl.keyPassphrase | Устанавливает пароль для ключа. Удалите эту настройку, если у ключа нет пароля. Необязательная настройка. |
server.ssl.keystore.path | Использует файл JKS (Java KeyStore) или PKCS12/PFX (Public-Key Cryptography Standards) вместо сертификата и ключа PEM. |
server.ssl.keystore.password | Устанавливает пароль для хранилища ключей. Обязательная настройка. |
server.ssl.clientAuthentication | Указывает режим аутентификации клиента TLS. Может быть одним из следующих: none, optional или required. Если установлено в required, ваш веб-браузер должен отправить действительный клиентский сертификат, подписанный CA, настроенным в server.ssl.certificateAuthorities. По умолчанию: none. |
server.ssl.certificateAuthorities | Указывает полный путь к одному или нескольким сертификатам CA в массиве, которые выдают сертификат, используемый для аутентификации клиента. Обязательная настройка, если server.ssl.clientAuthentication установлено в optional или required. |
server.ssl.truststore.path | Использует файл JKS или PKCS12/PFX trust store вместо сертификатов CA PEM. |
server.ssl.truststore.password | Устанавливает пароль для trust store. Обязательная настройка. |
opensearch.ssl.verificationMode | Устанавливает связь между OpenSearch и OpenSearch Dashboards. Допустимые значения: full, certificate или none. Рекомендуется использовать full, если TLS включен, что включает проверку имени хоста. certificate проверяет сертификат, но не имя хоста. none не выполняет никаких проверок (подходит для HTTP). По умолчанию: full. |
opensearch.ssl.certificateAuthorities | Если opensearch.ssl.verificationMode установлено в full или certificate, указывает полный путь к одному или нескольким сертификатам CA в массиве, которые составляют доверенную цепочку для кластера OpenSearch. Например, вам может потребоваться включить корневой CA и промежуточный CA, если вы использовали промежуточный CA для выдачи ваших сертификатов администратора, клиента и узла. |
opensearch.ssl.truststore.path | Использует файл trust store JKS или PKCS12/PFX вместо сертификатов CA PEM. |
opensearch.ssl.truststore.password | Устанавливает пароль для trust store. Обязательная настройка. |
opensearch.ssl.alwaysPresentCertificate | Отправляет клиентский сертификат в кластер OpenSearch, если установлено значение true, что необходимо, когда mTLS включен в OpenSearch. По умолчанию: false. |
opensearch.ssl.certificate | Если opensearch.ssl.alwaysPresentCertificate установлено в true, указывает полный путь к действительному клиентскому сертификату для кластера OpenSearch. Вы можете сгенерировать свой сертификат или получить его у CA. |
opensearch.ssl.key | Если opensearch.ssl.alwaysPresentCertificate установлено в true, указывает полный путь к ключу для клиентского сертификата. Вы можете сгенерировать свой сертификат или получить его у CA. |
opensearch.ssl.keyPassphrase | Устанавливает пароль для ключа. Удалите эту настройку, если у ключа нет пароля. Необязательная настройка. |
opensearch.ssl.keystore.path | Использует файл хранилища ключей JKS или PKCS12/PFX вместо сертификата и ключа PEM. |
opensearch.ssl.keystore.password | Устанавливает пароль для хранилища ключей. Обязательная настройка. |
opensearch_security.cookie.secure | Если TLS включен для OpenSearch Dashboards, измените эту настройку на true. Для HTTP установите значение false. |
Пример конфигурации opensearch_dashboards.yml
Следующая конфигурация opensearch_dashboards.yml показывает, как OpenSearch и OpenSearch Dashboards могут работать на одной машине с демонстрационной конфигурацией:
server.host: '0.0.0.0'
server.ssl.enabled: true
server.ssl.certificate: /usr/share/opensearch-dashboards/config/client-cert.pem
server.ssl.key: /usr/share/opensearch-dashboards/config/client-cert-key.pem
opensearch.hosts: ["https://localhost:9200"]
opensearch.ssl.verificationMode: full
opensearch.ssl.certificateAuthorities: [ "/usr/share/opensearch-dashboards/config/root-ca.pem", "/usr/share/opensearch-dashboards/config/intermediate-ca.pem" ]
opensearch.username: "kibanaserver"
opensearch.password: "kibanaserver"
opensearch.requestHeadersAllowlist: [ authorization,securitytenant ]
opensearch_security.multitenancy.enabled: true
opensearch_security.multitenancy.tenants.preferred: ["Private", "Global"]
opensearch_security.readonly_mode.roles: ["kibana_read_only"]
opensearch_security.cookie.secure: true
Если вы используете опцию установки через Docker, вы можете передать пользовательский файл opensearch_dashboards.yml в контейнер. Чтобы узнать больше, посетите страницу установки Docker.
После включения этих настроек и запуска приложения вы можете подключиться к OpenSearch Dashboards по адресу https://localhost:5601. Возможно, вам потребуется подтвердить предупреждение браузера, если ваши сертификаты самоподписанные. Чтобы избежать такого предупреждения (или полной несовместимости с браузером), рекомендуется использовать сертификаты от доверенного центра сертификации (CA).
8.2.3 - configuring opensearch
Динамические настройки
Динамические настройки индекса — это настройки, которые вы можете обновлять в любое время. Вы можете настраивать динамические параметры OpenSearch через API настроек кластера. Для получения подробной информации смотрите раздел Обновление настроек кластера с помощью API.
При возможности используйте API настроек кластера; файл opensearch.yml локален для каждого узла, в то время как API применяет настройки ко всем узлам в кластере.
Статические настройки
Некоторые операции являются статическими и требуют изменения конфигурационного файла opensearch.yml и перезапуска кластера. В общем, эти настройки относятся к сетевым параметрам, формированию кластера и локальной файловой системе. Чтобы узнать больше, смотрите раздел Формирование кластера.
Указание настроек в виде переменных окружения
Вы можете указывать переменные окружения следующими способами:
Аргументы при запуске
Вы можете указать переменные окружения в качестве аргументов, используя -E при запуске OpenSearch:
./opensearch -Ecluster.name=opensearch-cluster -Enode.name=opensearch-node1 -Ehttp.host=0.0.0.0 -Ediscovery.type=single-node
Непосредственно в среде оболочки
Вы можете настроить переменные окружения непосредственно в среде оболочки перед запуском OpenSearch, как показано в следующем примере:
export OPENSEARCH_JAVA_OPTS="-Xms2g -Xmx2g"
export OPENSEARCH_PATH_CONF="/etc/opensearch"
./opensearch
Файл службы systemd
При запуске OpenSearch как службы, управляемой systemd, вы можете указать переменные окружения в файле службы, как показано в следующем примере:
# /etc/systemd/system/opensearch.service.d/override.conf
[Service]
Environment="OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g"
Environment="OPENSEARCH_PATH_CONF=/etc/opensearch"
После создания или изменения файла перезагрузите конфигурацию systemd и перезапустите службу с помощью следующих команд:
sudo systemctl daemon-reload
sudo systemctl restart opensearch
Переменные окружения Docker
При запуске OpenSearch в Docker вы можете указать переменные окружения, используя опцию -e с командой docker run, как показано в следующей команде:
docker run -e "OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g" -e "OPENSEARCH_PATH_CONF=/usr/share/opensearch/config" opensearchproject/opensearch:latest
Обновление настроек кластера с помощью API
Первый шаг в изменении настройки — это просмотр текущих настроек, отправив следующий запрос:
GET _cluster/settings?include_defaults=true
Для более краткого резюме нестандартных настроек отправьте следующий запрос:
GET _cluster/settings
В API настроек кластера существуют три категории настроек: постоянные, временные и стандартные. Постоянные настройки сохраняются после перезапуска кластера. После перезапуска OpenSearch очищает временные настройки.
Если вы указываете одну и ту же настройку в нескольких местах, OpenSearch использует следующий порядок приоритета:
- Временные настройки
- Постоянные настройки
- Настройки из
opensearch.yml - Стандартные настройки
Чтобы изменить настройку, используйте API настроек кластера и укажите новое значение как постоянное или временное. Этот пример показывает форму плоских настроек:
PUT _cluster/settings
{
"persistent" : {
"action.auto_create_index" : false
}
}
Вы также можете использовать расширенную форму, которая позволяет вам копировать и вставлять из ответа GET и изменять существующие значения:
PUT _cluster/settings
{
"persistent": {
"action": {
"auto_create_index": false
}
}
}
Конфигурационный файл
Вы можете найти файл opensearch.yml по следующему пути:
- Для Docker:
/usr/share/opensearch/config/opensearch.yml - Для большинства дистрибутивов Linux:
/etc/opensearch/opensearch.yml
Вы можете отредактировать переменную OPENSEARCH_PATH_CONF=/etc/opensearch, чтобы изменить расположение каталога конфигурации. Эта переменная берется из /etc/default/opensearch (для Debian-пакета) и /etc/sysconfig/opensearch (для RPM-пакета).
Если вы установите свою пользовательскую переменную OPENSEARCH_PATH_CONF, имейте в виду, что другие стандартные переменные окружения не будут загружены.
В файле opensearch.yml вы не помечаете настройки как постоянные или временные, и настройки используют плоскую форму:
cluster.name: my-application
action.auto_create_index: true
compatibility.override_main_response_version: true
Демонстрационная конфигурация включает в себя ряд настроек для плагина безопасности, которые вы должны изменить перед использованием OpenSearch для производственной нагрузки. Чтобы узнать больше, смотрите раздел Безопасность.
(Необязательно) Конфигурация заголовков CORS
Если вы работаете над клиентским приложением, которое взаимодействует с кластером OpenSearch на другом домене, вы можете настроить заголовки в opensearch.yml, чтобы разрешить разработку локального приложения на той же машине. Используйте механизм Cross Origin Resource Sharing (CORS), чтобы ваше приложение могло делать вызовы к API OpenSearch, работающему локально. Добавьте следующие строки в ваш файл custom-opensearch.yml (обратите внимание, что символ “-” должен быть первым символом в каждой строке):
- http.host: 0.0.0.0
- http.port: 9200
- http.cors.allow-origin: "http://localhost"
- http.cors.enabled: true
- http.cors.allow-headers: X-Requested-With,X-Auth-Token,Content-Type,Content-Length,Authorization
- http.cors.allow-credentials: true
8.2.3.1 - Настройки доступности и восстановления
- Снимки
- Ограничение задач менеджера кластера
- Хранение с удаленной поддержкой
- Обратное давление при поиске
- Обратное давление при индексации шардов
- Репликация сегментов
- Репликация между кластерами
Чтобы узнать больше о статических и динамических настройках, см. Настройка OpenSearch.
Настройки снимков
OpenSearch поддерживает следующие настройки снимков:
- snapshot.max_concurrent_operations (Динамическое, целое число): Максимальное количество одновременных операций снимков. По умолчанию 1000.
Настройки снимков, связанные с безопасностью
Для настроек снимков, связанных с безопасностью, см. Настройки безопасности.
Настройки файловой системы
Для получения информации о настройках файловой системы см. Общая файловая система.
Настройки Amazon S3
Для получения информации о настройках репозитория Amazon S3 см. Amazon S3.
Настройки ограничения задач менеджера кластера
Для получения информации о настройках ограничения задач менеджера кластера см. Установка пределов ограничения.
Настройки хранения с удаленной поддержкой
OpenSearch поддерживает следующие настройки хранения с удаленной поддержкой на уровне кластера:
cluster.remote_store.translog.buffer_interval (Динамическое, единица времени): Значение по умолчанию для интервала буфера транзакционного лога, используемого при выполнении периодических обновлений транзакционного лога. Эта настройка эффективна только в том случае, если настройка индекса
index.remote_store.translog.buffer_intervalотсутствует.remote_store.moving_average_window_size (Динамическое, целое число): Размер окна скользящего среднего, используемый для расчета значений скользящей статистики, доступных через API статистики удаленного хранилища. По умолчанию 20. Минимально допустимое значение - 5.
Для получения дополнительной информации о настройках хранения с удаленной поддержкой см. Хранение с удаленной поддержкой и Настройка хранения с удаленной поддержкой.
Для получения информации о настройках обратного давления сегментов см. Настройки обратного давления сегментов.
Настройки обратного давления при поиске
Обратное давление при поиске - это механизм, используемый для выявления ресурсоемких запросов на поиск и их отмены, когда узел испытывает нагрузку. Для получения дополнительной информации см. Настройки обратного давления при поиске.
Настройки обратного давления при индексации шардов
Обратное давление при индексации шардов - это механизм умного отклонения на уровне шардов, который динамически отклоняет запросы на индексацию, когда ваш кластер испытывает нагрузку. Для получения дополнительной информации см. Настройки обратного давления при индексации шардов.
Настройки репликации сегментов
Для получения информации о настройках репликации сегментов см. Репликация сегментов.
Для получения информации о настройках обратного давления репликации сегментов см. Обратное давление репликации сегментов.
Настройки репликации между кластерами
Для получения информации о настройках репликации между кластерами см. Настройки репликации.
8.2.3.2 - Конфигурация и системные настройки
Для получения обзора создания кластера OpenSearch и примеров настроек конфигурации см. раздел Создание кластера. Чтобы узнать больше о статических и динамических настройках, см. раздел Настройка OpenSearch.
OpenSearch поддерживает следующие системные настройки:
cluster.name (Статическая, строка): Имя кластера.
node.name (Статическая, строка): Описательное имя для узла.
node.roles (Статическая, список): Определяет одну или несколько ролей для узла OpenSearch. Допустимые значения:
cluster_manager,data,ingest,search,ml,remote_cluster_clientиcoordinating_only.path.data (Статическая, строка): Путь к директории, где хранятся ваши данные. Разделяйте несколько местоположений запятыми.
path.logs (Статическая, строка): Путь к файлам журналов.
bootstrap.memory_lock (Статическая, логическое): Блокирует память при запуске. Рекомендуется установить размер кучи примерно на половину доступной памяти в системе и убедиться, что владелец процесса имеет право использовать этот лимит. OpenSearch работает неэффективно, когда система использует свопинг памяти.
8.2.3.3 - Сетевые настройки
Чтобы узнать больше о статических и динамических настройках, см. раздел Настройка OpenSearch.
OpenSearch поддерживает следующие общие сетевые настройки:
network.host (Статическая, список): Привязывает узел OpenSearch к адресу. Используйте
0.0.0.0, чтобы включить все доступные сетевые интерфейсы, или укажите IP-адрес, назначенный конкретному интерфейсу. Настройкаnetwork.hostявляется комбинациейnetwork.bind_hostиnetwork.publish_host, если они имеют одинаковое значение. Альтернативойnetwork.hostявляется отдельная настройкаnetwork.bind_hostиnetwork.publish_hostпо мере необходимости. См. раздел Расширенные сетевые настройки.http.port (Статическая, одно значение или диапазон): Привязывает узел OpenSearch к пользовательскому порту или диапазону портов для HTTP-связи. Вы можете указать адрес или диапазон адресов. По умолчанию — 9200-9300.
transport.port (Статическая, одно значение или диапазон): Привязывает узел OpenSearch к пользовательскому порту для связи между узлами. Вы можете указать адрес или диапазон адресов. По умолчанию — 9300-9400.
Расширенные сетевые настройки
OpenSearch поддерживает следующие расширенные сетевые настройки:
network.bind_host (Статическая, список): Привязывает узел OpenSearch к адресу или адресам для входящих соединений. По умолчанию — значение из
network.host.network.publish_host (Статическая, список): Указывает адрес или адреса, которые узел OpenSearch публикует для других узлов в кластере, чтобы они могли подключиться к нему.
Расширенные HTTP-настройки
OpenSearch поддерживает следующие расширенные сетевые настройки для HTTP-связи:
http.host (Статическая, список): Устанавливает адрес узла OpenSearch для HTTP-связи. Настройка
http.hostявляется комбинациейhttp.bind_hostиhttp.publish_host, если они имеют одинаковое значение. Альтернативойhttp.hostявляется отдельная настройкаhttp.bind_hostиhttp.publish_hostпо мере необходимости.http.bind_host (Статическая, список): Указывает адрес или адреса, к которым узел OpenSearch привязывается для прослушивания входящих HTTP-соединений.
http.publish_host (Статическая, список): Указывает адрес или адреса, которые узел OpenSearch публикует для других узлов для HTTP-связи.
http.compression (Статическая, логическое): Включает поддержку сжатия с использованием
Accept-Encoding, когда это применимо. Когда включен HTTPS, по умолчанию — false, в противном случае — true. Отключение сжатия для HTTPS помогает снизить потенциальные риски безопасности, такие как атаки BREACH. Чтобы включить сжатие для HTTPS-трафика, явно установитеhttp.compressionв true.http.max_header_size (Статическая, строка): Максимальный общий размер всех HTTP-заголовков, разрешенный в запросе. По умолчанию — 16KB.
Расширенные транспортные настройки
OpenSearch поддерживает следующие расширенные сетевые настройки для транспортной связи:
transport.host (Статическая, список): Устанавливает адрес узла OpenSearch для транспортной связи. Настройка
transport.hostявляется комбинациейtransport.bind_hostиtransport.publish_host, если они имеют одинаковое значение. Альтернативойtransport.hostявляется отдельная настройкаtransport.bind_hostиtransport.publish_hostпо мере необходимости.transport.bind_host (Статическая, список): Указывает адрес или адреса, к которым узел OpenSearch привязывается для прослушивания входящих транспортных соединений.
transport.publish_host (Статическая, список): Указывает адрес или адреса, которые узел OpenSearch публикует для других узлов для транспортной связи.OpenSearch использует настройки HTTP для конфигурации связи с внешними клиентами через REST API и транспортные настройки для внутренней связи между узлами в OpenSearch.
Выбор транспорта
По умолчанию OpenSearch использует транспорт, предоставляемый модулем transport-netty4, который использует движок Netty 4 как для внутренней TCP-связи между узлами в кластере, так и для внешней HTTP-связи с клиентами. Эта связь полностью асинхронна и неблокирующая. В следующей таблице перечислены другие доступные плагины транспорта, которые могут использоваться взаимозаменяемо.
| Плагин | Описание |
|---|---|
| transport-reactor-netty4 | HTTP-транспорт OpenSearch на основе Project Reactor и Netty 4 (экспериментальный) |
Установка
./bin/opensearch-plugin install transport-reactor-netty4
Конфигурация (с использованием opensearch.yml)
http.type: reactor-netty4
http.type: reactor-netty4-secure
8.2.3.4 - Настройки обнаружения и шлюза
Чтобы узнать больше о статических и динамических настройках, см. раздел Настройка OpenSearch.
Настройки обнаружения
Процесс обнаружения используется при формировании кластера. Он включает в себя обнаружение узлов и выбор узла-менеджера кластера. OpenSearch поддерживает следующие настройки обнаружения:
discovery.seed_hosts (Статическая, список): Список хостов, которые выполняют обнаружение при запуске узла. По умолчанию список хостов:
["127.0.0.1", "[::1]"].discovery.seed_providers (Статическая, список): Указывает типы провайдеров начальных хостов, которые будут использоваться для получения адресов начальных узлов с целью запуска процесса обнаружения.
discovery.type (Статическая, строка): По умолчанию OpenSearch формирует кластер с несколькими узлами. Установите
discovery.typeвsingle-node, чтобы сформировать кластер с одним узлом.cluster.initial_cluster_manager_nodes (Статическая, список): Список узлов, имеющих право быть узлами-менеджерами кластера, используемых для начальной загрузки кластера.
Настройки шлюза
Локальный шлюз хранит состояние кластера и данные шардов, которые используются при перезапуске кластера. OpenSearch поддерживает следующие настройки локального шлюза:
gateway.recover_after_nodes (Статическая, целое число): После полного перезапуска кластера количество узлов, которые должны присоединиться к кластеру, прежде чем может начаться восстановление.
gateway.recover_after_data_nodes (Статическая, целое число): После полного перезапуска кластера количество узлов данных, которые должны присоединиться к кластеру, прежде чем может начаться восстановление.
gateway.expected_data_nodes (Статическая, целое число): Ожидаемое количество узлов данных, которые должны существовать в кластере. После того как ожидаемое количество узлов присоединится к кластеру, может начаться восстановление локальных шардов.
gateway.recover_after_time (Статическая, значение времени): Количество времени, которое нужно подождать перед началом восстановления, если количество узлов данных меньше ожидаемого количества узлов данных.
8.2.3.5 - Настройки безопасности
Для полного списка файлов конфигурации плагина безопасности см. раздел Изменение файлов YAML.
Следующие разделы описывают настройки, связанные с безопасностью, в файле opensearch.yml. Вы можете найти opensearch.yml в <OPENSEARCH_HOME>/config/opensearch.yml. Чтобы узнать больше о статических и динамических настройках, см. раздел Настройка OpenSearch.
Общие настройки
Плагин безопасности поддерживает следующие общие настройки:
plugins.security.nodes_dn (Статическая): Указывает список отличительных имен (DN), обозначающих другие узлы в кластере. Эта настройка поддерживает подстановочные знаки и регулярные выражения. Список DN также считывается из индекса безопасности, помимо конфигурации YAML, когда
plugins.security.nodes_dn_dynamic_config_enabledустановлено в true. Если эта настройка не настроена правильно, кластер не сможет сформироваться, так как узлы не смогут доверять друг другу, что приведет к следующей ошибке: “Аутентификация транспортного клиента больше не поддерживается”.plugins.security.nodes_dn_dynamic_config_enabled (Статическая): Актуально для сценариев использования кросс-кластера, где необходимо управлять разрешенными узлами DN без необходимости перезапускать узлы каждый раз, когда настраивается новый удаленный кросс-кластер. Установка
nodes_dn_dynamic_config_enabledв true включает доступные для супер-администратора API для отличительных имен, которые предоставляют средства для динамического обновления или получения узлов DN. Эта настройка имеет эффект только еслиplugins.security.cert.intercluster_request_evaluator_classне установлено. По умолчанию — false.plugins.security.authcz.admin_dn (Статическая): Определяет DN сертификатов, к которым должны быть назначены административные привилегии. Обязательно.
plugins.security.roles_mapping_resolution (Статическая): Определяет, как бэкенд-ролям сопоставляются роли безопасности. Поддерживаются следующие значения:
- MAPPING_ONLY (По умолчанию): Сопоставления должны быть явно настроены в
roles_mapping.yml. - BACKENDROLES_ONLY: Бэкенд-роли сопоставляются с ролями безопасности напрямую. Настройки в
roles_mapping.ymlне имеют эффекта. - BOTH: Бэкенд-роли сопоставляются с ролями безопасности как напрямую, так и через
roles_mapping.yml.
- MAPPING_ONLY (По умолчанию): Сопоставления должны быть явно настроены в
plugins.security.dls.mode (Статическая): Устанавливает режим оценки безопасности на уровне документа (DLS). По умолчанию — адаптивный. См. раздел Как установить режим оценки DLS.
plugins.security.compliance.salt (Статическая): Соль, используемая при генерации хеш-значения для маскирования полей. Должна содержать не менее 32 символов. Разрешены только ASCII-символы. Необязательно.
plugins.security.compliance.immutable_indices (Статическая): Документы в индексах, помеченных как неизменяемые, следуют парадигме “запись один раз, чтение много раз”. Документы, созданные в этих индексах, не могут быть изменены и, следовательно, являются неизменяемыми.
config.dynamic.http.anonymous_auth_enabled (Статическая): Включает анонимную аутентификацию. Это приведет к тому, что все HTTP-аутентификаторы не будут вызывать запросы на аутентификацию. По умолчанию — false.
http.detailed_errors.enabled (Статическая): Включает подробное сообщение об ошибке для REST-вызовов, выполненных против кластера OpenSearch. Если установлено в true, предоставляет
root_causeвместе с кодом ошибки. По умолчанию — true.
Настройки API управления REST
Плагин безопасности поддерживает следующие настройки API управления REST:
plugins.security.restapi.roles_enabled (Статическая): Включает доступ к API управления REST на основе ролей для указанных ролей. Роли разделяются запятой. По умолчанию — пустой список (ни одна роль не имеет доступа к API управления REST). См. раздел Контроль доступа для API.
plugins.security.restapi.endpoints_disabled.
. (Статическая): Отключает конкретные конечные точки и их HTTP-методы для ролей. Значения для этой настройки составляют массив HTTP-методов. Например:plugins.security.restapi.endpoints_disabled.all_access.ACTIONGROUPS: ["PUT","POST","DELETE"]. По умолчанию все конечные точки и методы разрешены. Существующие конечные точки включают ACTIONGROUPS, CACHE, CONFIG, ROLES, ROLESMAPPING, INTERNALUSERS, SYSTEMINFO, PERMISSIONSINFO и LICENSE. См. раздел Контроль доступа для API.plugins.security.restapi.password_validation_regex (Статическая): Указывает регулярное выражение для задания критериев для пароля при входе. Для получения дополнительной информации см. раздел Настройки пароля.
plugins.security.restapi.password_validation_error_message (Статическая): Указывает сообщение об ошибке, которое отображается, когда пароль не проходит проверку. Эта настройка используется вместе с
plugins.security.restapi.password_validation_regex.plugins.security.restapi.password_min_length (Статическая): Устанавливает минимальное количество символов для длины пароля при использовании оценщика силы пароля на основе баллов. По умолчанию — 8. Это также является минимальным значением. Для получения дополнительной информации см. раздел Настройки пароля.
plugins.security.restapi.password_score_based_validation_strength (Статическая): Устанавливает порог для определения, является ли пароль сильным или слабым. Допустимые значения: fair, good, strong и very_strong. Эта настройка используется вместе с
plugins.security.restapi.password_min_length.plugins.security.unsupported.restapi.allow_securityconfig_modification (Статическая): Включает использование методов PUT и PATCH для API конфигурации.
Расширенные настройки
Плагин безопасности поддерживает следующие расширенные настройки:
plugins.security.authcz.impersonation_dn (Статическая): Включает подмену на уровне транспортного слоя. Это позволяет DN выдавать себя за других пользователей. См. раздел Подмена пользователей.
plugins.security.authcz.rest_impersonation_user (Статическая): Включает подмену на уровне REST. Это позволяет пользователям выдавать себя за других пользователей. См. раздел Подмена пользователей.
plugins.security.allow_default_init_securityindex (Статическая): При установке в true OpenSearch Security автоматически инициализирует индекс конфигурации с файлами из директории
/config, если индекс не существует.Это будет использовать известные стандартные пароли. Используйте только в частной сети/окружении.
plugins.security.allow_unsafe_democertificates (Статическая): При установке в true OpenSearch запускается с демонстрационными сертификатами. Эти сертификаты выданы только для демонстрационных целей.
Эти сертификаты хорошо известны и, следовательно, небезопасны для использования в производственной среде. Используйте только в частной сети/окружении.
plugins.security.system_indices.permission.enabled (Статическая): Включает функцию разрешений для системных индексов. При установке в true функция включена, и пользователи с разрешением на изменение ролей могут создавать роли, которые включают разрешения, предоставляющие доступ к системным индексам. При установке в false разрешение отключено, и только администраторы с административным сертификатом могут вносить изменения в системные индексы. По умолчанию разрешение установлено в false в новом кластере.
Настройки уровня эксперта
Настройки уровня эксперта должны настраиваться и развертываться только администратором, который полностью понимает данную функцию. Неправильное понимание функции может привести к рискам безопасности, неправильной работе плагина безопасности или потере данных.
Плагин безопасности поддерживает следующие настройки уровня эксперта:
plugins.security.config_index_name (Статическая): Имя индекса, в котором .opendistro_security хранит свою конфигурацию.
plugins.security.cert.oid (Статическая): Определяет идентификатор объекта (OID) сертификатов узлов сервера.
plugins.security.cert.intercluster_request_evaluator_class (Статическая): Указывает реализацию
org.opensearch.security.transport.InterClusterRequestEvaluator, которая используется для оценки межкластерных запросов. Экземплярыorg.opensearch.security.transport.InterClusterRequestEvaluatorдолжны реализовывать конструктор с одним аргументом, принимающим объектorg.opensearch.common.settings.Settings.plugins.security.enable_snapshot_restore_privilege (Статическая): При установке в false эта настройка отключает восстановление снимков для обычных пользователей. В этом случае принимаются только запросы на восстановление снимков, подписанные административным TLS-сертификатом. При установке в true (по умолчанию) обычные пользователи могут восстанавливать снимки, если у них есть привилегии
cluster:admin/snapshot/restore,indices:admin/createиindices:data/write/index.Снимок можно восстановить только в том случае, если он не содержит глобального состояния и не восстанавливает индекс .opendistro_security.
plugins.security.check_snapshot_restore_write_privileges (Статическая): При установке в false дополнительные проверки индекса пропускаются. При установке по умолчанию в true попытки восстановить снимки оцениваются на наличие привилегий
indices:admin/createиindices:data/write/index.plugins.security.cache.ttl_minutes (Статическая): Определяет, как долго кэш аутентификации будет действителен. Кэш аутентификации помогает ускорить аутентификацию, временно храня объекты пользователей, возвращаемые из бэкенда, чтобы плагин безопасности не требовал повторных запросов к ним. Установите значение в минутах. По умолчанию — 60. Отключите кэширование, установив значение в 0.
plugins.security.disabled (Статическая): Отключает OpenSearch Security.
Отключение этого плагина может подвергнуть вашу конфигурацию (включая пароли) публичному доступу.
plugins.security.protected_indices.enabled (Статическая): Если установлено в true, включает защищенные индексы. Защищенные индексы более безопасны, чем обычные индексы. Эти индексы требуют роли для доступа, как и любой другой традиционный индекс, и требуют дополнительной роли для видимости. Эта настройка используется вместе с настройками
plugins.security.protected_indices.rolesиplugins.security.protected_indices.indices.plugins.security.protected_indices.roles (Статическая): Указывает список ролей, к которым пользователь должен быть сопоставлен для доступа к защищенным индексам.
plugins.security.protected_indices.indices (Статическая): Указывает список индексов, которые следует пометить как защищенные. Эти индексы будут видны только пользователям, сопоставленным с ролями, указанными в
plugins.security.protected_indices.roles. После выполнения этого требования пользователю все равно потребуется быть сопоставленным с традиционной ролью, используемой для предоставления разрешения на доступ к индексу.plugins.security.system_indices.enabled (Статическая): Если установлено в true, включает системные индексы. Системные индексы аналогичны индексу безопасности, за исключением того, что их содержимое не зашифровано. Индексы, настроенные как системные индексы, могут быть доступны либо супер-администратором, либо пользователем с ролью, включающей разрешение на системный индекс. Для получения дополнительной информации о системных индексах см. раздел Системные индексы.
plugins.security.system_indices.indices (Статическая): Список индексов, которые будут использоваться как системные индексы. Эта настройка контролируется настройкой
plugins.security.system_indices.enabled.plugins.security.allow_default_init_securityindex (Статическая): При установке в true устанавливает плагин безопасности в его стандартные настройки безопасности, если попытка создать индекс безопасности завершается неудачей при запуске OpenSearch. Стандартные настройки безопасности хранятся в YAML-файлах, находящихся в директории
opensearch-project/security/config. По умолчанию — false.plugins.security.cert.intercluster_request_evaluator_class (Статическая): Класс, который будет использоваться для оценки межкластерной связи.
plugins.security.enable_snapshot_restore_privilege (Статическая): Включает предоставление привилегии восстановления снимков. Необязательно. По умолчанию — true.
plugins.security.check_snapshot_restore_write_privileges (Статическая): Обеспечивает оценку привилегий записи при создании снимков. По умолчанию — true.
Если вы измените любое из следующих свойств хеширования паролей, вам необходимо повторно хешировать все внутренние пароли для обеспечения совместимости и безопасности.
plugins.security.password.hashing.algorithm (Статическая): Указывает алгоритм хеширования паролей, который следует использовать. Поддерживаются следующие значения:
- BCrypt (По умолчанию)
- PBKDF2
- Argon2
plugins.security.password.hashing.bcrypt.rounds (Статическая): Указывает количество раундов, используемых для хеширования паролей с помощью BCrypt. Допустимые значения находятся в диапазоне от 4 до 31, включая. По умолчанию — 12.
plugins.security.password.hashing.bcrypt.minor (Статическая): Указывает минорную версию алгоритма BCrypt, используемую для хеширования паролей. Поддерживаются следующие значения:
- A
- B
- Y (По умолчанию)
plugins.security.password.hashing.pbkdf2.function (Статическая): Указывает псевдослучайную функцию, применяемую к паролю. Поддерживаются следующие значения:
- SHA1
- SHA224
- SHA256 (По умолчанию)
- SHA384
- SHA512
plugins.security.password.hashing.pbkdf2.iterations (Статическая): Указывает количество раз, которое псевдослучайная функция применяется к паролю. По умолчанию — 600,000.
plugins.security.password.hashing.pbkdf2.length (Статическая): Указывает желаемую длину окончательного производного ключа. По умолчанию — 256.
plugins.security.password.hashing.argon2.iterations (Статическая): Указывает количество проходов по памяти, которые выполняет алгоритм. Увеличение этого значения увеличивает время вычислений на ЦП и улучшает устойчивость к атакам грубой силы. По умолчанию — 3.
plugins.security.password.hashing.argon2.memory (Статическая): Указывает количество памяти (в кибибайтах), используемой во время хеширования. По умолчанию — 65536 (64 МиБ).
plugins.security.password.hashing.argon2.parallelism (Статическая): Указывает количество параллельных потоков, используемых для вычислений. По умолчанию — 1.
plugins.security.password.hashing.argon2.length (Статическая): Указывает длину (в байтах) результирующего хеш-выхода. По умолчанию — 32.
plugins.security.password.hashing.argon2.type (Статическая): Указывает, какой вариант Argon2 использовать. Поддерживаются следующие значения:
- Argon2i
- Argon2d
- Argon2id (по умолчанию)
plugins.security.password.hashing.argon2.version (Статическая): Указывает, какую версию Argon2 использовать. Поддерживаются следующие значения:
- 16
- 19 (по умолчанию)
Настройки журнала аудита
Плагин безопасности поддерживает следующие настройки журнала аудита:
plugins.security.audit.enable_rest (Динамическая): Включает или отключает ведение журнала REST-запросов. По умолчанию установлено в true (включено).
plugins.security.audit.enable_transport (Динамическая): Включает или отключает ведение журнала запросов на уровне транспорта. По умолчанию установлено в false (выключено).
plugins.security.audit.resolve_bulk_requests (Динамическая): Включает или отключает ведение журнала пакетных запросов. При включении все подзапросы в пакетных запросах также записываются в журнал. По умолчанию установлено в false (выключено).
plugins.security.audit.config.disabled_categories (Динамическая): Отключает указанные категории событий.
plugins.security.audit.ignore_requests (Динамическая): Исключает указанные запросы из ведения журнала. Поддерживает подстановочные знаки и регулярные выражения, содержащие действия или пути REST-запросов.
plugins.security.audit.threadpool.size (Статическая): Определяет количество потоков в пуле потоков, используемом для ведения журнала событий. По умолчанию установлено в 10. Установка этого значения в 0 отключает пул потоков, что означает, что плагин ведет журнал событий синхронно.
plugins.security.audit.threadpool.max_queue_len (Статическая): Устанавливает максимальную длину очереди на поток. По умолчанию установлено в 100000.
plugins.security.audit.ignore_users (Динамическая): Массив пользователей. Запросы аудита от пользователей в списке не будут записываться в журнал.
plugins.security.audit.type (Статическая): Назначение событий журнала аудита. Допустимые значения: internal_opensearch, external_opensearch, debug и webhook.
plugins.security.audit.config.http_endpoints (Статическая): Список конечных точек для localhost.
plugins.security.audit.config.index (Статическая): Индекс журнала аудита. По умолчанию установлен auditlog6. Индекс может быть статическим или индексом, который включает дату, чтобы он вращался ежедневно, например, “‘auditlog6-‘YYYY.MM.dd”. В любом случае убедитесь, что индекс защищен должным образом.
plugins.security.audit.config.type (Статическая): Укажите тип журнала аудита как auditlog.
plugins.security.audit.config.username (Статическая): Имя пользователя для конфигурации журнала аудита.
plugins.security.audit.config.password (Статическая): Пароль для конфигурации журнала аудита.
plugins.security.audit.config.enable_ssl (Статическая): Включает или отключает SSL для ведения журнала аудита.
plugins.security.audit.config.verify_hostnames (Статическая): Включает или отключает проверку имени хоста для SSL/TLS сертификатов. По умолчанию установлено в true (включено).
plugins.security.audit.config.enable_ssl_client_auth (Статическая): Включает или отключает аутентификацию клиента SSL/TLS. По умолчанию установлено в false (выключено).
plugins.security.audit.config.cert_alias (Статическая): Псевдоним для сертификата, используемого для доступа к журналу аудита.
plugins.security.audit.config.pemkey_filepath (Статическая): Относительный путь к файлу ключа Privacy Enhanced Mail (PEM), используемого для ведения журнала аудита.
plugins.security.audit.config.pemkey_content (Статическая): Содержимое PEM-ключа, закодированное в base64, используемого для ведения журнала аудита. Это альтернатива …config.pemkey_filepath.
plugins.security.audit.config.pemkey_password (Статическая): Пароль для частного ключа в формате PEM, используемого клиентом.
plugins.security.audit.config.pemcert_filepath (Статическая): Относительный путь к файлу PEM-сертификата, используемого для ведения журнала аудита.
plugins.security.audit.config.pemcert_content (Статическая): Содержимое PEM-сертификата, закодированное в base64, используемого для ведения журнала аудита. Это альтернатива указанию пути к файлу с помощью …config.pemcert_filepath.
plugins.security.audit.config.pemtrustedcas_filepath (Статическая): Относительный путь к файлу доверенного корневого центра сертификации.
plugins.security.audit.config.pemtrustedcas_content (Статическая): Содержимое корневого центра сертификации, закодированное в base64. Это альтернатива …config.pemtrustedcas_filepath.
plugins.security.audit.config.webhook.url (Статическая): URL вебхука.
plugins.security.audit.config.webhook.format (Статическая): Формат, используемый для вебхука. Допустимые значения: URL_PARAMETER_GET, URL_PARAMETER_POST, TEXT, JSON и SLACK.
plugins.security.audit.config.webhook.ssl.verify (Статическая): Включает или отключает проверку любых SSL/TLS сертификатов, отправленных с любым запросом вебхука. По умолчанию установлено в true (включено).
plugins.security.audit.config.webhook.ssl.pemtrustedcas_filepath (Статическая): Относительный путь к файлу доверенного центра сертификации, против которого проверяются запросы вебхука.
plugins.security.audit.config.webhook.ssl.pemtrustedcas_content (Статическая): Содержимое центра сертификации, используемого для проверки запросов вебхука, закодированное в base64. Это альтернатива …config.pemtrustedcas_filepath.
plugins.security.audit.config.log4j.logger_name (Статическая): Пользовательское имя для логгера Log4j.
plugins.security.audit.config.log4j.level (Статическая): Устанавливает уровень журнала по умолчанию для логгера Log4j. Допустимые значения: OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE и ALL. По умолчанию установлено в INFO.
opendistro_security.audit.config.disabled_rest_categories (Динамическая): Список категорий REST, которые будут игнорироваться логгером. Допустимые значения: AUTHENTICATED и GRANTED_PRIVILEGES.
opendistro_security.audit.config.disabled_transport_categories (Динамическая): Список категорий на транспортном уровне, которые будут игнорироваться логгером. Допустимые значения: AUTHENTICATED и GRANTED_PRIVILEGES.
Настройки проверки имени хоста и DNS
Плагин безопасности поддерживает следующие настройки проверки имени хоста и DNS:
plugins.security.ssl.transport.enforce_hostname_verification (Статическая): Указывает, следует ли проверять имена хостов на транспортном уровне. Необязательно. По умолчанию установлено в true.
plugins.security.ssl.transport.resolve_hostname (Статическая): Указывает, следует ли разрешать имена хостов через DNS на транспортном уровне. Необязательно. По умолчанию установлено в true. Работает только если включена проверка имени хоста.
Для получения дополнительной информации см. раздел Проверка имени хоста и разрешение DNS.
Настройки аутентификации клиента
Плагин безопасности поддерживает следующую настройку аутентификации клиента:
- plugins.security.ssl.http.clientauth_mode (Статическая): Режим аутентификации клиента TLS, который следует использовать. Допустимые значения: OPTIONAL (по умолчанию), REQUIRE и NONE. Необязательно.
Для получения дополнительной информации см. раздел Аутентификация клиента.
Настройки включенных шифров и протоколов
Плагин безопасности поддерживает следующие настройки включенных шифров и протоколов. Каждая настройка должна быть выражена в массиве:
plugins.security.ssl.http.enabled_ciphers (Статическая): Включенные шифры TLS для REST-уровня. Поддерживается только формат Java.
plugins.security.ssl.http.enabled_protocols (Статическая): Включенные протоколы TLS для REST-уровня. Поддерживается только формат Java.
plugins.security.ssl.transport.enabled_ciphers (Статическая): Включенные шифры TLS для транспортного уровня. Поддерживается только формат Java.
plugins.security.ssl.transport.enabled_protocols (Статическая): Включенные протоколы TLS для транспортного уровня. Поддерживается только формат Java.
Для получения дополнительной информации см. раздел Включенные шифры и протоколы.
Файлы хранилища ключей и доверенных сертификатов — настройки TLS на транспортном уровне
Плагин безопасности поддерживает следующие настройки хранилища ключей и доверенных сертификатов для транспортного уровня TLS:
plugins.security.ssl.transport.keystore_type (Статическая): Тип файла хранилища ключей. Необязательно. Допустимые значения: JKS или PKCS12/PFX. По умолчанию установлено в JKS.
plugins.security.ssl.transport.keystore_filepath (Статическая): Путь к файлу хранилища ключей, который должен находиться в каталоге конфигурации и указываться с использованием относительного пути. Обязательно.
plugins.security.ssl.transport.keystore_alias (Статическая): Имя псевдонима хранилища ключей. Необязательно. По умолчанию используется первый псевдоним.
plugins.security.ssl.transport.keystore_password (Статическая): Пароль для хранилища ключей. По умолчанию установлено в changeit.
plugins.security.ssl.transport.truststore_type (Статическая): Тип файла доверенного хранилища. Необязательно. Допустимые значения: JKS или PKCS12/PFX. По умолчанию установлено в JKS.
plugins.security.ssl.transport.truststore_filepath (Статическая): Путь к файлу доверенного хранилища, который должен находиться в каталоге конфигурации и указываться с использованием относительного пути. Обязательно.
plugins.security.ssl.transport.truststore_alias (Статическая): Имя псевдонима доверенного хранилища. Необязательно. По умолчанию используются все сертификаты.
plugins.security.ssl.transport.truststore_password (Статическая): Пароль для доверенного хранилища. По умолчанию установлено в changeit.
Для получения дополнительной информации о файлах хранилища ключей и доверенных сертификатов см. раздел TLS на транспортном уровне.
Файлы хранилища ключей и доверенных сертификатов — настройки TLS на уровне REST
Плагин безопасности поддерживает следующие настройки хранилища ключей и доверенных сертификатов для уровня REST TLS:
plugins.security.ssl.http.enabled (Статическая): Указывает, следует ли включить TLS на уровне REST. Если включено, разрешен только HTTPS. Необязательно. По умолчанию установлено в false.
plugins.security.ssl.http.keystore_type (Статическая): Тип файла хранилища ключей. Необязательно. Допустимые значения: JKS или PKCS12/PFX. По умолчанию установлено в JKS.
plugins.security.ssl.http.keystore_filepath (Статическая): Путь к файлу хранилища ключей, который должен находиться в каталоге конфигурации и указываться с использованием относительного пути. Обязательно.
plugins.security.ssl.http.keystore_alias (Статическая): Имя псевдонима хранилища ключей. Необязательно. По умолчанию используется первый псевдоним.
plugins.security.ssl.http.keystore_password (Статическая): Пароль для хранилища ключей. По умолчанию установлено в changeit.
plugins.security.ssl.http.truststore_type (Статическая): Тип файла доверенного хранилища. Необязательно. Допустимые значения: JKS или PKCS12/PFX. По умолчанию установлено в JKS.
plugins.security.ssl.http.truststore_filepath (Статическая): Путь к файлу доверенного хранилища, который должен находиться в каталоге конфигурации и указываться с использованием относительного пути. Обязательно.
plugins.security.ssl.http.truststore_alias (Статическая): Имя псевдонима доверенного хранилища. Необязательно. По умолчанию используются все сертификаты.
plugins.security.ssl.http.truststore_password (Статическая): Пароль для доверенного хранилища. По умолчанию установлено в changeit.
Для получения дополнительной информации см. раздел TLS на уровне REST.
X.509 PEM-сертификаты и ключи PKCS #8 — настройки TLS на транспортном уровне
Плагин безопасности поддерживает следующие настройки TLS на транспортном уровне, связанные с X.509 PEM-сертификатами и ключами PKCS #8:
plugins.security.ssl.transport.pemkey_filepath (Статическая): Путь к файлу ключа сертификата (PKCS #8), который должен находиться в каталоге конфигурации и указываться с использованием относительного пути. Обязательно.
plugins.security.ssl.transport.pemkey_password (Статическая): Пароль для ключа. Укажите эту настройку, если у ключа есть пароль. Необязательно.
plugins.security.ssl.transport.pemcert_filepath (Статическая): Путь к цепочке сертификатов узла X.509 (формат PEM), который должен находиться в каталоге конфигурации и указываться с использованием относительного пути. Обязательно.
plugins.security.ssl.transport.pemtrustedcas_filepath (Статическая): Путь к корневым центрам сертификации (формат PEM), который должен находиться в каталоге конфигурации и указываться с использованием относительного пути. Обязательно.
Для получения дополнительной информации см. раздел TLS на транспортном уровне.
X.509 PEM-сертификаты и ключи PKCS #8 — настройки TLS на уровне REST
Плагин безопасности поддерживает следующие настройки TLS на уровне REST, связанные с X.509 PEM-сертификатами и ключами PKCS #8:
plugins.security.ssl.http.enabled (Статическая): Указывает, следует ли включить TLS на уровне REST. Если включено, разрешен только HTTPS. Необязательно. По умолчанию установлено в false.
plugins.security.ssl.http.pemkey_filepath (Статическая): Путь к файлу ключа сертификата (PKCS #8), который должен находиться в каталоге конфигурации и указываться с использованием относительного пути. Обязательно.
plugins.security.ssl.http.pemkey_password (Статическая): Пароль для ключа. Укажите эту настройку, если у ключа есть пароль. Необязательно.
plugins.security.ssl.http.pemcert_filepath (Статическая): Путь к цепочке сертификатов узла X.509 (формат PEM), который должен находиться в каталоге конфигурации и указываться с использованием относительного пути. Обязательно.
plugins.security.ssl.http.pemtrustedcas_filepath (Статическая): Путь к корневым центрам сертификации (формат PEM), который должен находиться в каталоге конфигурации и указываться с использованием относительного пути. Обязательно.
Для получения дополнительной информации см. раздел TLS на уровне REST.
Настройки безопасности на транспортном уровне
Плагин безопасности поддерживает следующие настройки безопасности на транспортном уровне:
plugins.security.ssl.transport.enabled (Статическая): Указывает, следует ли включить TLS на уровне REST.
plugins.security.ssl.transport.client.pemkey_password (Статическая): Пароль для частного ключа в формате PEM, используемого клиентом на транспортном уровне.
plugins.security.ssl.transport.keystore_keypassword (Статическая): Пароль для ключа внутри хранилища ключей.
plugins.security.ssl.transport.server.keystore_keypassword (Статическая): Пароль для ключа внутри хранилища ключей сервера.
plugins.security.ssl.transport.server.keystore_alias (Статическая): Имя псевдонима для хранилища ключей сервера.
plugins.security.ssl.transport.client.keystore_alias (Статическая): Имя псевдонима для хранилища ключей клиента.
plugins.security.ssl.transport.server.truststore_alias (Статическая): Имя псевдонима для доверенного хранилища сервера.
plugins.security.ssl.transport.client.truststore_alias (Статическая): Имя псевдонима для доверенного хранилища клиента.
plugins.security.ssl.client.external_context_id (Статическая): Предоставляет клиенту на транспортном уровне идентификатор для использования внешнего SSL-контекста.
plugins.security.ssl.transport.principal_extractor_class (Статическая): Указывает класс, реализующий извлечение, чтобы использовать пользовательскую часть сертификата в качестве основного.
plugins.security.ssl.http.crl.file_path (Статическая): Путь к файлу списка отозванных сертификатов (CRL).
plugins.security.ssl.http.crl.validate (Статическая): Включает проверку списка отозванных сертификатов (CRL). По умолчанию установлено в false (выключено).
plugins.security.ssl.http.crl.prefer_crlfile_over_ocsp (Статическая): Указывает, следует ли предпочитать запись сертификата CRL перед записью протокола статуса сертификата в режиме онлайн (OCSP), если сертификат содержит обе записи. Необязательно. По умолчанию установлено в false.
plugins.security.ssl.http.crl.check_only_end_entities (Статическая): Если установлено в true, проверяются только конечные сертификаты. По умолчанию установлено в true.
plugins.security.ssl.http.crl.disable_ocsp (Статическая): Отключает OCSP. По умолчанию установлено в false (OCSP включен).
plugins.security.ssl.http.crl.disable_crldp (Статическая): Отключает конечные точки CRL в сертификатах. По умолчанию установлено в false (конечные точки CRL включены).
plugins.security.ssl.allow_client_initiated_renegotiation (Статическая): Включает или отключает повторнуюNegotiation, инициированную клиентом. По умолчанию установлено в false (повторнаяNegotiation, инициированная клиентом, не разрешена).
Примеры настроек плагина безопасности
# Common configuration settings
plugins.security.nodes_dn:
- "CN=*.example.com, OU=SSL, O=Test, L=Test, C=DE"
- "CN=node.other.com, OU=SSL, O=Test, L=Test, C=DE"
- "CN=node.example.com, OU=SSL\\, Inc., L=Test, C=DE" # escape additional comma with `\\`
plugins.security.authcz.admin_dn:
- CN=kirk,OU=client,O=client,L=test, C=de
plugins.security.roles_mapping_resolution: MAPPING_ONLY
plugins.security.ssl.transport.pemcert_filepath: esnode.pem
plugins.security.ssl.transport.pemkey_filepath: esnode-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: root-ca.pem
plugins.security.ssl.transport.enforce_hostname_verification: false
plugins.security.ssl.http.enabled: true
plugins.security.ssl.http.pemcert_filepath: esnode.pem
plugins.security.ssl.http.pemkey_filepath: esnode-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem
plugins.security.allow_unsafe_democertificates: true
plugins.security.allow_default_init_securityindex: true
plugins.security.nodes_dn_dynamic_config_enabled: false
plugins.security.cert.intercluster_request_evaluator_class: # need example value for this.
plugins.security.audit.type: internal_opensearch
plugins.security.enable_snapshot_restore_privilege: true
plugins.security.check_snapshot_restore_write_privileges: true
plugins.security.cache.ttl_minutes: 60
plugins.security.restapi.roles_enabled: ["all_access", "security_rest_api_access"]
plugins.security.system_indices.enabled: true
plugins.security.system_indices.indices: [".opendistro-alerting-config", ".opendistro-alerting-alert*", ".opendistro-anomaly-results*", ".opendistro-anomaly-detector*", ".opendistro-anomaly-checkpoints", ".opendistro-anomaly-detection-state", ".opendistro-reports-*", ".opendistro-notifications-*", ".opendistro-notebooks", ".opendistro-asynchronous-search-response*"]
node.max_local_storage_nodes: 3
plugins.security.restapi.password_validation_regex: '(?=.*[A-Z])(?=.*[^a-zA-Z\d])(?=.*[0-9])(?=.*[a-z]).{8,}'
plugins.security.restapi.password_validation_error_message: "Password must be minimum 8 characters long and must contain at least one uppercase letter, one lowercase letter, one digit, and one special character."
plugins.security.allow_default_init_securityindex: true
plugins.security.cache.ttl_minutes: 60
#
# REST Management API configuration settings
plugins.security.restapi.roles_enabled: ["all_access","xyz_role"]
plugins.security.restapi.endpoints_disabled.all_access.ACTIONGROUPS: ["PUT","POST","DELETE"] # Alternative example: plugins.security.restapi.endpoints_disabled.xyz_role.LICENSE: ["DELETE"] #
# Audit log configuration settings
plugins.security.audit.enable_rest: true
plugins.security.audit.enable_transport: false
plugins.security.audit.resolve_bulk_requests: false
plugins.security.audit.config.disabled_categories: ["AUTHENTICATED","GRANTED_PRIVILEGES"]
plugins.security.audit.ignore_requests: ["indices:data/read/*","*_bulk"]
plugins.security.audit.threadpool.size: 10
plugins.security.audit.threadpool.max_queue_len: 100000
plugins.security.audit.ignore_users: ['kibanaserver','some*user','/also.*regex possible/']
plugins.security.audit.type: internal_opensearch
#
# external_opensearch settings
plugins.security.audit.config.http_endpoints: ['localhost:9200','localhost:9201','localhost:9202']
plugins.security.audit.config.index: "'auditlog6-'2023.06.15"
plugins.security.audit.config.type: auditlog
plugins.security.audit.config.username: auditloguser
plugins.security.audit.config.password: auditlogpassword
plugins.security.audit.config.enable_ssl: false
plugins.security.audit.config.verify_hostnames: false
plugins.security.audit.config.enable_ssl_client_auth: false
plugins.security.audit.config.cert_alias: mycert
plugins.security.audit.config.pemkey_filepath: key.pem
plugins.security.audit.config.pemkey_content: <...pem base 64 content>
plugins.security.audit.config.pemkey_password: secret
plugins.security.audit.config.pemcert_filepath: cert.pem
plugins.security.audit.config.pemcert_content: <...pem base 64 content>
plugins.security.audit.config.pemtrustedcas_filepath: ca.pem
plugins.security.audit.config.pemtrustedcas_content: <...pem base 64 content>
#
# Webhook settings
plugins.security.audit.config.webhook.url: "http://mywebhook/endpoint"
plugins.security.audit.config.webhook.format: JSON
plugins.security.audit.config.webhook.ssl.verify: false
plugins.security.audit.config.webhook.ssl.pemtrustedcas_filepath: ca.pem
plugins.security.audit.config.webhook.ssl.pemtrustedcas_content: <...pem base 64 content>
#
# log4j settings
plugins.security.audit.config.log4j.logger_name: auditlogger
plugins.security.audit.config.log4j.level: INFO
#
# Advanced configuration settings
plugins.security.authcz.impersonation_dn:
"CN=spock,OU=client,O=client,L=Test,C=DE":
- worf
"cn=webuser,ou=IT,ou=IT,dc=company,dc=com":
- user2
- user1
plugins.security.authcz.rest_impersonation_user:
"picard":
- worf
"john":
- steve
- martin
plugins.security.allow_default_init_securityindex: false
plugins.security.allow_unsafe_democertificates: false
plugins.security.cache.ttl_minutes: 60
plugins.security.restapi.password_validation_regex: '(?=.*[A-Z])(?=.*[^a-zA-Z\d])(?=.*[0-9])(?=.*[a-z]).{8,}'
plugins.security.restapi.password_validation_error_message: "A password must be at least 8 characters long and contain at least one uppercase letter, one lowercase letter, one digit, and one special character."
plugins.security.restapi.password_min_length: 8
plugins.security.restapi.password_score_based_validation_strength: very_strong
#
# Advanced SSL settings - use only if you understand SSL ins and outs
plugins.security.ssl.transport.client.pemkey_password: superSecurePassword1
plugins.security.ssl.transport.keystore_keypassword: superSecurePassword2
plugins.security.ssl.transport.server.keystore_keypassword: superSecurePassword3
plugins.security.ssl.http.keystore_keypassword: superSecurePassword4
plugins.security.ssl.http.clientauth_mode: REQUIRE
plugins.security.ssl.transport.enabled: true
plugins.security.ssl.transport.server.keystore_alias: my_alias
plugins.security.ssl.transport.client.keystore_alias: my_other_alias
plugins.security.ssl.transport.server.truststore_alias: trustore_alias_1
plugins.security.ssl.transport.client.truststore_alias: trustore_alias_2
plugins.security.ssl.client.external_context_id: my_context_id
plugins.security.ssl.transport.principal_extractor_class: org.opensearch.security.ssl.ExampleExtractor
plugins.security.ssl.http.crl.file_path: ssl/crl/revoked.crl
plugins.security.ssl.http.crl.validate: true
plugins.security.ssl.http.crl.prefer_crlfile_over_ocsp: true
plugins.security.ssl.http.crl.check_only_end_entitites: false
plugins.security.ssl.http.crl.disable_ocsp: true
plugins.security.ssl.http.crl.disable_crldp: true
plugins.security.ssl.allow_client_initiated_renegotiation: true
#
# Expert settings - use only if you understand their use completely: accidental values can potentially cause security risks or failures to OpenSearch Security.
plugins.security.config_index_name: .opendistro_security
plugins.security.cert.oid: '1.2.3.4.5.5'
plugins.security.cert.intercluster_request_evaluator_class: org.opensearch.security.transport.DefaultInterClusterRequestEvaluator
plugins.security.enable_snapshot_restore_privilege: true
plugins.security.check_snapshot_restore_write_privileges: true
plugins.security.cache.ttl_minutes: 60
plugins.security.disabled: false
plugins.security.protected_indices.enabled: true
plugins.security.protected_indices.roles: ['all_access']
plugins.security.protected_indices.indices: []
plugins.security.system_indices.enabled: true
plugins.security.system_indices.indices: ['.opendistro-alerting-config', '.opendistro-ism-*', '.opendistro-reports-*', '.opensearch-notifications-*', '.opensearch-notebooks', '.opensearch-observability', '.opendistro-asynchronous-search-response*', '.replication-metadata-store']
8.2.3.6 - Настройки предохранителей
Родительский предохранитель указывает общее доступное количество памяти для всех дочерних предохранителей. Дочерние предохранители указывают общее доступное количество памяти для себя.
Для получения дополнительной информации о статических и динамических настройках см. раздел Конфигурация OpenSearch.
Настройки родительского предохранителя
OpenSearch поддерживает следующие настройки родительского предохранителя:
indices.breaker.total.use_real_memory (Статическая, логическая): Если установлено в true, родительский предохранитель учитывает фактическое использование памяти. В противном случае родительский предохранитель учитывает количество памяти, зарезервированной дочерними предохранителями. По умолчанию установлено в true.
indices.breaker.total.limit (Динамическая, процент): Указывает начальный лимит памяти для родительского предохранителя. Если indices.breaker.total.use_real_memory установлено в true, по умолчанию составляет 95% кучи JVM. Если indices.breaker.total.use_real_memory установлено в false, по умолчанию составляет 70% кучи JVM.
Настройки предохранителя данных полей
Предохранитель данных полей ограничивает объем памяти кучи, необходимый для загрузки поля в кэш данных полей. OpenSearch поддерживает следующие настройки предохранителя данных полей:
indices.breaker.fielddata.limit (Динамическая, процент): Указывает лимит памяти для предохранителя данных полей. По умолчанию составляет 40% кучи JVM.
indices.breaker.fielddata.overhead (Динамическая, дробное число): Константа, на которую умножаются оценки данных полей для определения окончательной оценки. По умолчанию составляет 1.03.
Настройки предохранителя запросов
Предохранитель запросов ограничивает объем памяти, необходимый для построения структур данных, необходимых для запроса (например, при вычислении агрегатов). OpenSearch поддерживает следующие настройки предохранителя запросов:
indices.breaker.request.limit (Динамическая, процент): Указывает лимит памяти для предохранителя запросов. По умолчанию составляет 60% кучи JVM.
indices.breaker.request.overhead (Динамическая, дробное число): Константа, на которую умножаются оценки запросов для определения окончательной оценки. По умолчанию составляет 1.
Настройки предохранителя текущих запросов
Предохранитель текущих запросов ограничивает использование памяти для всех текущих входящих запросов на транспортном и HTTP-уровне. Использование памяти для запроса основано на длине содержимого запроса и включает память, необходимую для необработанного запроса и структурированного объекта, представляющего запрос. OpenSearch поддерживает следующие настройки предохранителя текущих запросов:
network.breaker.inflight_requests.limit (Динамическая, процент): Указывает лимит памяти для предохранителя текущих запросов. По умолчанию составляет 100% кучи JVM (таким образом, лимит использования памяти для текущего запроса определяется лимитом памяти родительского предохранителя).
network.breaker.inflight_requests.overhead (Динамическая, дробное число): Константа, на которую умножаются оценки текущих запросов для определения окончательной оценки. По умолчанию составляет 2.
Настройки предохранителя компиляции скриптов
Предохранитель компиляции скриптов ограничивает количество компиляций встроенных скриптов в течение временного интервала. OpenSearch поддерживает следующую настройку предохранителя компиляции скриптов:
- script.max_compilations_rate (Динамическая, ставка): Максимальное количество уникальных динамических скриптов, скомпилированных в течение временного интервала для данного контекста. По умолчанию составляет 150 каждые 5 минут (150/5m).
Настройки предохранителя регулярных выражений
Предохранитель регулярных выражений включает или отключает регулярные выражения и ограничивает их сложность. OpenSearch поддерживает следующие настройки предохранителя регулярных выражений:
script.painless.regex.enabled (Статическая, строка): Включает регулярные выражения в скриптах Painless. Допустимые значения:
- limited: Включает регулярные выражения и ограничивает их сложность с помощью настройки script.painless.regex.limit-factor.
- true: Включает регулярные выражения. Отключает предохранитель регулярных выражений и не ограничивает сложность регулярных выражений.
- false: Отключает регулярные выражения. Если скрипт Painless содержит регулярное выражение, возвращает ошибку.
По умолчанию установлено в limited.
script.painless.regex.limit-factor (Статическая, целое число): Применяется только если script.painless.regex.enabled установлено в limited. Ограничивает количество символов, которые может содержать регулярное выражение в скрипте Painless. Лимит символов рассчитывается путем умножения количества символов во входных данных скрипта на script.painless.regex.limit-factor. По умолчанию составляет 6 (таким образом, если входные данные содержат 5 символов, максимальное количество символов в регулярном выражении составляет 5 · 6 = 30).
8.2.3.7 - Настройка кластера
Чтобы узнать больше о статических и динамических настройках, смотрите раздел Настройка OpenSearch.
Настройки маршрутизации и распределения на уровне кластера
OpenSearch поддерживает следующие настройки маршрутизации на уровне кластера и распределения шардов:
cluster.routing.allocation.enable (Динамическая, строка)
Включает или отключает распределение для определенных типов шардов.
Допустимые значения:
- all – Разрешает распределение шардов для всех типов шардов.
- primaries – Разрешает распределение шардов только для первичных шардов.
- new_primaries – Разрешает распределение шардов только для первичных шардов новых индексов.
- none – Распределение шардов не разрешено для любых индексов.
По умолчанию установлено значение all.
cluster.routing.allocation.node_concurrent_incoming_recoveries (Динамическая, целое число)
Настраивает, сколько параллельных входящих восстановлений шардов разрешено на узле. По умолчанию установлено значение 2.
cluster.routing.allocation.node_concurrent_outgoing_recoveries (Динамическая, целое число)
Настраивает, сколько параллельных исходящих восстановлений шардов разрешено на узле. По умолчанию установлено значение 2.
cluster.routing.allocation.node_concurrent_recoveries (Динамическая, строка)
Используется для установки значений cluster.routing.allocation.node_concurrent_incoming_recoveries и cluster.routing.allocation.node_concurrent_outgoing_recoveries на одно и то же значение.
cluster.routing.allocation.node_initial_primaries_recoveries (Динамическая, целое число)
Устанавливает количество восстановлений для нераспределенных первичных шардов после перезапуска узла. По умолчанию установлено значение 4.
cluster.routing.allocation.same_shard.host (Динамическая, логическое)
При установке в true предотвращает распределение нескольких копий шарда на разные узлы на одном хосте. По умолчанию установлено значение false.
cluster.routing.rebalance.enable (Динамическая, строка)
Включает или отключает перераспределение для определенных типов шардов.
Допустимые значения:
- all – Разрешает балансировку шардов для всех типов шардов.
- primaries – Разрешает балансировку шардов только для первичных шардов.
- replicas – Разрешает балансировку шардов только для реплик.
- none – Балансировка шардов не разрешена для любых индексов.
По умолчанию установлено значение all.
cluster.routing.allocation.allow_rebalance (Динамическая, строка)
Указывает, когда разрешено перераспределение шардов.
Допустимые значения:
- always – Всегда разрешать перераспределение.
- indices_primaries_active – Разрешать перераспределение только когда все первичные шары в кластере распределены.
- indices_all_active – Разрешать перераспределение только когда все шары в кластере распределены.
По умолчанию установлено значение indices_all_active.
cluster.routing.allocation.cluster_concurrent_rebalance (Динамическая, целое число)
Позволяет контролировать, сколько параллельных перераспределений шардов разрешено в кластере. По умолчанию установлено значение 2.
cluster.routing.allocation.balance.shard (Динамическая, число с плавающей точкой)
Определяет весовой коэффициент для общего количества шардов, распределенных на узел. По умолчанию установлено значение 0.45.
cluster.routing.allocation.balance.index (Динамическая, число с плавающей точкой)
Определяет весовой коэффициент для количества шардов на индекс, распределенных на узел. По умолчанию установлено значение 0.55.
cluster.routing.allocation.balance.threshold (Динамическая, число с плавающей точкой)
Минимальное значение оптимизации операций, которые должны быть выполнены. По умолчанию установлено значение 1.0.
cluster.routing.allocation.balance.prefer_primary (Динамическая, логическое)
При установке в true OpenSearch пытается равномерно распределить первичные шары между узлами кластера. Включение этой настройки не всегда гарантирует равное количество первичных шардов на каждом узле, особенно в случае сбоя. Изменение этой настройки на false после установки в true не вызывает перераспределение первичных шардов. По умолчанию установлено значение false.
cluster.routing.allocation.rebalance.primary.enable (Динамическая, логическое)
При установке в true OpenSearch пытается перераспределить первичные шары между узлами кластера. При включении кластер пытается поддерживать количество первичных шардов на каждом узле, с максимальным буфером, определенным настройкой cluster.routing.allocation.rebalance.primary.buffer. Изменение этой настройки на false после установки в true не вызывает перераспределение первичных шардов. По умолчанию установлено значение false.
cluster.routing.allocation.rebalance.primary.buffer (Динамическая, число с плавающей точкой)
Определяет максимальный допустимый буфер первичных шардов между узлами, когда включена настройка cluster.routing.allocation.rebalance.primary.enable. По умолчанию установлено значение 0.1.
cluster.routing.allocation.disk.threshold_enabled (Динамическая, логическое)
При установке в false отключает решение о распределении по диску. Это также удалит любые существующие блокировки индекса index.blocks.read_only_allow_delete, когда отключено. По умолчанию установлено значение true.
Настройки водяных знаков дискового пространства
cluster.routing.allocation.disk.watermark.low (Динамическая, строка)
Контролирует низкий водяной знак для использования дискового пространства. При установке в процентном соотношении OpenSearch не будет распределять шары на узлы с указанным процентом использования диска. Это также можно указать в виде дробного значения, например, 0.85. Наконец, это можно установить в байтовом значении, например, 400mb. Эта настройка не влияет на первичные шары новых индексов, но предотвратит распределение их реплик. По умолчанию установлено значение 85%.
cluster.routing.allocation.disk.watermark.high (Динамическая, строка)
Контролирует высокий водяной знак. OpenSearch попытается переместить шары с узла, использование диска на котором превышает установленный процент. Это также можно указать в виде дробного значения, например, 0.85. Наконец, это можно установить в байтовом значении, например, 400mb. Эта настройка влияет на распределение всех шардов. По умолчанию установлено значение 90%.
cluster.routing.allocation.disk.watermark.flood_stage (Динамическая, строка)
Контролирует водяной знак на уровне затопления. Это последний шаг для предотвращения исчерпания дискового пространства на узлах. OpenSearch применяет блокировку индекса только для чтения (index.blocks.read_only_allow_delete) ко всем индексам, на которых есть один или несколько шардов, распределенных на узле, и хотя бы один диск превышает уровень затопления. Блокировка индекса снимается, как только использование диска падает ниже высокого водяного знака. Это также можно указать в виде дробного значения, например, 0.85. Наконец, это можно установить в байтовом значении, например, 400mb. По умолчанию установлено значение 95%.
cluster.info.update.interval (Динамическая, единица времени)
Устанавливает, как часто OpenSearch должен проверять использование диска для каждого узла в кластере. По умолчанию установлено значение 30s.
Настройки распределения шардов по атрибутам
cluster.routing.allocation.include. (Динамическая, перечисление)
Распределяет шары на узел, атрибут которого содержит хотя бы одно из включенных значений, разделенных запятыми.
cluster.routing.allocation.require. (Динамическая, перечисление)
Распределяет шары только на узел, атрибут которого содержит все включенные значения, разделенные запятыми.
cluster.routing.allocation.exclude. (Динамическая, перечисление)
Не распределяет шары на узел, атрибут которого содержит любое из включенных значений, разделенных запятыми. Настройки распределения кластера поддерживают следующие встроенные атрибуты.
Допустимые значения:
- _name – Совпадение узлов по имени узла.
- _host_ip – Совпадение узлов по IP-адресу хоста.
- _publish_ip – Совпадение узлов по публикуемому IP-адресу.
- _ip – Совпадение по _host_ip или _publish_ip.
- _host – Совпадение узлов по имени хоста.
- _id – Совпадение узлов по идентификатору узла.
- _tier – Совпадение узлов по роли уровня данных.
Настройки перемещения шардов
cluster.routing.allocation.shard_movement_strategy (Динамическая, перечисление)
Определяет порядок, в котором шары перемещаются с исходящих узлов на входящие.
Эта настройка поддерживает следующие стратегии:
- PRIMARY_FIRST – Первичные шары перемещаются первыми, перед репликами. Эта приоритизация может помочь предотвратить переход состояния здоровья кластера в красный, если узлы, на которые перемещаются шары, выйдут из строя в процессе.
- REPLICA_FIRST – Репликационные шары перемещаются первыми, перед первичными. Эта приоритизация может помочь предотвратить переход состояния здоровья кластера в красный при выполнении перемещения шардов в кластере OpenSearch с смешанными версиями и включенной репликацией сегментов. В этой ситуации первичные шары, перемещенные на узлы OpenSearch более новой версии, могут попытаться скопировать файлы сегментов на репликационные шары более старой версии OpenSearch, что приведет к сбою шардов. Перемещение репликационных шардов первыми может помочь избежать этого в кластерах с несколькими версиями.
- NO_PREFERENCE – Поведение по умолчанию, при котором порядок перемещения шардов не имеет значения.
cluster.routing.search_replica.strict (Динамическая, логическое)
Контролирует, как маршрутизируются поисковые запросы, когда для индекса существуют репликационные шары, например, когда index.number_of_search_replicas больше 0. Эта настройка применяется только в случае, если для индекса настроены поисковые реплики. При установке в true все поисковые запросы для таких индексов маршрутизируются только на репликационные шары. Если репликационные шары не назначены, запросы завершаются неудачей. При установке в false, если репликационные шары не назначены, запросы возвращаются к любому доступному шару. По умолчанию установлено значение true.
cluster.allocator.gateway.batch_size (Динамическая, целое число)
Ограничивает количество шардов, отправляемых на узлы данных в одной партии для получения метаданных любых нераспределенных шардов. По умолчанию установлено значение 2000.
cluster.allocator.existing_shards_allocator.batch_enabled (Статическая, логическая)
Включает пакетное распределение нераспределенных шардов, которые уже существуют на диске, вместо распределения одного шара за раз. Это снижает нагрузку на память и транспорт, получая метаданные любых нераспределенных шардов в пакетном вызове. По умолчанию установлено значение false.
cluster.routing.allocation.total_shards_per_node (Динамическая, целое число)
Максимальное общее количество первичных и репликационных шардов, которые могут быть распределены на один узел. По умолчанию установлено значение -1 (без ограничений). Помогает равномерно распределять шары по узлам, ограничивая общее количество шардов на узел. Используйте с осторожностью, так как шары могут оставаться нераспределенными, если узлы достигнут своих настроенных лимитов.
cluster.routing.allocation.total_primary_shards_per_node (Динамическая, целое число)
Максимальное количество первичных шардов, которые могут быть распределены на один узел. Эта настройка применима только для кластеров с удаленной поддержкой. По умолчанию установлено значение -1 (без ограничений). Помогает равномерно распределять первичные шары по узлам, ограничивая количество первичных шардов на узел. Используйте с осторожностью, так как первичные шары могут оставаться нераспределенными, если узлы достигнут своих настроенных лимитов.
Настройки шардов, блокировок и задач на уровне кластера
OpenSearch поддерживает следующие настройки шардов, блокировок и задач на уровне кластера:
action.search.shard_count.limit (Целое число)
Ограничивает максимальное количество шардов, которые могут быть задействованы во время поиска. Запросы, превышающие этот лимит, будут отклонены.
cluster.blocks.read_only (Логическое)
Устанавливает весь кластер в режим только для чтения. По умолчанию установлено значение false.
cluster.blocks.read_only_allow_delete (Логическое)
Похоже на cluster.blocks.read_only, но позволяет удалять индексы.
cluster.max_shards_per_node (Целое число)
Ограничивает общее количество первичных и репликационных шардов для кластера. Лимит рассчитывается следующим образом: cluster.max_shards_per_node умножается на количество не замороженных узлов данных. Шары для закрытых индексов не учитываются в этом лимите. По умолчанию установлено значение 1000.
cluster.persistent_tasks.allocation.enable (Строка)
Включает или отключает распределение для постоянных задач.
Допустимые значения:
- all – Разрешает назначение постоянных задач на узлы.
- none – Распределение для постоянных задач не разрешено. Это не влияет на уже работающие постоянные задачи.
По умолчанию установлено значение all.
cluster.persistent_tasks.allocation.recheck_interval (Единица времени)
Менеджер кластера автоматически проверяет, нужно ли назначать постоянные задачи, когда состояние кластера изменяется значительным образом. Существуют и другие факторы, такие как использование памяти, которые повлияют на то, будут ли постоянные задачи назначены на узлы, но не вызывают изменения состояния кластера. Эта настройка определяет, как часто выполняются проверки назначения в ответ на эти факторы. По умолчанию установлено значение 30 секунд, при этом минимальное значение составляет 10 секунд.
Настройки медленных логов на уровне кластера
Для получения дополнительной информации смотрите раздел Медленные логи запросов поиска.
cluster.search.request.slowlog.threshold.warn (Единица времени)
Устанавливает порог WARN для медленных логов на уровне запросов. По умолчанию установлено значение -1.
cluster.search.request.slowlog.threshold.info (Единица времени)
Устанавливает порог INFO для медленных логов на уровне запросов. По умолчанию установлено значение -1.
cluster.search.request.slowlog.threshold.debug (Единица времени)
Устанавливает порог DEBUG для медленных логов на уровне запросов. По умолчанию установлено значение -1.
cluster.search.request.slowlog.threshold.trace (Единица времени)
Устанавливает порог TRACE для медленных логов на уровне запросов. По умолчанию установлено значение -1.
cluster.search.request.slowlog.level (Строка)
Устанавливает минимальный уровень медленного лога для записи: WARN, INFO, DEBUG и TRACE. По умолчанию установлено значение TRACE.
Настройки индекса на уровне кластера
Для получения информации о настройках индекса на уровне индекса смотрите раздел Настройки индекса на уровне кластера.
Настройки координации на уровне кластера
OpenSearch поддерживает следующие настройки координации на уровне кластера. Все настройки в этом списке являются динамическими:
cluster.fault_detection.leader_check.timeout (Единица времени)
Количество времени, в течение которого узел ждет ответа от избранного менеджера кластера во время проверки лидера, прежде чем считать проверку неудачной. Допустимые значения от 1ms до 60s, включая. По умолчанию установлено значение 10s. Изменение этой настройки на значение, отличное от значения по умолчанию, может привести к нестабильности кластера.
cluster.fault_detection.follower_check.timeout (Единица времени)
Количество времени, в течение которого избранный менеджер кластера ждет ответа во время проверки последователя, прежде чем считать проверку неудачной. Допустимые значения от 1ms до 60s, включая. По умолчанию установлено значение 10s. Изменение этой настройки на значение, отличное от значения по умолчанию, может привести к нестабильности кластера.
cluster.fault_detection.follower_check.interval (Единица времени)
Количество времени, в течение которого избранный менеджер кластера ждет между отправкой проверок последователей другим узлам в кластере. Допустимые значения 100ms и выше. По умолчанию установлено значение 1000ms. Изменение этой настройки на значение, отличное от значения по умолчанию, может привести к нестабильности кластера.
cluster.follower_lag.timeout (Единица времени)
Количество времени, в течение которого избранный менеджер кластера ждет получения подтверждений обновлений состояния кластера от отстающих узлов. По умолчанию установлено значение 90s. Если узел не успешно применяет обновление состояния кластера в течение этого времени, он считается неудавшимся и удаляется из кластера.
cluster.publish.timeout (Единица времени)
Количество времени, в течение которого менеджер кластера ждет, пока каждое обновление состояния кластера будет полностью опубликовано на всех узлах, если только discovery.type не установлен на single-node. По умолчанию установлено значение 30s.
Настройки пределов ответов CAT на уровне кластера
OpenSearch поддерживает следующие настройки пределов ответов CAT API на уровне кластера, все из которых являются динамическими:
cat.indices.response.limit.number_of_indices (Целое число)
Устанавливает предел на количество индексов, возвращаемых API CAT Indices. Значение по умолчанию -1 (без ограничений). Если количество индексов в ответе превышает этот предел, API возвращает ошибку 429. Чтобы избежать этого, вы можете указать фильтр по шаблону индекса в вашем запросе (например, _cat/indices/<index-pattern>).
cat.shards.response.limit.number_of_shards (Целое число)
Устанавливает предел на количество шардов, возвращаемых API CAT Shards. Значение по умолчанию -1 (без ограничений). Если количество шардов в ответе превышает этот предел, API возвращает ошибку 429. Чтобы избежать этого, вы можете указать фильтр по шаблону индекса в вашем запросе (например, _cat/shards/<index-pattern>).
cat.segments.response.limit.number_of_indices (Целое число)
Устанавливает предел на количество индексов, возвращаемых API CAT Segments. Значение по умолчанию -1 (без ограничений). Если количество индексов в ответе превышает этот предел, API возвращает ошибку 429. Чтобы избежать этого, вы можете указать фильтр по шаблону индекса в вашем запросе (например, _cat/segments/<index-pattern>).
8.2.3.8 - Настройка индекса
Чтобы узнать больше о статических и динамических настройках, смотрите Конфигурирование OpenSearch.
Настройки индекса уровня кластера
Существует два типа настроек кластера:
- Статические настройки индекса уровня кластера — это настройки, которые нельзя обновить, пока кластер работает. Чтобы обновить статическую настройку, необходимо остановить кластер, обновить настройку, а затем перезапустить кластер.
- Динамические настройки индекса уровня кластера — это настройки, которые можно обновлять в любое время.
Статические настройки индекса уровня кластера
OpenSearch поддерживает следующие статические настройки индекса уровня кластера:
indices.cache.cleanup_interval(Единица времени): Запланирует периодическую фоновую задачу, которая очищает истекшие записи из кэша с указанным интервалом. По умолчанию 1m (1 минута). Для получения дополнительной информации смотрите Кэш запросов индекса.indices.requests.cache.size(Строка): Размер кэша в процентах от размера кучи (например, чтобы использовать 1% кучи, укажите 1%). По умолчанию 1%. Для получения дополнительной информации смотрите Кэш запросов индекса.
Динамические настройки индекса уровня кластера
OpenSearch поддерживает следующие динамические настройки индекса уровня кластера:
action.auto_create_index(Булевый): Автоматически создает индекс, если индекс еще не существует. Также применяет любые конфигурации шаблонов индексов. По умолчанию true.indices.recovery.max_concurrent_file_chunks(Целое число): Количество частей файлов, отправляемых параллельно для каждой операции восстановления. По умолчанию 2.indices.recovery.max_concurrent_operations(Целое число): Количество операций, отправляемых параллельно для каждого восстановления. По умолчанию 1.indices.recovery.max_concurrent_remote_store_streams(Целое число): Количество потоков к удаленному репозиторию, которые могут быть открыты параллельно при восстановлении индекса из удаленного хранилища. По умолчанию 20.indices.replication.max_bytes_per_sec(Строка): Ограничивает общий входящий и исходящий трафик репликации для каждого узла. Если значение не указано в конфигурации, используется настройкаindices.recovery.max_bytes_per_sec, по умолчанию равная 40 МБ. Если вы установите значение трафика репликации меньше или равным 0 МБ, ограничение скорости будет отключено, что приведет к передаче данных репликации с максимальной возможной скоростью.indices.fielddata.cache.size(Строка): Максимальный размер кэша данных полей. Может быть указан как абсолютное значение (например, 8 ГБ) или процент от кучи узла (например, 50%). Это значение статическое, поэтому его необходимо указать в файлеopensearch.yml. Если вы не укажете эту настройку, максимальный размер будет неограниченным. Это значение должно быть меньше, чемindices.breaker.fielddata.limit. Для получения дополнительной информации смотрите Систему защиты от переполнения кэша данных полей.indices.query.bool.max_clause_count(Целое число): Определяет максимальное произведение полей и терминов, которые могут быть запрошены одновременно. До версии OpenSearch 2.16 для применения этой статической настройки требовалась перезагрузка кластера. Теперь она динамическая, существующие пулы потоков поиска могут использовать старое статическое значение, что может привести к исключениям TooManyClauses. Новые пулы потоков используют обновленное значение. По умолчанию 1024.cluster.remote_store.index.path.type(Строка): Стратегия пути для данных, хранящихся в удаленном хранилище. Эта настройка эффективна только для кластеров с включенным удаленным хранилищем. Эта настройка поддерживает следующие значения:fixed: Хранит данные в структуре пути<repository_base_path>/<index_uuid>/<shard_id>/.hashed_prefix: Хранит данные в структуре путиhash(<shard-data-identifier>)/<repository_base_path>/<index_uuid>/<shard_id>/.hashed_infix: Хранит данные в структуре пути<repository_base_path>/hash(<shard-data-identifier>)/<index_uuid>/<shard_id>/.shard-data-identifierхарактеризуетсяindex_uuid,shard_id, типом данных (translog, segments) и типом данных (data, metadata, lock_files). По умолчаниюfixed.
cluster.remote_store.index.path.hash_algorithm(Строка): Хеш-функция, используемая для получения хеш-значения, когдаcluster.remote_store.index.path.typeустановлено наhashed_prefixилиhashed_infix. Эта настройка эффективна только для кластеров с включенным удаленным хранилищем. Эта настройка поддерживает следующие значения:fnv_1a_base64: Использует хеш-функцию FNV1a и генерирует безопасное для URL 20-битное хеш-значение в формате base64.fnv_1a_composite_1: Использует хеш-функцию FNV1a и генерирует пользовательское закодированное хеш-значение, которое хорошо масштабируется с большинством опций удаленного хранилища. Функция FNV1a генерирует 64-битное значение. Пользовательское кодирование использует 6 старших бит для создания безопасного для URL символа base64 и следующие 14 бит для создания двоичной строки. По умолчаниюfnv_1a_composite_1.
cluster.remote_store.translog.transfer_timeout(Единица времени): Управляет значением таймаута при загрузке файлов translog и контрольных точек во время синхронизации с удаленным хранилищем. Эта настройка применяется только для кластеров с включенным удаленным хранилищем. По умолчанию 30 секунд.cluster.remote_store.index.segment_metadata.retention.max_count(Целое число): Управляет минимальным количеством файлов метаданных, которые необходимо сохранить в репозитории сегментов на удаленном хранилище. Значение ниже 1 отключает удаление устаревших файлов метаданных сегментов. По умолчанию 10.cluster.remote_store.segment.transfer_timeout(Единица времени): Управляет максимальным временем ожидания обновления всех новых сегментов после обновления в удаленное хранилище. Если загрузка не завершится в течение указанного времени, будет выброшено исключение SegmentUploadFailedException. По умолчанию 30 минут. Минимальное ограничение составляет 10 минут.cluster.remote_store.translog.path.prefix(Строка): Управляет фиксированным префиксом пути для данных translog на кластере с включенным удаленным хранилищем. Эта настройка применяется только в том случае, если настройкаcluster.remote_store.index.path.typeустановлена наHASHED_PREFIXилиHASHED_INFIX. По умолчанию пустая строка, “”.cluster.remote_store.segments.path.prefix(Строка): Управляет фиксированным префиксом пути для данных сегментов на кластере с включенным удаленным хранилищем. Эта настройка применяется только в том случае, если настройкаcluster.remote_store.index.path.typeустановлена наHASHED_PREFIXилиHASHED_INFIX. По умолчанию пустая строка, “”.cluster.snapshot.shard.path.prefix(Строка): Управляет фиксированным префиксом пути для блобов уровня сегмента снимка. Эта настройка применяется только в том случае, если настройкаrepository.shard_path_typeустановлена наHASHED_PREFIXилиHASHED_INFIX. По умолчанию пустая строка, “”.cluster.default_number_of_replicas(Целое число): Управляет значением по умолчанию для количества реплик индексов в кластере. Настройка уровня индексаindex.number_of_replicasпо умолчанию принимает это значение, если не настроена. По умолчанию 1.cluster.thread_pool.<fixed-threadpool>.size(Целое число): Управляет размерами как фиксированных, так и изменяемых очередей пулов потоков. Переопределяет значения по умолчанию, указанные вopensearch.yml.cluster.thread_pool.<scaling-threadpool>.max(Целое число): Устанавливает максимальный размер пула потоков с изменяемым размером. Переопределяет значение по умолчанию, указанное вopensearch.yml.cluster.thread_pool.<scaling-threadpool>.core(Целое число): Указывает базовый размер пула потоков с изменяемым размером. Переопределяет значение по умолчанию, указанное вopensearch.yml.
Настройки индекса уровня индекса
Вы можете указать настройки индекса при создании индекса. Существует два типа настроек индекса:
Статические настройки индекса уровня индекса — это настройки, которые нельзя обновить, пока индекс открыт. Чтобы обновить статическую настройку, необходимо закрыть индекс, обновить настройку, а затем снова открыть индекс.
Динамические настройки индекса уровня индекса — это настройки, которые можно обновлять в любое время.
Указание настройки при создании индекса
При создании индекса вы можете указать его статические или динамические настройки следующим образом:
PUT /testindex
{
"settings": {
"index.number_of_shards": 1,
"index.number_of_replicas": 2
}
}
Статические настройки индекса уровня индекса
OpenSearch поддерживает следующие статические настройки индекса уровня индекса:
index.number_of_shards(Целое число): Количество первичных шардов в индексе. По умолчанию 1.index.number_of_routing_shards(Целое число): Количество шардов маршрутизации, используемых для разделения индекса.index.shard.check_on_startup(Булевый): Указывает, следует ли проверять шардов индекса на наличие повреждений. Доступные опции:false(не проверять на повреждения),checksum(проверять на физические повреждения),true(проверять как на физические, так и на логические повреждения). По умолчаниюfalse.
index.codec(Строка): Определяет, как сжимаются и хранятся на диске сохраненные поля индекса. Эта настройка влияет на размер шардов индекса и производительность операций индексации.Допустимые значения:
defaultbest_compressionzstd(OpenSearch 2.9 и позже)zstd_no_dict(OpenSearch 2.9 и позже)qat_lz4(OpenSearch 2.14 и позже, на поддерживаемых системах)qat_deflate(OpenSearch 2.14 и позже, на поддерживаемых системах)
Для
zstd,zstd_no_dict,qat_lz4иqat_deflateвы можете указать уровень сжатия в настройкеindex.codec.compression_level. Для получения дополнительной информации смотрите Настройки кодека индекса. Опционально. По умолчаниюdefault.index.codec.compression_level(Целое число): Настройка уровня сжатия обеспечивает компромисс между коэффициентом сжатия и скоростью. Более высокий уровень сжатия приводит к более высокому коэффициенту сжатия (меньший размер хранения), но замедляет скорость сжатия и распаковки, что приводит к увеличению задержек при индексации и поиске. Эта настройка может быть указана только еслиindex.codecустановлен наzstdиzstd_no_dictв OpenSearch 2.9 и позже илиqat_lz4иqat_deflateв OpenSearch 2.14 и позже. Допустимые значения — целые числа в диапазоне [1, 6]. Для получения дополнительной информации смотрите Настройки кодека индекса. Опционально. По умолчанию 3.index.codec.qatmode(Строка): Режим аппаратного ускорения, используемый для кодеков сжатияqat_lz4иqat_deflate. Допустимые значения:autoиhardware. Для получения дополнительной информации смотрите Настройки кодека индекса. Опционально. По умолчаниюauto.index.routing_partition_size(Целое число): Количество шардов, к которым может быть направлено значение пользовательской маршрутизации. Маршрутизация помогает несбалансированному кластеру, перемещая значения к подмножеству шардов, а не к одному шару. Чтобы включить маршрутизацию, установите это значение больше 1, но меньшеindex.number_of_shards. По умолчанию 1.index.soft_deletes.retention_lease.period(Единица времени): Максимальное время хранения истории операций шара. По умолчанию 12 часов.index.load_fixed_bitset_filters_eagerly(Булевый): Указывает, должен ли OpenSearch предварительно загружать кэшированные фильтры. Доступные опции:trueиfalse. По умолчаниюtrue.index.hidden(Булевый): Указывает, должен ли индекс быть скрытым. Скрытые индексы не возвращаются в результате запросов, содержащих подстановочные знаки. Доступные опции:trueиfalse. По умолчаниюfalse.index.merge.policy(Строка): Эта настройка управляет политикой слияния для сегментов Lucene. Доступные опции:tieredиlog_byte_size. По умолчаниюtiered, но для временных данных, таких как журналы событий, рекомендуется использовать политику слиянияlog_byte_size, которая может улучшить производительность запросов при выполнении диапазонных запросов по полю@timestamp. Рекомендуется не изменять политику слияния существующего индекса. Вместо этого настройте эту опцию при создании нового индекса.index.merge_on_flush.enabled(Булевый): Эта настройка управляет функцией слияния при обновлении Apache Lucene, которая направлена на уменьшение количества сегментов путем выполнения слияний при обновлении (или, в терминах OpenSearch, при сбросе). По умолчаниюtrue.index.merge_on_flush.max_full_flush_merge_wait_time(Единица времени): Эта настройка устанавливает время ожидания для слияний, когдаindex.merge_on_flush.enabledвключен. По умолчанию 10 секунд.index.merge_on_flush.policy(Строка): Эта настройка управляет тем, какая политика слияния должна использоваться, когдаindex.merge_on_flush.enabledвключен. По умолчаниюdefault.index.check_pending_flush.enabled(Булевый): Эта настройка управляет параметромcheckPendingFlushOnUpdateиндексации Apache Lucene, который указывает, должен ли поток индексации проверять наличие ожидающих сбросов при обновлении, чтобы сбросить буферы индексации на диск. По умолчаниюtrue.index.use_compound_file(Булевый): Эта настройка управляет параметрамиuseCompoundFileиндексации Apache Lucene, которые указывают, будут ли новые файлы сегментов упакованы в составной файл. По умолчаниюtrue.index.append_only.enabled(Булевый): Установите значениеtrue, чтобы предотвратить любые обновления документов в индексе. По умолчаниюfalse.
Обновление статической настройки индекса
Вы можете обновить статическую настройку индекса только для закрытого индекса. Следующий пример демонстрирует обновление настройки кодека индекса.
Сначала закройте индекс:
POST /testindex/_close
Затем обновите настройки, отправив запрос к конечной точке _settings:
PUT /testindex/_settings
{
"index": {
"codec": "zstd_no_dict",
"codec.compression_level": 3
}
}
Наконец, снова откройте индекс, чтобы включить операции чтения и записи:
POST /testindex/_open
Для получения дополнительной информации об обновлении настроек, включая поддерживаемые параметры запроса, смотрите Обновление настроек.
Динамические настройки индекса уровня индекса
OpenSearch поддерживает следующие динамические настройки индекса уровня индекса:
index.number_of_replicas(Целое число): Количество реплик, которые должен иметь каждый первичный шард. Например, если у вас 4 первичных шарда и вы установитеindex.number_of_replicasна 3, индекс будет иметь 12 реплик. Если не установлено, по умолчанию используется значениеcluster.default_number_of_replicas(по умолчанию 1).index.number_of_search_replicas(Целое число): Количество поисковых реплик, которые должен иметь каждый первичный шард. Например, если у вас 4 первичных шарда и вы установитеindex.number_of_search_replicasна 3, индекс будет иметь 12 поисковых реплик. По умолчанию 0.index.auto_expand_replicas(Строка): Указывает, должен ли кластер автоматически добавлять реплики на основе количества узлов данных. Укажите нижнюю и верхнюю границы (например, 0–9) илиallдля верхней границы. Например, если у вас 5 узлов данных и вы установитеindex.auto_expand_replicasна 0–3, кластер не добавит еще одну реплику. Однако, если вы установите это значение на 0-all и добавите 2 узла, всего 7, кластер расширится до 6 реплик. По умолчанию отключено.index.auto_expand_search_replicas(Строка): Управляет тем, автоматически ли кластер регулирует количество поисковых реплик на основе количества доступных узлов поиска. Укажите значение в виде диапазона с нижней и верхней границей, например, 0-3 или 0-all. Если вы не укажете значение, эта функция отключена.Например, если у вас 5 узлов данных и вы установите
index.auto_expand_search_replicasна 0-3, индекс может иметь до 3 поисковых реплик, и кластер не добавит еще одну поисковую реплику. Однако, если вы установитеindex.auto_expand_search_replicasна 0-all и добавите 2 узла, всего 7, кластер расширится до 7 поисковых реплик. Эта настройка по умолчанию отключена.index.search.idle.after(Единица времени): Время, в течение которого шард должен ждать запроса поиска или получения, прежде чем перейти в состояние ожидания. По умолчанию 30 секунд.index.search.default_pipeline(Строка): Имя поискового конвейера, который используется, если при поиске индекса не установлен явный конвейер. Если установлен конвейер по умолчанию и он не существует, запросы к индексу завершатся неудачей. Используйте имя конвейера_none, чтобы указать отсутствие конвейера поиска по умолчанию. Для получения дополнительной информации смотрите Конвейер поиска по умолчанию.index.refresh_interval(Единица времени): Как часто индекс должен обновляться, что публикует его последние изменения и делает их доступными для поиска. Может быть установлено на -1 для отключения обновления. По умолчанию 1 секунда.index.max_result_window(Целое число): Максимальное значениеfrom + sizeдля запросов к индексу.from— это начальный индекс для поиска, аsize— количество результатов для возврата. По умолчанию 10000.index.max_inner_result_window(Целое число): Максимальное значениеfrom + size, которое указывает количество возвращаемых вложенных результатов поиска и наиболее релевантных документов, агрегированных во время запроса.from— это начальный индекс для поиска, аsize— количество верхних результатов для возврата. По умолчанию 100.index.max_rescore_window(Целое число): Максимальное значениеwindow_sizeдля запросов пересчета к индексу. Запросы пересчета изменяют порядок документов индекса и возвращают новый балл, который может быть более точным. По умолчанию такое же, какindex.max_inner_result_window, или 10000 по умолчанию.index.max_docvalue_fields_search(Целое число): Максимальное количествоdocvalue_fields, разрешенных в запросе. По умолчанию 100.index.max_script_fields(Целое число): Максимальное количествоscript_fields, разрешенных в запросе. По умолчанию 32.index.max_ngram_diff(Целое число): Максимальная разница между значениямиmin_gramиmax_gramдляNGramTokenizerиNGramTokenFilter. По умолчанию 1.index.max_shingle_diff(Целое число): Максимальная разница междуmax_shingle_sizeиmin_shingle_size, которая подается в фильтр токеновshingle. По умолчанию 3.index.max_refresh_listeners(Целое число): Максимальное количество слушателей обновления, которые может иметь каждый шард.index.analyze.max_token_count(Целое число): Максимальное количество токенов, которые могут быть возвращены из операции API_analyze. По умолчанию 10000.index.highlight.max_analyzed_offset(Целое число): Количество символов, которые может анализировать запрос на выделение. По умолчанию 1000000.index.max_terms_count(Целое число): Максимальное количество терминов, которые может принять запрос терминов. По умолчанию 65536.index.max_regex_length(Целое число): Максимальная длина символов регулярного выражения, которое может быть в запросеregexp. По умолчанию 1000.index.query.default_field(Список): Поле или список полей, которые OpenSearch использует в запросах, если поле не указано в параметрах.index.query.max_nested_depth(Целое число): Максимальное количество уровней вложенности для вложенных запросов. По умолчанию 20. Минимум 1 (один вложенный запрос).index.requests.cache.enable(Булевый): Включает или отключает кэш запросов индекса. По умолчаниюtrue. Для получения дополнительной информации смотрите Кэш запросов индекса.index.routing.allocation.enable(Строка): Указывает параметры для распределения шардов индекса. Доступные опции:all(разрешить распределение для всех шардов),primaries(разрешить распределение только для первичных шардов),new_primaries(разрешить распределение только для новых первичных шардов),none(не разрешать распределение). По умолчаниюall.
index.routing.rebalance.enable(Строка): Включает перераспределение шардов для индекса. Доступные опции:all(разрешить перераспределение для всех шардов),primaries(разрешить перераспределение только для первичных шардов),replicas(разрешить перераспределение только для реплик),none(не разрешать перераспределение). По умолчаниюall.
index.gc_deletes(Единица времени): Время хранения номера версии удаленного документа. По умолчанию 60 секунд.index.default_pipeline(Строка): Конвейер узла обработки по умолчанию для индекса. Если установлен конвейер по умолчанию и он не существует, запросы к индексу завершатся неудачей. Имя конвейера_noneуказывает на то, что у индекса нет конвейера обработки.index.final_pipeline(Строка): Конечный конвейер узла обработки для индекса. Если установлен конечный конвейер и он не существует, запросы к индексу завершатся неудачей. Имя конвейера_noneуказывает на то, что у индекса нет конвейера обработки.index.optimize_doc_id_lookup.fuzzy_set.enabled(Булевый): Эта настройка управляет тем, следует ли включатьfuzzy_setдля оптимизации поиска идентификаторов документов в индексах или запросах, используя дополнительную структуру данных, в данном случае структуру данных Bloom filter. Включение этой настройки улучшает производительность операцийupsertи поиска, которые зависят от идентификаторов документов, создавая новую структуру данных (Bloom filter). Bloom filter позволяет обрабатывать отрицательные случаи (то есть идентификаторы, отсутствующие в существующем индексе) с помощью более быстрых обращений вне кучи. Обратите внимание, что создание Bloom filter требует дополнительного использования кучи во время индексации. По умолчаниюfalse.index.optimize_doc_id_lookup.fuzzy_set.false_positive_probability(Число с плавающей точкой)
Устанавливает вероятность ложного срабатывания для базового fuzzy_set (то есть, фильтра Блума). Более низкая вероятность ложного срабатывания обеспечивает более высокую пропускную способность для операций upsert и get, но приводит к увеличению использования памяти и хранилища. Допустимые значения находятся в диапазоне от 0.01 до 0.50. По умолчанию установлено значение 0.20.
index.routing.allocation.total_shards_per_node(Целое число)
Максимальное общее количество первичных и репликационных шардов из одного индекса, которые могут быть распределены на один узел. По умолчанию установлено значение -1 (без ограничений). Помогает контролировать распределение шардов по узлам для каждого индекса, ограничивая количество шардов на узел. Используйте с осторожностью, так как шары из этого индекса могут оставаться нераспределенными, если узлы достигнут своих настроенных лимитов.
index.routing.allocation.total_primary_shards_per_node(Целое число)
Максимальное количество первичных шардов из одного индекса, которые могут быть распределены на один узел. Эта настройка применима только для кластеров с удаленной поддержкой. По умолчанию установлено значение -1 (без ограничений). Помогает контролировать распределение первичных шардов по узлам для каждого индекса, ограничивая количество первичных шардов на узел. Используйте с осторожностью, так как первичные шары из этого индекса могут оставаться нераспределенными, если узлы достигнут своих настроенных лимитов.
Обновление динамической настройки индекса
Вы можете обновить динамическую настройку индекса в любое время через API. Например, чтобы обновить интервал обновления, используйте следующий запрос:
PUT /testindex/_settings
{
"index": {
"refresh_interval": "2s"
}
}
Для получения дополнительной информации об обновлении настроек, включая поддерживаемые параметры запроса, смотрите раздел Обновление настроек.
8.2.3.9 - Настройки поиска
search.max_buckets (Динамическое, целое число): Максимальное количество агрегатных бакетов, разрешенных в одном ответе. По умолчанию 65535.
search.phase_took_enabled (Динамическое, логическое): Включает возврат значений времени на уровне фаз в ответах на поиск. По умолчанию false.
search.allow_expensive_queries (Динамическое, логическое): Разрешает или запрещает дорогостоящие запросы. Для получения дополнительной информации см. Дорогостоящие запросы.
search.default_allow_partial_results (Динамическое, логическое): Настройка на уровне кластера, которая позволяет возвращать частичные результаты поиска, если запрос превышает время ожидания или если шард не отвечает. Если запрос на поиск содержит параметр
allow_partial_search_results, этот параметр имеет приоритет над данной настройкой. По умолчанию true.search.cancel_after_time_interval (Динамическое, единица времени): Настройка на уровне кластера, которая устанавливает значение по умолчанию для таймаута всех запросов на поиск на уровне координирующего узла. После достижения указанного времени запрос останавливается, и все связанные задачи отменяются. По умолчанию -1 (без таймаута).
search.default_search_timeout (Динамическое, единица времени): Настройка на уровне кластера, которая указывает максимальное время, в течение которого запрос на поиск может выполняться, прежде чем он будет отменен на уровне шарда. Если интервал таймаута указан в запросе на поиск, этот интервал имеет приоритет над настроенной настройкой. По умолчанию -1.
search.default_keep_alive (Динамическое, единица времени): Указывает значение по умолчанию для поддержания активности для запросов с прокруткой и точкой во времени (PIT). Поскольку запрос может попадать на шард несколько раз (например, во время фаз запроса и извлечения), OpenSearch открывает контекст запроса, который существует на протяжении всего времени запроса, чтобы обеспечить согласованность состояния шарда для каждого отдельного запроса к шард. В стандартном поиске, как только фаза извлечения завершается, контекст запроса закрывается. Для запроса с прокруткой или PIT OpenSearch сохраняет контекст запроса открытым до явного закрытия (или до достижения времени поддержания активности). Фоновый поток периодически проверяет все открытые контексты прокрутки и PIT и удаляет те, которые превысили свой таймаут поддержания активности. Настройка
search.keep_alive_intervalуказывает, как часто контексты проверяются на истечение срока. Настройкаsearch.default_keep_aliveявляется значением по умолчанию для истечения срока. Запрос с прокруткой или PIT может явно указать время поддержания активности, которое имеет приоритет над этой настройкой. По умолчанию 5m.search.keep_alive_interval (Статическое, единица времени): Определяет интервал, с которым OpenSearch проверяет контексты запросов, которые превысили свой лимит поддержания активности. По умолчанию 1m.
search.max_keep_alive (Динамическое, единица времени): Указывает максимальное значение поддержания активности. Настройка
max_keep_aliveиспользуется в качестве меры безопасности по отношению к другим настройкам поддержания активности (например,default_keep_alive) и настройкам поддержания активности на уровне запроса (для контекстов прокрутки и PIT). Если запрос превышает значениеmax_keep_aliveв любом из случаев, операция завершится неудачей. По умолчанию 24h.search.low_level_cancellation (Динамическое, логическое): Включает механизм низкоуровневой отмены запросов. Классический механизм таймаута Lucene проверяет время только во время сбора результатов поиска. Однако дорогостоящий запрос, такой как запрос с подстановочными знаками или префиксами, может занять много времени для расширения перед началом сбора результатов. В этом случае запрос может выполняться в течение времени, превышающего значение таймаута. Механизм низкоуровневой отмены решает эту проблему, устанавливая таймаут не только во время сбора результатов поиска, но и во время фазы расширения запроса или перед выполнением любой операции Lucene. По умолчанию true.
search.max_open_scroll_context (Динамическое, целое число): Настройка на уровне узла, которая указывает максимальное количество открытых контекстов прокрутки для узла. По умолчанию 500.
search.request_stats_enabled (Динамическое, логическое): Включает сбор статистики времени фаз на уровне узла с точки зрения координирующего узла. Статистика на уровне запроса отслеживает, сколько времени (всего) запросы на поиск проводят в каждой из различных фаз поиска. Вы можете получить эти счетчики, используя API статистики узлов. По умолчанию false.
search.highlight.term_vector_multi_value (Статическое, логическое): Указывает на необходимость выделять фрагменты по значениям многозначного поля. По умолчанию true.
search.max_aggregation_rewrite_filters (Динамическое, целое число): Определяет максимальное количество фильтров переписывания, разрешенных во время агрегации. Установите это значение в 0, чтобы отключить оптимизацию переписывания фильтров для агрегаций. Это экспериментальная функция и может измениться или быть удалена в будущих версиях.
search.dynamic_pruning.cardinality_aggregation.max_allowed_cardinality (Динамическое, целое число): Определяет порог для применения динамической обрезки в агрегации по кардинальности. Если кардинальность поля превышает этот порог, агрегация возвращается к методу по умолчанию. Это экспериментальная функция и может измениться или быть удалена в будущих версиях.
search.keyword_index_or_doc_values_enabled (Динамическое, логическое): Определяет, использовать ли индекс или значения документа при выполнении запросов
multi_termна полях ключевых слов. Значение по умолчанию - false.
Настройки точки во времени (PIT)
Для получения информации о настройках PIT см. Настройки PIT.
Чтобы узнать больше о статических и динамических настройках, см. Настройка OpenSearch.
8.2.3.10 - Настройки плагинов
Настройки плагина оповещений
Для получения информации о настройках оповещений см. Настройки оповещений.
Настройки плагина обнаружения аномалий
Для получения информации о настройках обнаружения аномалий см. Настройки обнаружения аномалий.
Настройки плагина асинхронного поиска
Для получения информации о настройках асинхронного поиска см. Настройки асинхронного поиска.
Настройки плагина репликации между кластерами
Для получения информации о настройках репликации между кластерами см. Настройки репликации.
Настройки плагина Flow Framework
Для получения информации о настройках автоматического рабочего процесса см. Настройки рабочего процесса.
Настройки плагина геопространственных данных
Для получения информации о настройках процессора IP2Geo плагина геопространственных данных см. Настройки кластера.
Настройки плагина управления индексами
Для получения информации о настройках управления состоянием индекса (ISM) см. Настройки ISM.
Настройки сворачивания индексов
Для получения информации о настройках сворачивания индексов см. Настройки сворачивания индексов.
Настройки плагина планировщика задач
Для получения информации о настройках плагина планировщика задач см. Настройки кластера планировщика задач.
Настройки плагина k-NN
Для получения информации о настройках k-NN см. Настройки k-NN.
Настройки плагина ML Commons
Для получения информации о настройках машинного обучения см. Настройки кластера ML Commons.
Настройки плагина нейронного поиска
Плагин Security Analytics поддерживает следующие настройки:
- plugins.neural_search.hybrid_search_disabled (Динамическое, логическое): Отключает гибридный поиск. По умолчанию false.
Настройки плагина уведомлений
Плагин уведомлений поддерживает следующие настройки. Все настройки в этом списке являются динамическими:
opensearch.notifications.core.allowed_config_types (Список): Разрешенные типы конфигурации плагина уведомлений. Используйте API
GET /_plugins/_notifications/features, чтобы получить значение этой настройки. Типы конфигурации включают slack, chime, microsoft_teams, webhook, email, sns, ses_account, smtp_account и email_group.opensearch.notifications.core.email.minimum_header_length (Целое число): Минимальная длина заголовка электронной почты. Используется для проверки общей длины сообщения электронной почты. По умолчанию 160.
opensearch.notifications.core.email.size_limit (Целое число): Лимит размера электронной почты. Используется для проверки общей длины сообщения электронной почты. По умолчанию 10000000.
opensearch.notifications.core.http.connection_timeout (Целое число): Таймаут подключения внутреннего HTTP-клиента. Клиент используется для каналов уведомлений на основе вебхуков. По умолчанию 5000.
opensearch.notifications.core.http.host_deny_list (Список): Список запрещенных хостов. HTTP-клиент не отправляет уведомления на URL вебхуков из этого списка.
opensearch.notifications.core.http.max_connection_per_route (Целое число): Максимальное количество HTTP-соединений на маршрут внутреннего HTTP-клиента. Клиент используется для каналов уведомлений на основе вебхуков. По умолчанию 20.
opensearch.notifications.core.http.max_connections (Целое число): Максимальное количество HTTP-соединений внутреннего HTTP-клиента. Клиент используется для каналов уведомлений на основе вебхуков. По умолчанию 60.
opensearch.notifications.core.http.socket_timeout (Целое число): Конфигурация таймаута сокета внутреннего HTTP-клиента. Клиент используется для каналов уведомлений на основе вебхуков. По умолчанию 50000.
opensearch.notifications.core.tooltip_support (Логическое): Включает поддержку подсказок для плагина уведомлений. Используйте API
GET /_plugins/_notifications/features, чтобы получить значение этой настройки. По умолчанию true.opensearch.notifications.general.filter_by_backend_roles (Логическое): Включает фильтрацию по ролям бэкенда (контроль доступа на основе ролей для каналов уведомлений). По умолчанию false.
Настройки плагина Query Insights
Для получения информации о настройках плагина Query Insights см. Функции и настройки Query Insights.
Настройки плагина безопасности
Для получения информации о настройках плагина безопасности см. Настройки безопасности.
Настройки плагина Security Analytics
Для получения информации о настройках аналитики безопасности см. Настройки Security Analytics.
Настройки плагина SQL
Для получения информации о настройках, связанных с SQL и PPL, см. Настройки SQL.
8.2.3.11 - Экспериментальные флаги функций
Включение в opensearch.yml
Если вы запускаете кластер OpenSearch и хотите включить флаги функций в конфигурационном файле, добавьте следующую строку в opensearch.yml:
opensearch.experimental.feature.<feature_name>.enabled: true
Включение в контейнерах Docker
Если вы используете Docker, добавьте следующую строку в docker-compose.yml в разделе opensearch-node > environment:
OPENSEARCH_JAVA_OPTS="-Dopensearch.experimental.feature.<feature_name>.enabled=true"
Включение в установке tarball
Чтобы включить флаги функций в установке tarball, укажите новый параметр JVM либо в config/jvm.options, либо в OPENSEARCH_JAVA_OPTS.
Вариант 1: Изменение jvm.options
Добавьте следующие строки в config/jvm.options перед запуском процесса OpenSearch, чтобы включить функцию и ее зависимости:
-Dopensearch.experimental.feature.<feature_name>.enabled=true
Затем запустите OpenSearch:
./bin/opensearch
Вариант 2: Включение с помощью переменной окружения
В качестве альтернативы прямому изменению config/jvm.options, вы можете определить свойства, используя переменную окружения. Это можно сделать с помощью одной команды при запуске OpenSearch или определив переменную с помощью export.
Чтобы добавить флаги функций в строке при запуске OpenSearch, выполните следующую команду:
OPENSEARCH_JAVA_OPTS="-Dopensearch.experimental.feature.<feature_name>.enabled=true" ./opensearch-3.1.0/bin/opensearch
Если вы хотите определить переменную окружения отдельно перед запуском OpenSearch, выполните следующие команды:
export OPENSEARCH_JAVA_OPTS="-Dopensearch.experimental.feature.<feature_name>.enabled=true"
./bin/opensearch
Включение для разработки OpenSearch
Чтобы включить флаги функций для разработки, вы должны добавить правильные свойства в run.gradle перед сборкой OpenSearch. См. Руководство для разработчиков для получения информации о том, как использовать Gradle для сборки OpenSearch.
Добавьте следующие свойства в run.gradle, чтобы включить функцию:
testClusters {
runTask {
testDistribution = 'archive'
if (numZones > 1) numberOfZones = numZones
if (numNodes > 1) numberOfNodes = numNodes
systemProperty 'opensearch.experimental.feature.<feature_name>.enabled', 'true'
}
}
8.2.3.12 - Logs
- В Docker OpenSearch записывает большинство логов в консоль и сохраняет оставшиеся в
opensearch/logs/. Установка tarball также используетopensearch/logs/. - В большинстве установок на Linux OpenSearch записывает логи в
/var/log/opensearch/.
Логи доступны в формате .log (обычный текст) и .json. Права доступа к логам OpenSearch по умолчанию составляют -rw-r--r--, что означает, что любой пользователь на узле может их читать. Вы можете изменить это поведение для каждого типа логов в log4j2.properties, используя опцию filePermissions. Например, вы можете добавить appender.rolling.filePermissions = rw-r-----, чтобы изменить права доступа для JSON-сервера логов. Для получения подробной информации см. документацию Log4j 2.
Логи приложений
Для своих логов приложений OpenSearch использует Apache Log4j 2 и его встроенные уровни логирования (от наименее до наиболее серьезных). В следующей таблице описаны настройки логирования.
| Настройка | Тип данных | Описание |
|---|---|---|
logger.org.opensearch.discovery | Строка | Логгеры принимают встроенные уровни логирования Log4j2: OFF, FATAL, ERROR, WARN, INFO, DEBUG и TRACE. По умолчанию INFO. |
Вместо изменения уровня логирования по умолчанию (logger.level), вы можете изменить уровень логирования для отдельных модулей OpenSearch:
PUT /_cluster/settings
{
"persistent" : {
"logger.org.opensearch.index.reindex" : "DEBUG"
}
}
Самый простой способ идентифицировать модули — не по логам, которые сокращают путь (например, o.o.i.r), а по исходному коду OpenSearch.
После этого изменения OpenSearch будет генерировать гораздо более подробные логи во время операций повторной индексации:
[2019-10-18T16:52:51,184][DEBUG][o.o.i.r.TransportReindexAction] [node1] [1626]: starting
[2019-10-18T16:52:51,186][DEBUG][o.o.i.r.TransportReindexAction] [node1] executing initial scroll against [some-index]
[2019-10-18T16:52:51,291][DEBUG][o.o.i.r.TransportReindexAction] [node1] scroll returned [3] documents with a scroll id of [DXF1Z==]
[2019-10-18T16:52:51,292][DEBUG][o.o.i.r.TransportReindexAction] [node1] [1626]: got scroll response with [3] hits
[2019-10-18T16:52:51,294][DEBUG][o.o.i.r.WorkerBulkByScrollTaskState] [node1] [1626]: preparing bulk request for [0s]
[2019-10-18T16:52:51,297][DEBUG][o.o.i.r.TransportReindexAction] [node1] [1626]: preparing bulk request
[2019-10-18T16:52:51,299][DEBUG][o.o.i.r.TransportReindexAction] [node1] [1626]: sending [3] entry, [222b] bulk request
[2019-10-18T16:52:51,310][INFO ][o.e.c.m.MetaDataMappingService] [node1] [some-new-index/R-j3adc6QTmEAEb-eAie9g] create_mapping [_doc]
[2019-10-18T16:52:51,383][DEBUG][o.o.i.r.TransportReindexAction] [node1] [1626]: got scroll response with [0] hits
[2019-10-18T16:52:51,384][DEBUG][o.o.i.r.WorkerBulkByScrollTaskState] [node1] [1626]: preparing bulk request for [0s]
[2019-10-18T16:52:51,385][DEBUG][o.o.i.r.TransportReindexAction] [node1] [1626]: preparing bulk request
[2019-10-18T16:52:51,386][DEBUG][o.o.i.r.TransportReindexAction] [node1] [1626]: finishing without any catastrophic failures
[2019-10-18T16:52:51,395][DEBUG][o.o.i.r.TransportReindexAction] [node1] Freed [1] contexts
Уровни DEBUG и TRACE являются чрезвычайно подробными. Если вы включаете один из них для устранения проблемы, отключите его после завершения.
Существуют и другие способы изменения уровней логирования:
- Добавление строк в
opensearch.yml
logger.org.opensearch.index.reindex: debug
Изменение opensearch.yml имеет смысл, если вы хотите повторно использовать свою конфигурацию логирования для нескольких кластеров или отлаживать проблемы запуска с одним узлом.
- Изменение
log4j2.properties
# Определите новый логгер с уникальным ID для повторной индексации
logger.reindex.name = org.opensearch.index.reindex
# Установите уровень логирования для этого ID
logger.reindex.level = debug
Этот подход является чрезвычайно гибким, но требует знакомства с синтаксисом файла свойств Log4j 2. В общем, другие варианты предлагают более простую конфигурацию.
Если вы изучите файл log4j2.properties по умолчанию в каталоге конфигурации, вы увидите несколько специфичных для OpenSearch переменных:
appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] [%node_name]%marker %m%n
appender.rolling_old.fileName = ${sys:opensearch.logs.base_path}${sys:file.separator}${sys:opensearch.logs.cluster_name}.log
${sys:opensearch.logs.base_path}— это каталог для логов (например,/var/log/opensearch/).${sys:opensearch.logs.cluster_name}— это имя кластера.${sys:opensearch.logs.node_name}— это имя узла.[%node_name]— это имя узла.
Медленные логи запросов поиска
Новая функция в версии 2.12, OpenSearch предлагает медленные логи на уровне запросов для поиска. Эти логи основываются на пороговых значениях, чтобы определить, что квалифицируется как “медленно”. Все запросы, которые превышают порог, записываются в логи.
Медленные логи запросов поиска включаются динамически через API настроек кластера. В отличие от медленных логов шардов, пороги медленных логов запросов поиска настраиваются для общего времени выполнения запроса. По умолчанию логи отключены (все пороги установлены на -1).
PUT /_cluster/settings
{
"persistent" : {
"cluster.search.request.slowlog.level" : "TRACE",
"cluster.search.request.slowlog.threshold.warn": "10s",
"cluster.search.request.slowlog.threshold.info": "5s",
"cluster.search.request.slowlog.threshold.debug": "2s",
"cluster.search.request.slowlog.threshold.trace": "10ms"
}
}
Строка из opensearch_index_search_slowlog.log может выглядеть следующим образом:
[2023-10-30T15:47:42,630][TRACE][c.s.r.slowlog] [runTask-0] took[80.8ms], took_millis[80], phase_took_millis[{expand=0, query=39, fetch=22}], total_hits[4 hits], search_type[QUERY_THEN_FETCH], shards[{total: 10, successful: 10, skipped: 0, failed: 0}], source[{"query":{"match_all":{"boost":1.0}}}], id[]
Медленные логи запросов поиска могут занимать значительное место на диске и влиять на производительность, если вы установите низкие пороговые значения. Рассмотрите возможность временного включения их для устранения неполадок или настройки производительности. Чтобы отключить медленные логи запросов поиска, верните все пороги к -1.
Медленные логи шардов
OpenSearch имеет два типа медленных логов шардов, которые помогают выявлять проблемы с производительностью: медленный лог поиска и медленный лог индексации.
Эти логи основываются на пороговых значениях, чтобы определить, что квалифицируется как “медленный” поиск или “медленная” операция индексации. Например, вы можете решить, что запрос считается медленным, если его выполнение занимает более 15 секунд. В отличие от логов приложений, которые настраиваются для модулей, медленные логи настраиваются для индексов. По умолчанию оба лога отключены (все пороги установлены на -1).
В отличие от медленных логов запросов поиска, пороги медленных логов шардов настраиваются для времени выполнения отдельных шардов.
GET <some-index>/_settings?include_defaults=true
{
"indexing": {
"slowlog": {
"reformat": "true",
"threshold": {
"index": {
"warn": "-1",
"trace": "-1",
"debug": "-1",
"info": "-1"
}
},
"source": "1000",
"level": "TRACE"
}
},
"search": {
"slowlog": {
"level": "TRACE",
"threshold": {
"fetch": {
"warn": "-1",
"trace": "-1",
"debug": "-1",
"info": "-1"
},
"query": {
"warn": "-1",
"trace": "-1",
"debug": "-1",
"info": "-1"
}
}
}
}
}
Чтобы включить эти логи, увеличьте один или несколько порогов:
PUT <some-index>/_settings
{
"indexing": {
"slowlog": {
"threshold": {
"index": {
"warn": "15s",
"trace": "750ms",
"debug": "3s",
"info": "10s"
}
},
"source": "500",
"level": "INFO"
}
}
}
Пример настройки медленных логов индексации
В этом примере OpenSearch записывает операции индексации, которые занимают 15 секунд или дольше, на уровне WARN, а операции, которые занимают от 10 до 14.x секунд, на уровне INFO. Если вы установите порог в 0 секунд, OpenSearch будет записывать все операции, что может быть полезно для проверки, действительно ли медленные логи включены.
- reformat указывает, следует ли записывать поле _source документа в одной строке (true) или позволить ему занимать несколько строк (false).
- source — это количество символов поля _source документа, которые нужно записать.
- level — это минимальный уровень логирования, который следует включить.
Строка из opensearch_index_indexing_slowlog.log может выглядеть следующим образом:
node1 | [2019-10-24T19:48:51,012][WARN][i.i.s.index] [node1] [some-index/i86iF5kyTyy-PS8zrdDeAA] took[3.4ms], took_millis[3], type[_doc], id[1], routing[], source[{"title":"Your Name", "Director":"Makoto Shinkai"}]
Медленные логи шардов могут занимать значительное место на диске и влиять на производительность, если вы установите низкие пороговые значения. Рассмотрите возможность временного включения их для устранения неполадок или настройки производительности. Чтобы отключить медленные логи шардов, верните все пороги к -1.
Журналы задач
OpenSearch может записывать время ЦП и использование памяти для N самых затратных по памяти поисковых задач, когда включены потребители ресурсов задач. По умолчанию потребители ресурсов задач будут записывать 10 самых затратных поисковых задач с интервалом в 60 секунд. Эти значения можно настроить в файле opensearch.yml.
Запись задач включается динамически через API настроек кластера:
PUT _cluster/settings
{
"persistent" : {
"task_resource_consumers.enabled" : "true"
}
}
Включение потребителей ресурсов задач может повлиять на задержку поиска.
После включения журналы будут записываться в файлы logs/opensearch_task_detailslog.json и logs/opensearch_task_detailslog.log.
Чтобы настроить интервал записи и количество записываемых поисковых задач, добавьте следующие строки в opensearch.yml:
# Количество затратных поисковых задач для записи
cluster.task.consumers.top_n.size: 100
# Интервал записи
cluster.task.consumers.top_n.frequency: 30s
Журналы устаревания
Журналы устаревания фиксируют, когда клиенты делают устаревшие вызовы API к вашему кластеру. Эти журналы могут помочь вам выявить и исправить проблемы до обновления до новой основной версии. По умолчанию OpenSearch записывает устаревшие вызовы API на уровне WARN, что хорошо подходит для почти всех случаев использования. При необходимости настройте logger.deprecation.level, используя _cluster/settings, opensearch.yml или log4j2.properties.
8.2.4 - Сравнение ОС
Совместимость OpenSearch и OpenSearch Dashboards
OpenSearch и OpenSearch Dashboards совместимы с Red Hat Enterprise Linux (RHEL) и дистрибутивами Linux на базе Debian, которые используют systemd, такими как Amazon Linux и Ubuntu Long-Term Support (LTS). Хотя OpenSearch и OpenSearch Dashboards должны работать на большинстве дистрибутивов Linux, мы тестируем только подмножество из них.
Поддерживаемые операционные системы
Следующая таблица перечисляет версии операционных систем, которые мы в настоящее время тестируем:
| ОС | Версия |
|---|---|
| Rocky Linux | 8 |
| Alma Linux | 8 |
| Amazon Linux | 2/2023 |
| Ubuntu | 24.04 |
| Windows Server | 2019 |
Журнал изменений
Следующая таблица перечисляет изменения, внесенные в совместимость операционных систем.
| Дата | Проблема | PR | Подробности |
|---|---|---|---|
| 2025-02-06 | opensearch-build Issue 5270 | PR 9165 | Удаление Ubuntu 20.04 |
| 2024-07-23 | opensearch-build Issue 4379 | PR 7821 | Удаление CentOS7 |
| 2024-03-08 | opensearch-build Issue 4573 | PR 6637 | Удаление CentOS8, добавление Almalinux8/Rockylinux8 и удаление Ubuntu 16.04/18.04, так как мы в настоящее время тестируем только на 20.04 |
| 2023-06-06 | documentation-website Issue 4217 | PR 4218 | Создание матрицы поддержки |
8.2.5 - Настройка OpenSearch Dashboards
OpenSearch Dashboards использует файл конфигурации opensearch_dashboards.yml для чтения настроек при запуске кластера. Вы можете найти opensearch_dashboards.yml по следующему пути: /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml (Docker) или /etc/opensearch-dashboards/opensearch_dashboards.yml (большинство дистрибутивов Linux) на каждом узле.
Для получения информации о настройках OpenSearch Dashboards ознакомьтесь с образцом файла opensearch_dashboards.yml.
8.2.6 - Upgrading OpenSearch
Проект OpenSearch регулярно выпускает обновления, которые включают новые функции, улучшения и исправления ошибок. OpenSearch использует семантическое версионирование, что означает, что разрушающие изменения вводятся только между основными версиями. Чтобы узнать о предстоящих функциях и исправлениях, ознакомьтесь с дорожной картой проекта OpenSearch на GitHub. Чтобы просмотреть список предыдущих релизов или узнать больше о том, как OpenSearch использует версионирование, смотрите раздел “График релизов и политика обслуживания”.
Мы понимаем, что пользователи заинтересованы в обновлении OpenSearch, чтобы воспользоваться последними функциями, и мы будем продолжать расширять эти документы по обновлению и миграции, чтобы охватить дополнительные темы, такие как обновление OpenSearch Dashboards и сохранение пользовательских конфигураций, например, для плагинов.
Если вы хотите, чтобы был добавлен конкретный процесс или хотите внести свой вклад, создайте задачу на GitHub. Ознакомьтесь с Руководством для участников, чтобы узнать, как вы можете помочь.
Учет рабочих процессов
Потратьте время на планирование процесса перед внесением каких-либо изменений в ваш кластер. Например, рассмотрите следующие вопросы:
- Сколько времени займет процесс обновления?
- Если ваш кластер используется в производственной среде, насколько критично время простоя?
- У вас есть инфраструктура для развертывания нового кластера в тестовой или разработческой среде перед его переводом в эксплуатацию, или вам нужно обновить производственные узлы напрямую?
Ответы на такие вопросы помогут вам определить, какой путь обновления будет наиболее подходящим для вашей среды.
Минимально вы должны:
- Ознакомиться с разрушающими изменениями.
- Ознакомиться с матрицами совместимости инструментов OpenSearch.
- Ознакомиться с совместимостью плагинов.
- Создать резервные копии файлов конфигурации.
- Создать снимок.
Остановить любую несущественную индексацию перед началом процедуры обновления, чтобы устранить ненужные требования к ресурсам кластера во время выполнения обновления.
Ознакомление с разрушающими изменениями
Важно определить, как новая версия OpenSearch будет интегрироваться с вашей средой. Ознакомьтесь с разделом “Разрушающие изменения” перед началом любых процедур обновления, чтобы определить, нужно ли вам вносить изменения в ваш рабочий процесс. Например, компоненты, находящиеся выше или ниже по потоку, могут потребовать модификации для совместимости с изменением API (см. мета-проблему #2589).
Ознакомление с матрицами совместимости инструментов OpenSearch
Если ваш кластер OpenSearch взаимодействует с другими службами в вашей среде, такими как Logstash или Beats, вам следует проверить матрицы совместимости инструментов OpenSearch, чтобы определить, нужно ли обновлять другие компоненты.
Ознакомление с совместимостью плагинов
Проверьте плагины, которые вы используете, чтобы определить их совместимость с целевой версией OpenSearch. Официальные плагины проекта OpenSearch можно найти в репозитории проекта OpenSearch на GitHub. Если вы используете сторонние плагины, вам следует ознакомиться с документацией для этих плагинов, чтобы определить, совместимы ли они.
Перейдите в раздел “Доступные плагины”, чтобы увидеть справочную таблицу, которая подчеркивает совместимость версий для встроенных плагинов OpenSearch.
Основные, второстепенные и патч-версии плагинов должны соответствовать основным, второстепенным и патч-версиям OpenSearch для обеспечения совместимости. Например, версии плагинов 2.3.0.x работают только с OpenSearch 2.3.0.
Резервное копирование файлов конфигурации
Снизьте риск потери данных, создав резервные копии любых важных файлов перед началом обновления. Обычно эти файлы будут находиться в одной из двух директорий:
opensearch/configopensearch-dashboards/config
Некоторые примеры включают opensearch.yml, opensearch_dashboards.yml, файлы конфигурации плагинов и сертификаты TLS. Как только вы определите, какие файлы хотите сохранить, скопируйте их на удаленное хранилище для безопасности.
Если вы используете функции безопасности, обязательно ознакомьтесь с разделом “Предостережение” для получения информации о резервном копировании и восстановлении ваших настроек безопасности.
Создание снимка
Рекомендуется создать резервную копию состояния вашего кластера и индексов с помощью снимков. Снимки, сделанные перед обновлением, могут быть использованы в качестве точек восстановления, если вам нужно будет откатить кластер к его оригинальной версии.
Вы можете дополнительно снизить риск потери данных, храня ваши снимки на внешнем хранилище, таком как смонтированная файловая система сети (NFS) или облачное хранилище, как указано в следующей таблице.
| Местоположение репозитория снимков | Требуемый плагин OpenSearch |
|---|---|
| Amazon Simple Storage Service (Amazon S3) | repository-s3 |
| Google Cloud Storage (GCS) | repository-gcs |
| Apache Hadoop Distributed File System (HDFS) | repository-hdfs |
| Microsoft Azure Blob Storage | repository-azure |
Методы обновления
Выберите подходящий метод для обновления вашего кластера до новой версии OpenSearch в зависимости от ваших требований:
- Постепенное обновление (rolling upgrade) обновляет узлы по одному без остановки кластера.
- Обновление с перезапуском кластера (cluster restart upgrade) обновляет службы, пока кластер остановлен.
Обновления, охватывающие более одной основной версии OpenSearch, потребуют дополнительных усилий из-за необходимости повторной индексации. Для получения дополнительной информации обратитесь к API повторной индексации. См. таблицу совместимости индексов, включенную позже в этом руководстве, для помощи в планировании миграции данных.
Постепенное обновление
Постепенное обновление — отличный вариант, если вы хотите сохранить работоспособность вашего кластера на протяжении всего процесса. Данные могут продолжать поступать, анализироваться и запрашиваться, пока узлы поочередно останавливаются, обновляются и перезапускаются. Вариация постепенного обновления, называемая “замена узла” (node replacement), следует точно такому же процессу, за исключением того, что хосты и контейнеры не повторно используются для нового узла. Вы можете выполнить замену узла, если также обновляете базовые хосты.
Узлы OpenSearch не могут присоединиться к кластеру, если менеджер кластера работает на более новой версии OpenSearch, чем узел, запрашивающий членство. Чтобы избежать этой проблемы, обновляйте узлы, имеющие право на управление кластером, последними.
Смотрите раздел “Постепенное обновление” для получения дополнительной информации о процессе.
Обновление с перезапуском кластера
Администраторы OpenSearch могут выбрать выполнение обновления с перезапуском кластера по нескольким причинам, например, если администратор не хочет проводить обслуживание работающего кластера или если кластер мигрируется в другую среду.
В отличие от постепенного обновления, при котором только один узел отключен в любой момент времени, обновление с перезапуском кластера требует остановки OpenSearch и OpenSearch Dashboards на всех узлах кластера перед продолжением. После остановки узлов устанавливается новая версия OpenSearch. Затем OpenSearch запускается, и кластер загружается на новую версию.
Совместимость
Узлы OpenSearch совместимы с другими узлами OpenSearch, работающими на любой другой минорной версии в рамках одного основного релиза. Например, версия 1.1.0 совместима с 1.3.7, поскольку они являются частью одной основной версии (1.x). Кроме того, узлы OpenSearch и индексы обратно совместимы с предыдущей основной версией. Это означает, что, например, индекс, созданный узлом OpenSearch, работающим на любой версии 1.x, может быть восстановлен из снимка в кластер OpenSearch, работающий на любой версии 2.x.
Узлы OpenSearch 1.x совместимы с узлами, работающими на Elasticsearch 7.x, но продолжительность работы смешанной версии не должна превышать период обновления кластера.
Совместимость индексов определяется версией Apache Lucene, которая создала индекс. Если индекс был создан кластером OpenSearch, работающим на версии 1.0.0, то этот индекс может использоваться любым другим кластером OpenSearch, работающим до последнего релиза 1.x или 2.x. См. таблицу совместимости индексов для версий Lucene, работающих в OpenSearch 1.0.0 и более поздних версиях, а также в Elasticsearch 6.8 и более поздних версиях.
Если ваш путь обновления охватывает более одной основной версии и вы хотите сохранить существующие индексы, вы можете использовать API повторной индексации (Reindex API), чтобы сделать ваши индексы совместимыми с целевой версией OpenSearch перед обновлением. Например, если ваш кластер в настоящее время работает на Elasticsearch 6.8 и вы хотите обновиться до OpenSearch 2.x, вам сначала нужно обновиться до OpenSearch 1.x, заново создать ваши индексы с помощью API повторной индексации и, наконец, обновиться до 2.x. Одной из альтернатив повторной индексации является повторное извлечение данных из источника, например, воспроизведение потока данных или извлечение данных из базы данных.
Справочная таблица совместимости индексов
Если вы планируете сохранить старые индексы после обновления версии OpenSearch, вам может потребоваться повторная индексация или повторное извлечение данных. Обратитесь к следующей таблице для версий Lucene в недавних релизах OpenSearch и Elasticsearch.
| Версия Lucene | Версия OpenSearch | Версия Elasticsearch |
|---|---|---|
| 9.10.0 | 2.14.0 | |
| 2.13.0 | 8.13 | |
| 9.9.2 | 2.12.0 | — |
| 9.7.0 | 2.11.1 | |
| 2.9.0 | 8.9.0 | |
| 9.6.0 | 2.8.0 | 8.8.0 |
| 9.5.0 | 2.7.0 | |
| 2.6.0 | 8.7.0 | |
| 9.4.2 | 2.5.0 | |
| 2.4.1 | 8.6 | |
| 9.4.1 | 2.4.0 | — |
| 9.4.0 | — | 8.5 |
| 9.3.0 | 2.3.0 | |
| 2.2.x | 8.4 | |
| 9.2.0 | 2.1.0 | 8.3 |
| 9.1.0 | 2.0.x | 8.2 |
| 9.0.0 | — | 8.1 |
| 8.0 | ||
| 8.11.1 | — | 7.17 |
| 8.10.1 | 1.3.x | |
| 1.2.x | 7.16 | |
| 8.9.0 | 1.1.0 | 7.15 |
| 7.14 | ||
| 8.8.2 | 1.0.0 | 7.13 |
| 8.8.0 | — | 7.12 |
| 8.7.0 | — | 7.11 |
| 7.10 | ||
| 8.6.2 | — | 7.9 |
| 8.5.1 | — | 7.8 |
| 7.7 | ||
| 8.4.0 | — | 7.6 |
| 8.3.0 | — | 7.5 |
| 8.2.0 | — | 7.4 |
| 8.1.0 | — | 7.3 |
| 8.0.0 | — | 7.2 |
| 7.1 | ||
| 7.7.3 | — | 6.8 |
Тире (—) указывает на то, что нет версии продукта, содержащей указанную версию Apache Lucene.
8.2.6.1 - Приложение по обновлениям
Конкретные процедуры, изложенные в разделе приложения, могут быть использованы различными способами:
- Новые пользователи OpenSearch могут использовать шаги и примеры ресурсов, которые мы предоставляем, чтобы узнать о конфигурации и использовании OpenSearch и OpenSearch Dashboards.
- Системные администраторы, работающие с кластерами OpenSearch, могут использовать предоставленные примеры для симуляции обслуживания кластера в тестовой среде перед применением любых изменений к рабочей нагрузке в производственной среде.
Если вы хотите запросить конкретную тему, пожалуйста, оставьте комментарий по вопросу #2830 в проекте OpenSearch на GitHub.
Конкретные команды, включенные в это приложение, служат примерами взаимодействия с API OpenSearch и основным хостом, чтобы продемонстрировать шаги, описанные в связанных документах по процессу обновления. Цель состоит не в том, чтобы быть чрезмерно предписывающим, а в том, чтобы добавить контекст для пользователей, которые новы в OpenSearch и хотят увидеть практические примеры.
8.2.6.2 - Постепенное обновление
Постепенные обновления, иногда называемые “обновлениями замены узлов”, могут выполняться на работающих кластерах с практически нулевым временем простоя. Узлы поочередно останавливаются и обновляются на месте. В качестве альтернативы узлы могут быть остановлены и заменены, один за другим, хостами, работающими на новой версии. В процессе вы можете продолжать индексировать и запрашивать данные в вашем кластере.
Этот документ служит общим обзором процедуры постепенного обновления, не зависящим от платформы. Для конкретных примеров команд, скриптов и файлов конфигурации смотрите Приложение.
Подготовка к обновлению
Ознакомьтесь с разделом “Обновление OpenSearch” для получения рекомендаций по резервному копированию ваших файлов конфигурации и созданию снимка состояния кластера и индексов перед внесением каких-либо изменений в ваш кластер OpenSearch.
Важно: Узлы OpenSearch не могут быть понижены. Если вам нужно отменить обновление, вам потребуется выполнить новую установку OpenSearch и восстановить кластер из снимка. Сделайте снимок и сохраните его в удаленном репозитории перед началом процедуры обновления.
Выполнение обновления
- Проверьте состояние вашего кластера OpenSearch перед началом. Вам следует решить любые проблемы с индексами или распределением шардов перед обновлением, чтобы гарантировать сохранность ваших данных. Статус “green” указывает на то, что все первичные и реплика-шарды распределены. См. раздел “Состояние кластера” для получения дополнительной информации. Следующая команда запрашивает конечную точку API _cluster/health:
GET "/_cluster/health?pretty"
Ответ должен выглядеть примерно так:
{
"cluster_name": "opensearch-dev-cluster",
"status": "green",
"timed_out": false,
"number_of_nodes": 4,
"number_of_data_nodes": 4,
"active_primary_shards": 1,
"active_shards": 4,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0,
"delayed_unassigned_shards": 0,
"number_of_pending_tasks": 0,
"number_of_in_flight_fetch": 0,
"task_max_waiting_in_queue_millis": 0,
"active_shards_percent_as_number": 100.0
}
- Отключите репликацию шардов, чтобы предотвратить создание реплик шардов, пока узлы отключаются. Это остановит перемещение сегментов индекса Lucene на узлах в вашем кластере. Вы можете отключить репликацию шардов, запросив конечную точку API _cluster/settings:
PUT "/_cluster/settings?pretty"
{
"persistent": {
"cluster.routing.allocation.enable": "primaries"
}
}
Ответ должен выглядеть примерно так:
{
"acknowledged": true,
"persistent": {
"cluster": {
"routing": {
"allocation": {
"enable": "primaries"
}
}
}
},
"transient": {}
}
- Выполните операцию сброса на кластере, чтобы зафиксировать записи журнала транзакций в индексе Lucene:
POST "/_flush?pretty"
Ответ должен выглядеть примерно так:
{
"_shards": {
"total": 4,
"successful": 4,
"failed": 0
}
}
Ознакомьтесь с вашим кластером и определите первый узел для обновления. Узлы, имеющие право на управление кластером, должны обновляться последними, поскольку узлы OpenSearch могут присоединиться к кластеру с управляющими узлами, работающими на более старой версии, но не могут присоединиться к кластеру, в котором все управляющие узлы работают на более новой версии.
Запросите конечную точку
_cat/nodes, чтобы определить, какой узел был повышен до управляющего узла кластера. Следующая команда включает дополнительные параметры запроса, которые запрашивают только имя, версию, роль узла и заголовки master. Обратите внимание, что версии OpenSearch 1.x используют термин “master”, который был устаревшим и заменен на “cluster_manager” в OpenSearch 2.x и более поздних версиях.
GET "/_cat/nodes?v&h=name,version,node.role,master" | column -t
Ответ должен выглядеть примерно так:
name version node.role master
os-node-01 7.10.2 dimr -
os-node-04 7.10.2 dimr -
os-node-03 7.10.2 dimr -
os-node-02 7.10.2 dimr *
Остановите узел, который вы обновляете. Не удаляйте объем, связанный с контейнером, когда вы удаляете контейнер. Новый контейнер OpenSearch будет использовать существующий объем. Удаление объема приведет к потере данных.
Подтвердите, что связанный узел был исключен из кластера, запросив конечную точку API
_cat/nodes:
GET "/_cat/nodes?v&h=name,version,node.role,master" | column -t
Ответ должен выглядеть примерно так:
name version node.role master
os-node-02 7.10.2 dimr *
os-node-04 7.10.2 dimr -
os-node-03 7.10.2 dimr -
Узел os-node-01 больше не отображается, потому что контейнер был остановлен и удален.
Разверните новый контейнер, работающий на желаемой версии OpenSearch и подключенный к тому же объему, что и удаленный контейнер.
Запросите конечную точку
_cat/nodesпосле того, как OpenSearch запустится на новом узле, чтобы подтвердить, что он присоединился к кластеру:
GET "/_cat/nodes?v&h=name,version,node.role,master" | column -t
Ответ должен выглядеть примерно так:
name version node.role master
os-node-02 7.10.2 dimr *
os-node-04 7.10.2 dimr -
os-node-01 7.10.2 dimr -
os-node-03 7.10.2 dimr -
В примере вывода новый узел OpenSearch сообщает о работающей версии 7.10.2 в кластер. Это результат compatibility.override_main_response_version, который используется при подключении к кластеру с устаревшими клиентами, проверяющими версию. Вы можете вручную подтвердить версию узла, вызвав конечную точку API /_nodes, как в следующей команде. Замените <nodeName> на имя вашего узла. См. раздел “API узлов”, чтобы узнать больше.
GET "/_nodes/<nodeName>?pretty=true" | jq -r '.nodes | .[] | "\(.name) v\(.version)"'
Подтвердите, что ответ выглядит примерно так:
os-node-01 v1.3.7
- Включите репликацию шардов снова:
PUT "/_cluster/settings?pretty"
{
"persistent": {
"cluster.routing.allocation.enable": "all"
}
}
Ответ должен выглядеть примерно так:
{
"acknowledged": true,
"persistent": {
"cluster": {
"routing": {
"allocation": {
"enable": "all"
}
}
}
},
"transient": {}
}
- Подтвердите, что кластер здоров:
GET "/_cluster/health?pretty"
Ответ должен выглядеть примерно так: