Vivliostyle CLI превращает рукописи Markdown, готовые HTML-страницы, манифесты веб-публикаций и EPUB в сверстанный PDF, а при подходящем исходнике также выпускает EPUB или WebPub. Пользователь управляет размером листа, полями, колонтитулами, нумерацией, оглавлением, обложкой, закладками, вылетами и метками реза через CSS и конфигурационный файл, проверяет результат в Vivliostyle Viewer и затем повторяет ту же сборку одной командой или в автоматическом процессе.
Рабочий процесс строится вокруг четырёх команд. create создаёт заготовку проекта, init формирует конфигурацию, preview открывает постраничное представление, а build записывает итоговый файл. Для короткой работы достаточно передать команде один HTML- или Markdown-файл; книга из нескольких глав описывается массивом entry, где задаются порядок, отдельные стили, служебные страницы и названия разделов.
Основной экран проверки — Viewer в браузерном окне: в нём видны развороты, границы листов, колонтитулы, переносы, ссылки и фактическое распределение текста по страницам. Изменения в исходниках и CSS удобно оценивать через повторную пагинацию, а режим --quick ускоряет открытие большой публикации ценой неточной предварительной нумерации, поэтому финальную проверку выполняют без этого ключа.
Скачать Vivliostyle CLI
- Редактирование PDF
- Русский интерфейс
- Просто новичкам
- Нужен Node.js
- Нет визуального редактора
- Нужно знать CSS
Как устроен рабочий процесс Vivliostyle CLI
Vivliostyle CLI не предлагает холст с объектами, панель шрифтов и мышиное перетаскивание блоков. Основой макета служит документная структура HTML или VFM — варианта Markdown, рассчитанного на книги, технические материалы и другие многостраничные публикации. Оформление задаётся CSS: обычные правила отвечают за абзацы, таблицы и изображения, а правила страничной верстки определяют формат листа, поля, колонтитулы, нумерацию и поведение разрывов. Такое разделение особенно полезно там, где одну и ту же рукопись нужно выпускать повторно после правок или собирать в нескольких форматах.
Минимальная сборка выглядит как vivliostyle build manuscript.md -o book.pdf. Если имя результата не указано, команда создаёт output.pdf для одиночного входа либо использует название публикации из конфигурации. Ключ -s A4 задаёт лист A4, --style print.css подключает авторскую таблицу стилей, а --theme применяет готовую тему. Параметры можно сочетать, однако для регулярно выпускаемого документа удобнее перенести их в vivliostyle.config.js: тогда одинаковая команда воспроизводит один и тот же порядок глав и набор выходных файлов.
Пагинация выполняется движком Vivliostyle Core, а печать PDF — управляемым браузером. Из-за этого результат ближе к веб-верстке, чем к классическому настольному издательскому макету: доступны HTML, современные селекторы и значительная часть CSS, но стабильность результата зависит от шрифтов, доступности ресурсов и версии используемого браузерного движка. Для воспроизводимой сборки в команде важно фиксировать зависимости, хранить шрифты вместе с проектом или в контролируемом окружении и не полагаться на случайные системные гарнитуры.
Создание проекта и выбор шаблона
Команда vivliostyle create my-book создаёт каталог публикации и задаёт основные параметры через интерактивные вопросы. Встроенные варианты Minimal, Basic, Documentation, Novel, Academic и Magazine отличаются назначением и объёмом начального содержимого: Minimal даёт простую основу, а остальные добавляют структуру и настройки для соответствующего типа издания. В мастере могут появляться и шаблоны, поставляемые выбранной темой. Это позволяет начать не с абстрактной пустой папки, а с файловой схемы, рассчитанной на конкретный жанр или оформление.
Шаблон можно указать без диалога: vivliostyle create manual --template minimal. Допускаются каталоги на диске и удалённые репозитории в формате, который понимает загрузчик шаблонов. Ссылка может включать подпапку и метку ветки или тега, поэтому организация способна хранить собственную утверждённую основу для инструкций, отчётов или учебных пособий. При копировании исключаются каталоги node_modules и .git, а двоичные файлы переносятся без текстовой обработки.
Текстовые файлы шаблона могут содержать переменные Handlebars. При создании проекта подставляются путь проекта, название, автор, языковой код, выбранная тема и сведения о ней. Это полезно не только для титульной страницы: переменные можно включить в package.json, конфигурацию, метаданные публикации и заготовки глав. Следует помнить, что обработка применяется к UTF-8-тексту; изображения, шрифты и другие двоичные ресурсы надо подготовить в окончательном виде заранее.
После генерации проекта стоит сразу проверить три места: массив entry, путь output и каталог ресурсов. Ошибка в порядке входов изменит последовательность страниц; относительный путь к картинке может оказаться корректным в редакторе, но недоступным в рабочем каталоге сборки; общий CSS может непреднамеренно затронуть обложку или оглавление. Первый запуск preview на ранней стадии быстрее выявляет эти проблемы, чем попытка разбирать уже собранный большой PDF.
Установка и подготовка среды
Команда устанавливается через npm: глобальный вариант npm install -g @vivliostyle/cli делает исполняемые имена vivliostyle и vs доступными во всех каталогах, а npm install @vivliostyle/cli добавляет зависимость только в текущий проект. Второй способ предпочтительнее для совместной работы и непрерывной интеграции: версия фиксируется в файле зависимостей, а запуск выполняется через npm-скрипт или npx, поэтому разные сотрудники получают одинаковый инструмент.
Для запуска нужен Node.js не ниже 22.12.0. Проверка node --version должна выполняться до установки, иначе ошибка может проявиться не на этапе npm, а при запуске с сообщением о неподдерживаемом синтаксисе. В Linux для распаковки загружаемого браузера требуется системная утилита unzip. Если первый запуск останавливается во время загрузки Chromium или Chrome, сначала проверяют свободное место, права на каталог кэша, наличие unzip и доступ к сети, а уже затем очищают неполный браузерный кэш и повторяют команду.
На Windows, macOS и Linux набор команд одинаков, но пути и оболочка различаются. В конфигурационном файле лучше применять относительные пути и функции Node.js для их построения, а не вставлять разделители, характерные только для одной системы. Названия файлов с пробелами передают в кавычках. В автоматическом задании рабочий каталог следует задавать явно: многие проблемы с не найденным CSS, изображением или шрифтом возникают не из-за движка, а из-за запуска из другой папки.
Для проекта полезен скрипт "build": "vivliostyle build" и отдельный "preview": "vivliostyle preview" в package.json. Тогда команды npm run build и npm run preview не зависят от глобальной установки. В репозитории хранят package.json и файл блокировки npm, pnpm или Yarn; каталог node_modules не включают в репозиторий. Такой подход также упрощает проверку чужой публикации: после установки зависимостей контролёр запускает тот же сценарий, который использовал автор.
Входные форматы и правила их выбора
Для одиночной статьи подходят HTML и Markdown. HTML даёт полный контроль над семантической разметкой, атрибутами, ARIA-ролями, ссылками и подключением стилей. Markdown быстрее для рукописи, но перед пагинацией преобразуется в HTML; итоговая структура зависит от VFM и его настроек. Когда важны сложные таблицы, нестандартные контейнеры или точные атрибуты, разумно либо вставлять допустимые HTML-фрагменты в Markdown, либо использовать собственный преобразователь и отдавать Vivliostyle готовый HTML.
EPUB можно открыть и превратить в PDF, указав файл .epub или распакованный OPF. Это удобно для печатной копии существующей электронной книги и проверки её CSS. Обратное преобразование ограничено: если входом служит EPUB или OPF, матрица форматов допускает PDF, но не формирование нового EPUB или WebPub. Для выпуска электронного пакета следует начинать с Markdown, HTML, webbook или манифеста публикации, чтобы CLI мог собрать ресурсы и структуру заново.
Манифест publication.json описывает чтение как упорядоченный набор ресурсов. Он подходит для многофайловой публикации, где оглавление, метаданные и последовательность уже представлены в стандартизованной форме. Формат webbook использует HTML, связанный с машинно-читаемым оглавлением или манифестом. В обоих случаях команда получает больше сведений о книге, чем из случайного набора HTML-файлов, поэтому корректнее формирует навигацию, закладки и электронные выходы.
Допускается входная веб-страница, но этот сценарий требует особой проверки. Страница может зависеть от авторизации, динамического JavaScript, сетевых шрифтов, относительных API-запросов или политики доступа к ресурсам. То, что она открывается в обычном браузере пользователя, не гарантирует успешную автоматическую печать. Для устойчивого результата лучше подготовить статическую версию, убедиться, что все нужные стили и изображения доступны без интерактивного входа, и проверить сборку в том же сетевом окружении, где будет работать автоматизация.
VFM: Markdown, приспособленный к книге
VFM сохраняет привычные заголовки, списки, ссылки, таблицы, код и изображения Markdown, но ориентируется на публикационную разметку. После преобразования элементы получают HTML-структуру, к которой применяются темы и пользовательский CSS. Это позволяет автору работать преимущественно с текстом, а дизайнеру — менять оформление без массовой правки глав. На практике важно сначала изучить HTML, который генерируется для конкретной конструкции, и только затем писать сложные селекторы: догадка о структуре часто приводит к правилам, которые не срабатывают.
Иллюстрации следует снабжать понятным альтернативным текстом и хранить в предсказуемом каталоге. Размер в PDF лучше задавать CSS, а не подгонять исходный файл вручную для каждой страницы. Для кода пригодны блочные ограждения с языком: тема может раскрашивать синтаксис, а правила white-space, overflow-wrap и размер шрифта предотвращают выход длинных строк за поле. Таблицы необходимо тестировать на реальной ширине листа; широкая веб-таблица редко помещается в книжный набор без сокращения столбцов, поворота страницы или специального стиля.
Для сносок и подписей надо применять конструкции, поддерживаемые VFM и выбранной темой, а не имитировать их вручную верхними индексами. Семантическая разметка даёт движку возможность правильно разместить примечание, связать маркер с текстом и сохранить порядок при переносах. Если тема меняет формат сносок, нужно проверить длинные примечания, несколько ссылок на одной строке и границу страницы: именно эти случаи выявляют переполнение области сносок или неожиданный перенос основного текста.
Метаданные главы можно читать программно через экспортируемые функции VFM и JavaScript API CLI. Это пригодно для конвейера, где заголовок, автор, дата или пользовательские поля определяют порядок и оформление. Однако метаданные не заменяют явную конфигурацию всей книги: глобальный язык, обложка, итоговые форматы, порядок входов и правила оглавления должны оставаться в одном контролируемом месте, иначе публикация станет зависеть от неочевидного содержимого отдельных файлов.
Конфигурационный файл без скрытых настроек
vivliostyle init создаёт vivliostyle.config.js. В модульном варианте удобно импортировать defineConfig из пакета: редактор получает проверку типов и подсказки, а ошибки в названиях полей обнаруживаются раньше. Допустим и vivliostyle.config.json в формате JSONC с комментариями. JavaScript-конфигурация гибче, потому что может читать каталог, строить массив заданий и вычислять пути; JSONC проще анализировать внешними средствами и безопаснее для среды, где выполнение произвольного кода нежелательно.
Поля title, author и language используются не только как справочная подпись. Название влияет на имя результата по умолчанию и метаданные, язык попадает в атрибут lang сгенерированного HTML, а корректный языковой код помогает переносам, озвучиванию и обработке текста. Для смешанного издания язык отдельных фрагментов отмечают уже в HTML. Нельзя рассчитывать, что один глобальный код автоматически распознает цитаты или главы на другом языке.
entry принимает строку, объект или массив. Объект позволяет задать path, собственный title, тему и служебную роль. Порядок элементов — это порядок чтения и страниц. Если входы лежат в отдельной папке, entryContext задаёт базу для разрешения путей. Это особенно важно при программной генерации массива: путь к главе может выглядеть верно относительно скрипта, но CLI будет искать его относительно другого каталога.
output тоже бывает строкой, объектом или массивом. В объекте указываются path и format, поэтому один запуск способен выпустить PDF, каталог WebPub и EPUB. У нескольких выходов общий исходник, но требования форматов различаются: печатные метки и фиксированный лист нужны PDF, а электронная книга должна корректно перестраиваться. Поэтому общий CSS следует дополнять медиавыражениями и проверять каждый результат отдельно, а не считать EPUB побочным пакетом уже готового печатного макета.
workspaceDir определяет место для промежуточных HTML и служебных файлов. Выделенная папка сохраняет исходный каталог чистым и упрощает удаление временных результатов. Одновременно она вводит границу рабочей области: ресурсы за её пределами могут оказаться недоступными, особенно в контейнере. Надёжная структура помещает рукопись, стили, изображения и шрифты под единый корень проекта либо явно копирует необходимые файлы перед сборкой.
Несколько заданий в одной конфигурации
Экспорт массива конфигураций превращает один файл в пакетный сценарий. Например, скрипт читает все Markdown-файлы каталога src, для каждого создаёт объект с отдельным названием, входом и PDF в каталоге output. Это подходит для набора сертификатов, карточек, отчётов по подразделениям или самостоятельных статей. Поскольку конфигурация является кодом, список можно фильтровать по имени, сортировать и дополнять метаданными из внешнего JSON.
Пакетная схема требует строгого контроля ошибок. Если один вход повреждён, необходимо понимать, остановится ли весь запуск и какие результаты успели записаться. В CI выходной каталог лучше очищать перед сборкой, а после команды проверять наличие ожидаемого количества файлов. Нельзя принимать старый PDF за свежий только потому, что он остался после предыдущего успешного запуска. Для важных публикаций дополнительно вычисляют хеши и сохраняют журнал команды, версии Node.js и зависимостей.
Предпросмотр в Vivliostyle Viewer
vivliostyle preview запускает сервер и открывает Viewer. В окне отображается не непрерывная веб-страница, а результат разбиения на листы: видны развороты, пустые страницы, поля, колонтитулы и расположение объектов относительно обрезного формата. Это основной инструмент проверки, потому что редактор кода показывает лишь структуру и CSS, но не знает, где конкретная строка вытеснит следующий абзац на новую страницу.
Проверку следует проводить от крупного к мелкому. Сначала оценивают последовательность обложки, титула, оглавления и глав; затем начало разделов на правой или левой странице; после этого — висячие строки, разрывы таблиц, подписи, сноски и ссылки. У длинной книги полезно составить перечень контрольных мест: первая страница каждой главы, самый большой рисунок, самая широкая таблица, страница с несколькими примечаниями, последний разворот и все намеренно пустые листы.
Ключ --quick ускоряет открытие публикации из многих документов за счёт приблизительной оценки количества страниц. Он подходит для проверки текста и стилей внутри одной главы, но номера в оглавлении, перекрёстные ссылки и расположение поздних разделов могут не совпасть с полной пагинацией. Перед выпуском необходимо открыть материал без ускоренного режима и дождаться завершения расчёта всех страниц. При создании PDF прогресс пагинации помогает отличить долгий расчёт от зависания.
Если изменение CSS не видно, сначала проверяют, действительно ли сохранён файл и подключается ли нужная таблица стилей. Затем исключают конфликт каскада, очищают ошибочный путь к теме и перезапускают предпросмотр. Локальная тема может обновляться через символическую ссылку, но npm-тема разрешается и кэшируется; при подозрении на старый вариант полезно проверить фактический пакет в рабочем каталоге и не смешивать одинаково названные глобальные и проектные зависимости.
Темы, авторские стили и каскад CSS
Тема Vivliostyle — это готовый пакет оформления, обычно опубликованный в npm или размещённый в каталоге проекта. Её указывают ключом -T, полем theme или путём к CSS. Если npm-пакета ещё нет в проекте, CLI может установить его в папку themes при первом запуске. Для неинтерактивной сборки важно заранее управлять этим поведением: неожиданный вопрос об установке блокирует CI, поэтому зависимости фиксируют заранее или применяют параметры, отключающие запросы.
--style additional.css добавляет авторскую таблицу после стилей документа. Обычный каскад позволяет ей переопределять правила с равной специфичностью. --user-style user.css подключает пользовательский уровень, который без !important не обязан побеждать авторский. Различие полезно: первый способ предназначен для оформления самой публикации, второй — для персональных или диагностических поправок, например увеличения шрифта при проверке.
--css принимает CSS-текст непосредственно в командной строке. Так удобно быстро проверить размер страницы, переменную темы или одно правило: --css "@page { size: A5; }". Для постоянной верстки длинная строка неудобна: кавычки зависят от оболочки, история команд становится трудно читаемой, а редактор не проверяет синтаксис. После эксперимента правило лучше перенести в файл и добавить в систему контроля версий.
Тему следует считать начальной системой, а не неизменяемым шаблоном. Проектный CSS может переопределить гарнитуру, интервалы, оформление заголовков и правила страниц. Чтобы обновление темы не разрушило макет, избегают чрезмерно хрупких селекторов по внутренней структуре и проверяют каскад на небольшом контрольном документе. Если приходится использовать много !important, полезнее пересмотреть порядок подключений и специфичность, чем наращивать конфликтующие исключения.
Размер листа, поля, вылеты и метки реза
Ключ -s или --size понимает A5, A4, A3, B5, B4, JIS-B5, JIS-B4, letter, legal и ledger. Произвольный формат задаётся парой размеров через запятую, например 10in,7.5in. Внутренне это эквивалентно правилу @page { size: ...; }. Для книги формат лучше хранить в CSS или конфигурации, чтобы он не потерялся при ручном запуске другой команды.
Поля задаются в @page, а не через margin у body. Поле страницы резервирует пространство между областью набора и краем листа и содержит margin boxes для колонтитулов. Отступ у body изменяет поток документа и может вести себя иначе на первой и последующих страницах. Для зеркальных полей применяют псевдоклассы :left и :right, а для первой страницы главы — именованные страницы или :first в подходящем контексте.
-m или --crop-marks добавляет метки реза и кресты. --bleed 3mm задаёт вылет, а --crop-offset — расстояние до меток. Наличие ключа не делает макет автоматически готовым к типографии: фон или изображение должны действительно доходить до области вылета, важный текст — оставаться внутри безопасной зоны, а размер страницы и требования к цвету — совпадать с техническим заданием печати.
При проверке меток важно различать MediaBox, TrimBox и область содержимого. Обычный просмотрщик может показывать лист целиком, тогда как типография ориентируется на обрезной формат. Контрольный PDF следует открыть средством, которое умеет показывать боксы, или проверить его препресс-профилем. Ошибка в миллиметрах часто незаметна на экране, но проявляется после резки как белая полоска или слишком близкий к краю текст.
Правила @page и области колонтитулов
CSS Paged Media предоставляет шестнадцать основных областей по краям листа: угловые, верхние, нижние и боковые margin boxes. В них помещают номер, название главы, название книги или декоративный элемент через свойство content. Например, @bottom-center { content: counter(page); } выводит текущий номер внизу. Само наличие счётчика не гарантирует правильную нумерацию служебных листов: обложка, титул и оглавление могут требовать отдельной последовательности или скрытого отображения.
Для бегущего заголовка текст заголовка захватывают функцией string-set, а в области страницы выводят string(). Правило назначается элементу главы, поэтому значение меняется, когда движок встречает следующий заголовок. Нужно определить, использовать первое или последнее значение на странице и что показывать до первого заголовка. На странице начала главы колонтитул часто скрывают отдельным правилом, чтобы он не дублировал крупный заголовок.
Счётчики CSS пригодны не только для страниц. Ими нумеруют главы, рисунки, таблицы и примеры, а target-counter() подставляет номер страницы элемента по ссылке. Так формируются строки оглавления и указатели без ручного обновления. Для работы у цели должен быть устойчивый идентификатор, а ссылка — корректный фрагмент. Если номер отсутствует, прежде всего проверяют id, адрес href и то, включён ли целевой документ в одну публикацию.
Разрывы регулируются свойствами break-before, break-after и break-inside. Жёсткий запрет разрыва у большого блока может создать огромную пустую область или привести к переполнению, если блок выше страницы. Поэтому break-inside: avoid применяют к небольшим связанным элементам — подписи с рисунком, короткой таблице, карточке — и обязательно тестируют крайний размер. Для главы используют осмысленный разрыв на правую или левую страницу, учитывая, что движок может вставить пустой лист.
Оглавление, номера страниц и навигация
Поле toc: true генерирует index.html с заголовком публикации и элементом nav role="doc-toc". В простейшем варианте список содержит по одному пункту на каждый вход. Объект toc позволяет изменить имя HTML-файла, текст заголовка и sectionDepth от 1 до 6. Последний параметр включает внутренние заголовки глав; слишком большая глубина делает оглавление громоздким, поэтому для книги обычно выбирают уровень, соответствующий реальной навигационной структуре.
Служебный объект { rel: 'contents' } в массиве entry помещает оглавление в нужную позицию, например после титула. Если требуется полностью собственная разметка, создают HTML-шаблон с пустым nav role="doc-toc", задают его как вход с ролью contents и указывают итоговое имя. CLI вставит пункты в отмеченный контейнер, а автор сохранит контроль над вступительным текстом, классами и декоративной структурой.
Печатные номера в строках оглавления обычно строятся CSS через целевые счётчики. Их правильность зависит от полной пагинации, поэтому быстрый предпросмотр не является окончательной проверкой. После изменения шрифта, межстрочного интервала, иллюстрации или размера страницы номера могут сдвинуться во всей книге. Ручные цифры в Markdown недопустимы: они сразу устаревают и не отражают автоматически вставленные пустые страницы.
PDF-закладки — отдельная навигационная структура, хотя часто повторяют заголовки и оглавление. CLI умеет формировать их при выводе PDF; итог следует проверить в панели закладок нескольких просмотрщиков. Чрезмерно глубокая иерархия неудобна, а одинаковые заголовки без контекста затрудняют переход. Если служебный заголовок не должен становиться закладкой, лучше изменить семантику или правила генерации, а не прятать текст только визуально.
Обложка и служебные страницы
Поле cover: 'image.png' создаёт cover.html и помещает изображение на страницу без полей. В объектной форме задаются src, htmlPath и доступное название. Если htmlPath равно false, обложка не включается как страница PDF, но может использоваться как изображение обложки в EPUB или WebPub. Это важное различие: электронная обложка является метаданным и ресурсом пакета, а печатная — реальной страницей последовательности.
Позиция задаётся объектом { rel: 'cover' } в entry. Допускаются передняя и задняя обложки с разными файлами и выходными именами. Для нестандартной композиции готовят HTML-шаблон с img role="doc-cover", куда CLI подставляет изображение. Шаблон полезен, когда на обложке должны быть текстовые элементы, фон и несколько слоёв, однако для типографского макета нужно отдельно проверить вылет, цвет и качество растров.
Титульный лист, оборот титула, аннотация, выходные сведения и колофон обычно оформляются обычными входами, а не специальными полями. Каждой странице можно назначить собственную тему или именованную страницу CSS. Так общая тема книги не добавит номер на обложку и не применит красную строку к юридическому блоку. Порядок служебных листов остаётся явно виден в entry, что облегчает рецензирование.
Изображение обложки не следует растягивать без контроля соотношения сторон. Сгенерированный шаблон применяет object-fit: contain, поэтому вокруг картинки могут появиться пустые полосы, если пропорции не совпадают с листом. Для печати чаще готовят файл точно в пропорции страницы с учётом вылета или используют собственный HTML/CSS. Для EPUB проверяют, что файл имеет разумный размер и корректно отображается не только в PDF-просмотрщике.
Таблицы, изображения, код и сложные блоки
Таблица в многостраничном документе должна оставаться читаемой после разбиения. Заголовок thead можно повторять на следующих страницах, но строка с большим количеством текста всё равно способна занять почти весь лист. Запрет разрыва каждой строки иногда ухудшает ситуацию. Практичнее сокращать содержимое, задавать ширины столбцов, перенос длинных слов и проверять, как движок ведёт себя с объединёнными ячейками. Для принципиально широкой таблицы используют альбомную именованную страницу или выносят данные в приложение.
Растровое изображение должно иметь достаточное число пикселей для физического размера в PDF. CSS-ширина 150 мм не добавит деталей исходнику шириной 600 пикселей. С другой стороны, многомегапиксельные фотографии замедляют пагинацию и раздувают результат. Перед сборкой изображения приводят к разумному разрешению, удаляют ненужные метаданные и выбирают формат: JPEG для фотографий, PNG для схем с резкими границами и прозрачностью, SVG для векторных диаграмм при корректной поддержке используемых возможностей.
Подпись рекомендуется связывать с рисунком через figure и figcaption. Нумерация строится счётчиком, а ссылка в тексте — через идентификатор. Если картинка переносится, правила должны сохранять подпись рядом, но не запрещать разрыв огромной фигуры любой ценой. Полностраничные иллюстрации лучше оформлять отдельным типом страницы или page float, чем пытаться удержать их внутри обычного абзацного потока.
Код требует моноширинной гарнитуры с нужными символами. Длинные строки можно переносить, уменьшать или выводить на более широком листе, но горизонтальная прокрутка из веб-интерфейса в PDF бессмысленна. Подсветка синтаксиса должна сохранять контраст при печати в градациях серого. Для команд, которые читатель будет копировать, важно не вставлять декоративные псевдоэлементы внутрь выделяемого текста.
Шрифты и воспроизводимость верстки
Шрифт меняет не только внешний вид, но и количество строк, переносы, высоту заголовков и номера страниц. Если на компьютере автора доступна гарнитура, которой нет на сервере, браузер подставит замену и вся пагинация сдвинется. Надёжный проект подключает разрешённые для встраивания файлы через @font-face, хранит их в контролируемом каталоге и использует конкретные семейства и начертания. После сборки проверяют, что PDF действительно содержит нужные шрифты, а не только похожий системный вариант.
Для кириллицы, латиницы, японского текста, математических символов и эмодзи может потребоваться несколько семейств. CSS-стек задают осознанно, потому что подстановка отдельного символа из другой гарнитуры способна отличаться по высоте и толщине. В технической книге особенно проверяют знаки кода, стрелки, греческие буквы и неразрывные пробелы. Пустой квадрат в PDF обычно означает отсутствие глифа, а не ошибку конвертации Markdown.
В контейнере видны только шрифты, встроенные в образ или смонтированные в него. Ссылка на путь из домашнего каталога хоста там не работает. Для проекта с закрытыми корпоративными гарнитурами образ собирают внутри организации либо монтируют каталог при запуске с учётом лицензии. Для публичной автоматизации проще применять свободно распространяемые шрифты и включать их в репозиторий или артефакт сборки.
Сетевые шрифты удобны для сайта, но рискованны для тиражной сборки: доступ может исчезнуть, ответ задержаться или измениться файл под тем же адресом. Если публикация должна воспроизводиться спустя месяцы, ресурсы фиксируют локально и записывают их хеши. После любого обновления шрифта выполняют полную пагинацию и сравнивают ключевые страницы, даже если название семейства и визуальный стиль не изменились.
PDF, закладки, ссылки и метаданные
PDF создаётся командой build с форматом pdf или расширением .pdf. Внутренние HTML-ссылки и якоря должны превращаться в переходы по документу, а внешние — сохраняться как адреса, если политика выпуска это допускает. Перед передачей файла проверяют ссылки после объединения нескольких глав: относительный адрес, работавший в отдельном HTML, может указывать не на тот итоговый ресурс или потерять цель после преобразования Markdown.
Название, автор и язык из конфигурации используются при формировании публикации, но набор PDF-метаданных стоит проверить отдельным анализатором. Особенно это важно для долговременных хранилищ и библиотек, где имя файла не считается достаточным описанием. Неправильная кодировка автора или пустой заголовок не видны на странице, но появляются в свойствах документа и поисковых системах.
Размер файла зависит от растров, шрифтов и постобработки. CLI не является универсальным оптимизатором готовых PDF: если результат слишком велик, сначала анализируют ресурсы, а не пытаются снизить качество всей страницы. Повторяющиеся изображения должны переиспользоваться, фотографии — иметь подходящее сжатие, а огромные SVG — не содержать скрытые слои. После любой внешней оптимизации заново проверяют ссылки, закладки, прозрачность, цвет и читаемость мелкого текста.
Интерактивные PDF-формы, редактирование существующих страниц, OCR, цифровая подпись и ручное комментирование не относятся к рабочему процессу Vivliostyle CLI. Мастер изменяют в HTML, Markdown или данных и собирают документ снова. Если задача состоит в исправлении одной опечатки внутри чужого готового PDF без исходников, быстрее использовать редактор PDF; попытка восстановить всю верстку в HTML оправдана только при последующих регулярных выпусках.
EPUB и WebPub из общего проекта
Формат вывода выбирается -f epub, -f webpub либо расширением пути результата. EPUB упаковывает ресурсы и навигацию в файл, WebPub создаёт веб-публикацию в каталоге. Один массив output может включать оба варианта вместе с PDF. Это не означает, что одно оформление автоматически оптимально везде: фиксированные поля, метки реза и бегущие колонтитулы относятся к печати, а электронный текст должен свободно менять ширину и размер шрифта.
Для электронного выпуска важны порядок чтения, альтернативный текст, семантические заголовки, язык и машинно-читаемое оглавление. Визуально красивый PDF может скрывать плохую структуру, потому что читатель видит страницы; EPUB-ридер и вспомогательные технологии зависят от DOM. Поэтому HTML следует строить семантически до оформления, а не исправлять доступность в конце одними CSS-правилами.
Обложка может включаться в электронный пакет без отдельной страницы PDF через настройку htmlPath: false. Это позволяет не дублировать изображение в потоке чтения, но требует проверки метаданных и отображения в нескольких ридерах. WebPub удобен для размещения набора HTML и ресурсов на сервере, однако относительные пути, MIME-типы и регистр имён должны быть корректными в целевой файловой системе.
Входной EPUB предназначен для печати в PDF и не служит основой для пересборки EPUB или WebPub. Если нужен полноценный цикл один мастер — несколько выходов, хранить мастер следует в Markdown, HTML или манифесте публикации. Тогда исправления не зависят от распаковки чужого электронного пакета, а все форматы получают одинаковую структуру из контролируемых файлов.
Печатный PDF и подготовка PDF/X-1a
Специальная постобработка может формировать печатный PDF профиля PDF/X-1a. Такой сценарий рассчитан на типографию: цвета приводятся к допустимому пространству, шрифты должны быть встроены, а прозрачность и другие элементы проверяются на соответствие профилю. Включение опции не заменяет технического задания печатника. Сначала согласуют ICC-профиль, максимальную сумму красок, формат, вылеты и требования к чёрному тексту.
Для этой постобработки используется контейнерное окружение. Проект и все нужные ресурсы должны быть доступны внутри него; абсолютный путь к файлу на хосте не станет виден автоматически. Перед запуском проверяют монтирование рабочего каталога, наличие шрифтов и права на запись результата. Проблема в обычном PDF всё есть, а в печатном пропало часто указывает на разницу окружений, а не на CSS.
Цвет device-cmyk() и карта преобразования RGB в CMYK позволяют точнее управлять печатными цветами, но требуют профессионального контроля. Экранное значение RGB не имеет единственного универсального эквивалента CMYK. Для фирменного цвета задают утверждённое значение и проверяют пробу; фотографии конвертируют с подходящим профилем; мелкий чёрный текст обычно оставляют однокрасочным, чтобы избежать несовмещения.
После создания PDF/X файл проверяют валидатором профиля и префлайтом типографии. Отдельно просматривают обрезные боксы, метки, вылеты, встраивание шрифтов, разрешение изображений и неожиданные прозрачности. Визуальное совпадение с обычным PDF недостаточно: профиль содержит машинно проверяемые ограничения, а цветопреобразование способно изменить оттенки без изменения геометрии страницы.
Интеграция с Vite и фронтенд-проектами
Vivliostyle CLI умеет работать с Vite и предоставляет адаптер для проекта, где HTML формируется фронтенд-сборкой. Это полезно, когда публикация разделяет компоненты, данные и стили с веб-приложением. Сначала Vite подготавливает страницы и ресурсы, затем Vivliostyle выполняет пагинацию. В таком конвейере важно различать адреса разработки и статический результат: ссылка, доступная только через dev server, не обязательно существует в итоговом каталоге.
Базовый путь, каталог ассетов и маршрутизация должны поддерживать прямое открытие нужной страницы. Одностраничное приложение, которое рисует всё после сложной авторизации, хуже подходит для воспроизводимого PDF, чем предварительно сгенерированный HTML. Асинхронные данные следует загрузить до печати и предоставить явный признак готовности; иначе браузер начнёт пагинацию, пока таблица или график ещё пусты.
JavaScript может подготовить содержимое, но печатный макет не должен зависеть от непредсказуемой анимации, размера окна или пользовательского клика. Отключают переходы, фиксируют состояние раскрывающихся блоков и обеспечивают одинаковый DOM при повторном запуске. Данные сортируют явно: порядок ответа API или обход свойств не должен менять страницы между двумя сборками.
Ресурсы, выдаваемые Vite, могут получать хешированные имена. Это нормально, если HTML ссылается на правильный манифест и весь каталог передан в рабочую область. Ошибки 404 в Viewer обычно означают, что базовый URL, assetsDir или относительный путь рассчитаны для сайта, а не для публикации. Диагностику начинают с сетевой панели браузера и журнала сервера, а не с изменения CSS.
JavaScript API и программная сборка
Пакет экспортирует функции для создания, сборки и предпросмотра, а также defineConfig, VFM и вспомогательные средства. API подходит, когда команда должна быть частью приложения Node.js: данные получают из базы, генерируют входы, запускают сборку и передают PDF в хранилище. При этом надо обрабатывать отклонённые Promise, корректно завершать браузер и удалять временные каталоги; простое подавление ошибки способно оставить процессы и заблокировать следующий запуск.
Программный вызов не отменяет конфигурационную модель. Удобно хранить базовые параметры в типизированном объекте, а на каждый заказ добавлять название, вход и выход. Входные данные необходимо проверять до передачи в шаблон: недоверенный HTML или CSS может обращаться к сети и файлам, создавать тяжёлую верстку или включать нежелательное содержимое. Сервис генерации документов должен ограничивать ресурсы, время и доступные пути.
Адаптер Vite позволяет включить пагинацию в существующий процесс разработки, а экспорт VFM предотвращает несовпадение версий преобразователя и CLI. Если приложение отдельно устанавливает другой выпуск VFM, получившийся HTML может отличаться от ожидаемого движком. Использование реэкспортируемой функции и единого файла блокировки снижает риск, что локальная и серверная сборки по-разному интерпретируют одну Markdown-конструкцию.
Для тестирования полезно иметь маленькие эталонные входы: страницу с колонтитулами, оглавление с целевыми номерами, таблицу через разрыв, длинную сноску и изображение с подписью. Тест может проверять успешное завершение, число страниц и наличие текста или закладок. Побитовое сравнение PDF слишком строго: метаданные или внутренний порядок объектов могут меняться без визуальной разницы, поэтому геометрию и содержание проверяют специализированными средствами.
Автоматизация, CI и контейнер
В CI выполняют установку по файлу блокировки, затем команду сборки из проекта. Кэш зависимостей и браузера ускоряет повторные задания, но его ключ должен учитывать платформу, версию Node.js и файл блокировки. Повреждённый или несовместимый кэш проявляется как ошибка запуска браузера; в таком случае безопаснее удалить его, чем бесконечно повторять команду. Итоговый PDF, EPUB или каталог WebPub публикуют как артефакт только после проверок.
Официальный контейнер удобен для одинаковой среды на рабочей станции и сервере. В нём уже подготовлены зависимости браузера, но проект надо смонтировать, рабочий каталог — выбрать, а UID и права — согласовать с хостом. Иначе результат создастся владельцем root или команда не сможет записать файл. Шрифты и системные библиотеки также являются частью образа; изменение тега образа следует рассматривать как изменение версточной среды и сопровождать повторной проверкой страниц.
Для воспроизводимости фиксируют версию npm-пакета и контейнерный digest, а не только плавающий тег. В журнал сборки записывают команду, commit исходников и хеш результата. Если PDF выпускается по расписанию, входные данные тоже сохраняют или версионируют. Без этого невозможно объяснить, почему документ, собранный повторно через месяц, имеет другие страницы при неизменном Markdown.
Параллельная сборка нескольких больших книг потребляет память и процессы браузера. Ограничение конкуренции часто эффективнее увеличения тайм-аута. Каждый job должен иметь собственный рабочий каталог и выходной путь, иначе промежуточные файлы и кэш темы пересекаются. При отмене задания процессу дают время завершить очистку; принудительное убийство всей группы может оставить частичный PDF, который нельзя публиковать как успешный артефакт.
Диагностика типичных ошибок
Команда не запускается после установки
Сначала выполняют node --version и npm --version. Node.js ниже 22.12.0 не соответствует требованиям. Затем проверяют, где установлен пакет: глобальная установка требует, чтобы каталог npm binaries входил в PATH; проектная запускается через npx vivliostyle или npm-скрипт. Если оболочка находит старую глобальную копию раньше проектной, сравнивают vivliostyle --version и путь команды.
Браузер не скачивается или не распаковывается
Проверяют соединение, прокси, сертификаты и место на диске. На Linux требуется unzip. После оборванной загрузки в кэше может остаться неполный каталог; его удаляют только после остановки всех процессов и затем повторяют установку браузера. В корпоративной сети адрес загрузки может блокироваться, поэтому кэш подготавливают в разрешённом окружении или применяют контейнер, прошедший внутреннюю проверку.
Изображение или CSS не найден
Относительный путь вычисляется от конкретного HTML или рабочего контекста, а не обязательно от файла конфигурации. Открывают сгенерированный HTML в workspaceDir, смотрят фактический src или href и проверяют существование файла с учётом регистра. В Linux Cover.png и cover.png различаются. В контейнере ресурс должен находиться внутри смонтированного дерева.
Предпросмотр и PDF отличаются
Убеждаются, что предпросмотр выполнен без --quick, использует те же параметры, тему и вход. Проверяют шрифты и загрузку сетевых ресурсов. Если PDF строится в контейнере, а Viewer открыт на хосте, среды почти наверняка отличаются. Сравнение начинают с вычисленного CSS и списка шрифтов, затем проверяют размеры страницы и только после этого ищут ошибку в движке.
Номера в оглавлении пусты или неверны
Проверяют уникальность идентификаторов заголовков, корректность ссылок и включение всех целевых файлов в одну публикацию. Затем выполняют полную пагинацию. Ручной шаблон оглавления должен содержать nav role="doc-toc", если пункты вставляет CLI. Слишком ранняя генерация номера средствами JavaScript не знает окончательных страниц; для печатных ссылок применяют целевые счётчики CSS.
Текст выходит за страницу
Чаще всего виноваты длинный URL, код без переносов, таблица с фиксированной шириной или элемент с white-space: nowrap. Временно добавляют контур всем блокам и находят фактический переполняющий узел. Затем задают overflow-wrap, разрешают перенос, уменьшают только проблемный тип содержимого или меняют страницу на альбомную. Глобальное уменьшение шрифта маскирует причину и ухудшает весь документ.
Сборка зависает на сложной странице
Изолируют вход, сокращая публикацию до проблемной главы, затем удаляют по половине содержимого. Бесконечную или очень долгую раскладку могут вызывать конфликтующие правила разрыва, чрезмерно большой неразрывный блок, тяжёлый SVG, рекурсивный скрипт или ресурс без тайм-аута. После исправления тестируют соседние страницы: снятие одного запрета разрыва иногда переносит проблему дальше, не устраняя её.
Практические сценарии
Книга из Markdown-глав
Каждая глава хранится отдельным VFM-файлом, общий CSS задаёт набор и страницы, а entry фиксирует порядок. toc строит оглавление, cover добавляет обложку, output создаёт PDF и EPUB. Автор работает с чистым текстом, редактор проверяет diff, дизайнер меняет тему, а выпуск повторяется без ручной переклейки страниц. Критические проверки — начало глав, сноски, иллюстрации, целевые номера и электронная навигация.
Техническая документация
HTML или Markdown генерируется из репозитория продукта, примеры кода подсвечиваются, а Vite может собирать компоненты и ассеты. Один и тот же материал публикуется как сайт и как PDF. Для печати добавляются формат листа, колонтитулы и разрывы перед разделами, но DOM остаётся семантическим. Основная трудность — не допустить, чтобы интерактивные виджеты сайта попали в документ пустыми; для каждого компонента нужна печатная форма.
Отчёты из данных
Node.js-скрипт получает проверенные данные, создаёт HTML-таблицы и графики, затем вызывает API сборки. Конфигурация формирует отдельный PDF для клиента или периода. Шаблон должен выдерживать нулевые значения, длинные названия, много строк и отсутствие изображения. Для аудита сохраняют входной JSON, commit шаблона и хеш PDF; иначе невозможно воспроизвести конкретный отчёт после изменения данных.
Учебное пособие с несколькими выходами
Печатный PDF использует фиксированный лист и поля для заметок, EPUB — перестраиваемый текст, WebPub — материалы для размещения. Общие правила отвечают за типографику и семантику, а @media print и форматные настройки скрывают или заменяют элементы, не подходящие конкретному выходу. Видео и интерактивные упражнения в PDF получают статическую подпись или QR-код, но электронная версия сохраняет доступную ссылку.
Японская вертикальная верстка
CSS задаёт writing-mode, направление страниц, гарнитуры и правила пунктуации. Проверяют положение руби, знаков переноса, латинских вставок, боковых колонтитулов и иллюстраций. Готовая японская тема ускоряет старт, но не освобождает от проверки конкретного текста. Особое внимание уделяют шрифтам: отсутствие нужных вертикальных форм или подстановка другой гарнитуры заметно меняет строку и страницу.
Поддерживаемые возможности CSS и метод проверки
Vivliostyle реализует большой набор свойств обычной веб-верстки и модулей, связанных с фрагментацией, Generated Content for Paged Media и страничными носителями. На практике это означает поддержку селекторов, каскада, flex- и grid-компоновки в подходящих задачах, многостолбочного текста, счётчиков, строковых значений для колонтитулов, целевых ссылок и правил страницы. Однако печатная фрагментация меняет поведение элементов: блок, который безупречно выглядит в окне сайта, может пересекать границу страницы, создавать нежелательную пустоту или требовать отдельного правила для продолжения.
Надёжный способ проверить редкую возможность — создать минимальный HTML с одним эффектом и собрать его тем же окружением, что и основную публикацию. В тест включают как нормальный пример, так и крайний: длинный заголовок, два последовательных разрыва, объект выше доступной области, вложенный список, пустой блок. Если свойство работает только на коротком демонстрационном тексте, оно ещё не пригодно для книги. Минимальные тесты полезно хранить рядом с темой и повторять после обновления зависимостей.
Для сеток и flex-контейнеров особое внимание уделяют фрагментации дочерних элементов. Сложная панель карточек может хорошо размещаться на одной странице, но не иметь очевидного поведения при переносе. Иногда проще преобразовать печатную версию в обычный блочный поток через @media print, чем заставлять интерактивную сетку делиться между листами. То же относится к липким позициям, фиксированным панелям и элементам, смысл которых связан с прокруткой: в PDF их заменяют статической структурой.
Свойства с префиксом Vivliostyle и экспериментальные возможности применяют только после проверки документации и контрольного файла. Они способны решить задачу, которой ещё нет в стабильном стандарте, но повышают зависимость темы от конкретного движка. Если публикация должна одновременно печататься другим форматтером или обычным браузером, нестандартное правило помещают в отдельный слой и предусматривают понятное резервное оформление.
Сноски, плавающие объекты и фрагментация
Сноска состоит из маркера в основном тексте, содержимого примечания и области внизу страницы. Движок должен перенести часть основного текста, если примечания занимают слишком много места, и сохранить связь маркера с содержимым. Поэтому сноски проверяют не по одному короткому примеру, а в комбинациях: несколько маркеров в одном абзаце, длинное примечание, ссылка внутри примечания, граница главы и страница с рисунком. Ошибка обычно проявляется как слишком большая пустота, неожиданное продолжение или наложение на колонтитул.
Плавающие объекты позволяют вынести иллюстрацию или примечание к верхнему, нижнему либо боковому краю страницы. Они полезны в учебниках и журналах, где изображение не обязано стоять точно в месте ссылки, но должно оставаться поблизости. Чем больше независимых float-объектов, тем сложнее выбор позиции. Следует ограничивать их размеры, задавать приоритеты и проверять последовательность, иначе несколько крупных рисунков вытеснят текст или соберутся на отдельной странице.
Page float отличается от обычного float: left в веб-странице: его размещение учитывает границы листа и доступные области. Для критической иллюстрации полезно иметь резервное правило, допускающее обычное положение в потоке. Если float не помещается в желаемую область, жёсткая комбинация ограничений может задержать его на много страниц. Читатель тогда увидит ссылку задолго до самого рисунка. Контрольный текст должен содержать последовательность из нескольких объектов, а не один идеальный пример.
Свойства widows и orphans помогают избегать одиночных строк абзаца на границе, но их завышенные значения создают большие пробелы. Правило break-inside: avoid не следует назначать каждому абзацу, списку и таблице одновременно. Страничная верстка — это компромисс: движку нужна свобода переносить содержимое. Лучше определить небольшое число действительно неделимых конструкций и разрешить обычному тексту фрагментироваться естественно.
Доступность и семантика публикации
Правильная структура HTML важна даже тогда, когда главным результатом считается печатный PDF. Заголовки должны идти в логическом порядке, списки — оставаться списками, таблицы — иметь заголовочные ячейки, а изображения — альтернативный текст. CSS может визуально сделать любой div похожим на заголовок, но оглавление, закладки, EPUB-ридер и вспомогательные технологии не получат нужной информации. Семантику исправляют в разметке, а не декоративным псевдоэлементом.
Альтернативное описание не должно повторять подпись слово в слово, если подпись уже доступна рядом. Для чисто декоративного изображения задают пустое описание и исключают его из смыслового потока. Диаграмма требует передачи вывода или ключевых значений в тексте. Эти решения важны для EPUB и WebPub и одновременно улучшают сопровождение: автор понимает назначение ресурса, даже когда файл временно не загружается.
Цвет нельзя использовать как единственный способ различать предупреждение, успешный результат или серию на графике. Печатная копия может быть чёрно-белой, а читатель — иметь нарушение цветового восприятия. Добавляют текстовую метку, форму линии или значок с доступным названием. Контраст проверяют для обычного текста, ссылок, кода и серых подписей; слишком светлая веб-палитра на бумаге становится ещё менее читаемой.
Язык задаётся для публикации и меняется атрибутом lang в фрагментах с другим языком. Это влияет на переносы, произношение и выбор шрифта. Ссылки должны иметь осмысленный текст, а не повторять длинный адрес; в печатной версии при необходимости добавляют короткое понятное обозначение. Поскольку Vivliostyle CLI не исправляет семантику автоматически, проверка исходного HTML должна быть частью редакционного процесса до пагинации.
Безопасная обработка чужих документов
HTML, CSS и JavaScript способны обращаться к сети и локальным ресурсам в пределах разрешений процесса. Поэтому нельзя без ограничений принимать чужой пакет и запускать его в среде, где доступны секреты, домашний каталог или внутренние сервисы. Для сервера генерации используют отдельного непривилегированного пользователя, изолированный рабочий каталог, контейнер, сетевые ограничения и лимит времени. Результат не считается безопасным только потому, что на выходе ожидается PDF.
Пути из входных данных нормализуют и проверяют, чтобы конструкция с переходом к родительскому каталогу не прочитала файл за пределами проекта. Символические ссылки также могут вывести из рабочей области. Загружаемые шрифты, изображения, SVG и EPUB анализируют по реальному формату, а не только по расширению. Пакет распаковывают с ограничением общего размера и количества файлов, чтобы маленький вход не превратился в гигантский набор данных.
Сетевые запросы делают сборку недетерминированной и создают канал доступа к внутренним адресам. В доверенном проекте их стараются заменить зафиксированными ресурсами. В публичном сервисе разрешают только заранее определённые домены либо полностью отключают исходящую сеть. Удалённый сервер может вернуть другой файл, задержать ответ или вести себя по-разному в зависимости от заголовков; итоговая страница тогда меняется без правки репозитория.
Конфигурация JavaScript является исполняемым кодом. Внутри собственной команды это удобно, но файл от неизвестного автора нельзя воспринимать как пассивный JSON. Для недоверенных заданий применяют ограниченную декларативную схему, самостоятельно создают конфигурационный объект и не исполняют присланный модуль. Журналы также очищают от токенов, путей с персональными данными и содержимого закрытых документов.
Совместная работа и контроль изменений
Текстовая природа проекта делает рецензирование точнее, чем обмен последовательностью двоичных PDF. В pull request видно изменение абзаца, CSS-правила, порядка глав и метаданных. Но одного diff недостаточно: небольшая правка шрифта может изменить сотни страниц. Поэтому к значимому изменению прикладывают собранный артефакт или набор снимков контрольных страниц, а автоматическая проверка убеждается, что команда завершилась без ошибок.
Структуру репозитория лучше сделать очевидной: исходники в одном каталоге, изображения в другом, стили и темы отдельно, конфигурация в корне, результаты вне дерева исходников. Имена файлов выбирают устойчивыми и без зависимости от номера страницы. Если глава переезжает, её ссылки и идентификаторы не должны массово ломаться. Служебные HTML, созданные в workspaceDir, не смешивают с рукописью и обычно не редактируют вручную.
Ответственность можно разделить: автор меняет Markdown, редактор проверяет содержание и структуру, дизайнер сопровождает тему, выпускающий отвечает за конфигурацию и префлайт. При этом все участники должны понимать, какие изменения влияют на пагинацию. Например, редакторская замена одного термина на более длинный способна сдвинуть рисунок и оглавление, поэтому только текстовая правка всё равно проходит визуальный контроль перед выпуском.
Конфликты в сгенерированных файлах не стоит разрешать вручную, если их можно пересоздать. В системе контроля версий хранят мастер и параметры, а PDF публикуют как релизный артефакт. Исключение — утверждённый эталон для сравнения; его помещают отдельно и обновляют осознанно. Такой порядок исключает ситуацию, когда в репозитории лежит PDF, не соответствующий текущему Markdown.
Оптимизация скорости большой сборки
Время уходит на преобразование входов, загрузку ресурсов, выполнение скриптов, пагинацию и печать. Сначала измеряют этап, а не уменьшают качество вслепую. Если задержка связана с удалёнными картинками и шрифтами, их фиксируют рядом с проектом. Если долго рассчитывается одна глава, изолируют сложные таблицы, SVG, многостолбочные блоки и цепочки float-объектов. Если узкое место — запуск браузера, пакетные задания организуют так, чтобы избежать лишних повторных инициализаций в рамках поддерживаемого API.
Режим --quick предназначен для интерактивного просмотра, а не для ускорения финального PDF. Его приблизительные номера не подходят для контроля оглавления. Гораздо полезнее во время редактирования открывать отдельную главу или небольшой тестовый манифест, сохраняя полную публикацию для периодических проверок. Перед релизом всегда запускают весь набор без сокращений.
Изображения уменьшают до требуемого физического размера, а тяжёлые SVG очищают от невидимых объектов и редакторских данных. Огромный DOM из повторяющихся декоративных элементов лучше заменить CSS-фоном или псевдоэлементом. Сложную подсветку кода выполняют заранее, если клиентский скрипт заметно задерживает готовность страницы. Каждая оптимизация должна сохранять доступный текст и печатное качество.
Кэш темы, npm и браузера ускоряет стабильную среду, но требует управляемого сброса. Ключ кэша связывают с файлом блокировки и платформой. После смены Node.js или контейнерного образа старый кэш браузера может быть несовместим. В таком случае чистая установка является диагностическим эталоном: если она работает, причину ищут в кэше, а не в разметке книги.
Сравнение Vivliostyle CLI с аналогами
| Программа | Лучше подходит для | Главное ограничение |
|---|---|---|
| Vivliostyle CLI | Книги и документация из HTML, Markdown и манифестов с CSS Paged Media | Макет настраивается кодом, а не визуально |
| Prince | Промышленное преобразование HTML или XML в PDF с развитой печатной версткой | Проприетарная лицензия для рабочего применения |
| WeasyPrint | Серверные отчёты, счета и документы в Python-проектах | Не выполняет клиентский JavaScript как браузер |
| Paged.js CLI | Эксперименты с Paged Media и собственными обработчиками на базе Chromium | Зависит от полифила Paged.js и Puppeteer |
| Antenna House Formatter | Корпоративная публикация XML, DITA, XSL-FO и HTML большого объёма | Коммерческий продукт со сложной конфигурацией |
| PDF Commander | Ручное редактирование, объединение и оформление уже готовых PDF | Не строит публикацию из HTML и CSS |
Vivliostyle CLI разумно выбирать, когда исходник живёт в Git, требуется Markdown или HTML, а результат надо собирать повторяемо и выпускать в нескольких публикационных форматах. Prince и Antenna House подходят организациям, которым важны коммерческая поддержка и зрелые корпоративные функции. WeasyPrint удобен внутри Python-сервиса с относительно прямой версткой, Paged.js CLI — для проектов с собственными JavaScript-обработчиками Paged Media. PDF Commander лучше решает другую часть процесса: быстро изменить существующий PDF без пересборки исходного документа.
Ограничения, которые важно учитывать заранее
Главное ограничение — отсутствие визуального редактора страниц. Viewer показывает результат, но не превращает изменение макета в перетаскивание объектов или редактирование текста непосредственно на листе. Исправление выполняется в исходнике, CSS или конфигурации. Для разработчика и технического автора это даёт прозрачность и автоматизацию; человеку без HTML и CSS потребуется время на освоение каскада, страничных правил и диагностики браузера.
Vivliostyle CLI не редактирует произвольный готовый PDF. Нельзя открыть скан, распознать его, удалить объект с третьей страницы и сохранить на месте. Сильная сторона проявляется, когда есть структурированный мастер и ожидаются повторные выпуски. Если исходника нет, его придётся восстановить или выбрать PDF-редактор; автоматическая печать веб-страницы не возвращает редактируемую семантику чужого документа.
Поддержка CSS широка, но не тождественна каждому браузеру и каждому коммерческому форматтеру. Перед использованием редкого свойства надо сверяться со списком поддерживаемых возможностей и создавать минимальный тест. Даже стандартное правило может иметь особые ограничения в фрагментированном потоке. Макет не следует строить на случайном эффекте, который работает только в одном примере и не проверен на длинном содержимом.
Зависимость от Node.js и управляемого браузера увеличивает объём среды. Первый запуск может загружать браузер, контейнер занимает место, а CI нуждается в кэше и системных библиотеках. Эти затраты оправданы для автоматизации, но избыточны для одноразового изменения пары страниц. Выбор инструмента должен исходить из жизненного цикла документа, а не только из возможности получить PDF одной командой.
Проверка перед выпуском
- Соберите публикацию с зафиксированными зависимостями и без режима быстрого предпросмотра.
- Проверьте порядок всех входов, обложку, титульные листы, оглавление и последнюю страницу.
- Сравните номера оглавления, ссылки, PDF-закладки и фактические цели переходов.
- Просмотрите страницы с длинными таблицами, кодом, сносками, рисунками и нестандартными разрывами.
- Убедитесь, что шрифты загрузились и встроились, а отсутствующие глифы не заменены квадратами.
- Проверьте размер листа, зеркальные поля, вылеты, метки и обрезные боксы.
- Для EPUB и WebPub проверьте порядок чтения, навигацию, альтернативный текст и перестройку размера шрифта.
- Для PDF/X выполните профильный префлайт и согласуйте цветовые параметры с типографией.
- Сохраните журнал сборки, версию зависимостей, входные данные и хеш итогового файла.
Финальный контроль лучше выполнять не только на экране разработчика. PDF открывают в независимом просмотрщике и, для печатной работы, печатают несколько характерных листов в масштабе 100 процентов. EPUB проверяют хотя бы в двух движках чтения. Такой подход отделяет ошибку исходной верстки от особенности одного Viewer и позволяет обнаружить проблему до передачи файла читателю или типографии.
Итоговый выбор рабочего подхода
Vivliostyle CLI даёт наибольшую отдачу там, где документ рассматривается как собираемый проект: текст, изображения, стили, конфигурация и зависимости хранятся вместе, изменения рецензируются, а результат можно воспроизвести командой. Для небольшой статьи достаточно одного входного файла и пары ключей; для книги применяются шаблон, массив глав, автоматическое оглавление, обложка, отдельные темы и несколько выходов.
Качество результата определяется не количеством параметров, а дисциплиной исходника. Семантический HTML, предсказуемые пути, встроенные шрифты, умеренные изображения и проверенные правила разрывов дают устойчивую пагинацию. Быстрый Viewer ускоряет ежедневную работу, но не заменяет полной сборки. Контейнер и CI закрепляют среду, но требуют контроля прав, ресурсов и кэшей.
Когда задача — регулярно выпускать книгу, инструкцию, отчёт или учебный материал из Markdown и HTML, этот подход устраняет ручное повторение и связывает печатную верстку с обычными средствами веб-разработки. Когда требуется править только существующий PDF без исходников, распознавать сканы или расставлять подписи мышью, нужен инструмент другого класса. Правильное разделение этих сценариев позволяет использовать Vivliostyle CLI именно для того, в чём он силён: управляемой CSS-верстки, полной проверки страниц и воспроизводимого выпуска публикаций.