пятница, 30 марта 2018 г.

GOSTdown: автоматическая вёрстка документации по ГОСТам

Введение

В данном посте описаны решения, которые легли в основу GOSTdown — набора шаблонов и скриптов для автоматической вёрстки. GOSTdown предназначен для тех, кому приходится писать и оформлять научно-технические отчёты (НТО) или программы по Единой системе программной документации (ЕСПД). Такие документы нередко имеют крупный размер, создаются долго и несколькими людьми, и перед сдачей проверяются на соответствие ГОСТам. Традиционно для создания таких документов используется Microsoft Word. Исполнители привыкли делать в Word, заказчики привыкли принимать в Word. Заказчиков мы обсуждать не будем, а поговорим об исполнителях и их проблемах.

Проблема

При создании документации нередко требуются следующие вещи:
  • Нумерация глав и разделов, генерация оглавления
  • Вставка и нумерация формул, таблиц и рисунков
  • Нумерация и форматирование многоуровневых списков
  • Ссылки на главы, разделы, формулы, таблицы и рисунки
  • Ведение перечня использованных источников, генерация списка литературы и ссылок на него в тексте
  • Автоматический подсчёт и вставка в текст количества страниц, таблиц, рисунков, приложений
  • Вставка текста из других документов и оформление его под стиль
  • Протоколирование изменений, внесённых разными людьми
  • Слияние изменений, сделанных разными людьми в своих копиях документа
Само собой, подразумевается отсутствие ручной работы. Никакой перенумерации ссылок или сравнения двух документов «на глаз». Никакого выставления отступов и промежутков индивидуально для абзаца. Рутинные задачи должен делать компьютер.

Строго говоря, Word имеет средства для всех вышеперечисленных задач. Да, для всех. С параллельным редактированием и слиянием изменений Word в одиночку не справится, но установка сервера Sharepoint решит и этот вопрос.

Допустим, существуют люди, которые используют Word и его возможности, и у них всё получается. Им будет неинтересно читать дальше. Этот пост может представлять интерес для людей, у которых:
  • Какие-то заголовки упорно не появляются в оглавлении, а другие, которые в нём не нужны — упорно появляются
  • Текст документа пестрит сообщениями [ошибка! источник ссылки не найден] или ненадёжными прямыми номерами, вставленными отчаявшимися коллегами
  • Постоянно ломается форматирование многоуровневых списков
  • Съезжает форматирование при вставке пункта списка из буфера обмена, вне зависимости от способа вставки
  • Отслеживание изменений невозможно, потому что от «Отформатировано: русский» рябит в глазах
  • Нет Sharepoint, а если он и появится, никто не научится им пользоваться
  • При сохранении doc-файла в .docx работа Word необъяснимо и фатально замедляется
  • Любая попытка привести в порядок зоопарк стилей в 100-страничном документе делает всё только хуже
  • Есть необходимость редактировать основной текст документа в iOS или Android, и при этом не портить оформление при сохранении.

Решение

Решение заключается в том, чтобы редактировать документ в формате, основанном на тексте (plain text), а для чтения, печати и сдачи осуществлять преобразование текста в docx-файл, оформленный по всем правилам.

Исходный текстовый формат позволит легко отслеживать и сливать изменения (в идеале — с применением git или иной системы контроля версий). Автоматизированная процедура преобразования в docx пронумерует всё необходимое, расставит номера ссылок и применит стили оформления.

Пример исходного текста в Markdown:

Результат в PDF, сохранённом из docx:

Полный пример документа см. в репозитории. Там же находится руководство пользователя (README.md). Примеры результатов см. в архиве артефактов репозитория.

Остальное — технические детали, в которых всё самое интересное.

Выбор исходного формата и конвертера

С конвертером всё просто: он фактически единственный и называется Pandoc. Он обладает уникальным движком преобразования латеховских формул в формулы Word 2010.

Pandoc — универсальный инструмент для преобразования более чем 20 форматов друг в друга. Но схема его работы такова, что любые преобразования идут через внутреннее промежуточное представление документа в самом Pandoc. Модель внутреннего представления не содержит всех возможностей всех исходных форматов (и наоборот, содержит возможности, которые присутствуют не во всех исходных форматах). Это фактически приводит к выбору формата для нашей задачи. Есть только один формат, на 100% соответствующий внутреннему представлению Pandoc: Markdown. Точнее, Pandoc’s Markdown (формат Markdown сам по себе существует во многих вариациях).

Формулы в Pandoc’s Markdown вводятся в формате LaTeX. Для библиографии доступны разные варианты, включая BibTeX. Это привычно многим сотрудникам научных организаций, которые занимаются написанием статей.

Иллюстрации в Markdown вставляются в виде внешних файлов в форматах PNG, JPEG и EMF (последний — для графиков и векторных рисунков).

Ссылками в Pandoc занимаются т.н. фильтры: pandoc-citeproc (для библиографических ссылок) и pandoc-crossref (для всего остального). Эти фильтры — отдельные программы, запускаемые из Pandoc и работающие с документом в его внутреннем представлении.

Библиография

Существует два ГОСТа: 7.1-2003 (Библиографическая запись. Библиографическое
описание) и 7.0.5-2008 (Библиографическая ссылка). При создании списка
литературы в программной и научно-технической документации формально требуется применять ГОСТ 7.1. Но реально его никто не применяет из-за нелепых требований:
  • вставлять пометку «[Текст]» в ссылки на любые тексты (т.е. практически во все ссылки);
  • повторять имя первого автора дважды (включая случай, если автор всего один);
  • писать полный список авторов после названия (до трёх включительно), а если их четыре и более, то упоминать только первого «и др».
ГОСТ 7.0.5 обходится без этих требований, поэтому его более охотно используют
вместо 7.1 — ту его часть, которая называется «затекстовые ссылки», про
которые, впрочем, сказано, что «Совокупность затекстовых библиографических
ссылок не является библиографическим списком».

В пакете pandoc-citeproc, используемом в Pandoc, есть стилевой файл в формате CSL 1.0.1, основанный на ГОСТ 7.0.5 с отдельными элементами ГОСТ 7.1.

В целом, правила ГОСТов (как 7.1, так и 7.0.5) настолько сложны, что автоматизировать библиографию по всем правилам невозможно. Вышеупомянутый формат CSL 1.0.1, задуманный как универсальный окончательный формат для формирования всей библиографии на свете, разумеется, не подходит в полной мере для этих ГОСТов.

В частности, в ГОСТе есть разумное требование: английские ссылки должны быть с английскими вспомогательными словами (Vol., No., pp., ed. и прочие), а русские — с русскими. В CSL 1.0.1 такой опции не предусмотрено. Опция появилась в расширении CSL-M, которое не поддерживается в pandoc-citeproc. Это препятствие удалось частично преодолеть ценой установки вспомогательного поля «note» в русскоязычных статьях и дополнительных изменений в CSL-файле.

Шаблон

Pandoc работает с основным текстом документа. Такие вещи, как титульный лист и колонтитулы, легко создаются пользователями в Word в режиме WISYWIG, тогда как их создание в Pandoc затруднено или невозможно. Для разрешения этого противоречия в GOSTdown существует файл-шаблон в формате docx, который содержит следующее:
  1. Формат колонтитулов (Pandoc «подхватывает» этот формат при генерации документа с основым текстом)
  2. Перечень стилей, которые впоследствии использует Pandoc при генерации docx-файла
  3. Собственно неосновное содержимое документа, т.е. небольшая часть содержимого, которая не генерируется из Markdown.

Постобработка

Напомним, Pandoc преобразует файл основного текста в формате Markdown в аналогичный файл в формате docx. Сразу после получения этого файла возникает задача вставки его в нужное место шаблона (после титульного листа). Этим занимается скрипт постобработки. И не только этим: файл, сгенерированный Pandoc, хотя и содержит необходимые стили, всё же не является готовым продуктом. Для получения готового продукта необходимо следующее:
  1. Установка стилей нумерации и отступы для списков и вложенных списков (Pandoc в настоящий момент не обладает механизмом шаблонизации списков)
  2. Исправление выравнивания номеров формул (нумерованные формулы pandoc-crossref генерирует как таблицы из двух колонок)
  3. Исправление горизонтального выравнивания ячеек таблиц, в которых есть только формула и больше ничего (Word в таком случае берёт настройки выравнивания из формулы, а не из ячейки, а Pandoc не заботится о том, чтобы выравнивание в формуле совпадало с оным в ячейке.)
  4. Установка стилей таблиц (Pandoc не умеет этого делать)
  5. Установка стилей ненумерованных заголовков (они отличаются от стилей нумерованных, а Pandoc присваивает всем заголовкам одного уровня один стиль).
  6. Разные другие мелочи по части форматирования
  7. Вставление оглавления средствами Word
  8. Подсчёт количества страниц, рисунков, таблиц, приложений, литературных источников, и вставка этих чисел в необходимое место документа.
  9. Сохранение полученного документа не только в docx, но и в PDF.
Всё это делается с помощью Word COM. Фактически, любая инсталляция Word на Windows открывает возможности для программного управления содержимым документа так же, как пользователь делал бы это вручную в программе. Широко известно применение этой технологии в макросах (VBA), но макросы не очень удобны тем, что сами хранятся в документе. Менее известен следующий факт: с COM-объектами без труда можно работать в скриптах Powershell. Это и реализовано в GOSTdown, см. скрипт для запуска Pandoc и постобработки.

Вопросы и ответы

1. Где рамочки с боковыми ячейками для подписей?

В представленном примере Описания программы имеются рамки на листе утверждения и титульном листе. В основной части ГОСТ разрешает рамку не наносить. В НТО рамки не требуются нигде.

2. Всё это точно по ГОСТу?

ГОСТы соблюдены в разумных пределах. В редких случаях требования ГОСТов проигнорированы в угоду эстетической составляющей. Например, ГОСТ рекомендует форматировать списки следующим образом:
Также см. выше ремарку о библиографии.

3. Почему шрифты не Arial и Times New Roman, а какие-то другие?

Требований по гарнитуре нет в ГОСТах (за исключением ГОСТов на стандарты и на конструкторскую документацию). В представленных шаблонах используются общедоступные гарнитуры фирмы «Паратайп»: PT Serif (с засечками), PT Sans (без засечек) и PT Mono (моноширинный) Объяснение, почему паратайповские шрифты идеально подходят для документов на русском языке, см. здесь.

4. Почему docx-файлы такие большие?

Из-за вышеупомянутых шрифтов, встроенных в файл. Можно отключить встраивание шрифтов (за него отвечает опция -embedfonts), и тогда файлы станут адекватного размера, но если на компьютере вашего коллеги или заказчика не установлены шрифты PT Serif, PT Sans и PT Mono, то при открытии документа в Word шрифты заменятся на шрифты по умолчанию, и документ в итоге будет выглядеть не так, как было задумано.

5. Почему не LaTeX?

Государственные заказчики не возьмут LaTeX-файл, т.к. не знают, что это такое. В принципе, если заказчику не нужен исходник и достаточно PDF-файла, то можно использовать и LaTeX.
Pandoc умеет генерировать docx-файлы из LaTeX, но генерация осуществляется с потерями из-за разницы в идеологиях LaTeX и Word в области стилей. Теоретически возможен вариант генерации и LaTeX и docx-файлов из одного исходника в Markdown с помощью Pandoc, но в реальности такое средство пока не создано.

6. Почему не Google Docs? Там даже формулы появились

Да, и даже доступны дополнения (Add-ons) для нумерации и библиографии. В Google Docs удобные средства совместной работы, но ограниченные средства форматирования. Нет стилей (кроме небольшого исходного набора). Проблематична вставка векторных рисунков. Нет поддержки офлайновой работы. (На самом деле есть, но тогда перестаёт решаться проблема слияния изменений.)

7. Почему не LibreOffice?

Во-первых, потому, что в LibreOffice/OpenOffice крайне плохо обстоит дело с отображением формул. Позвольте не называть остальные 17 причин.

8. Как преобразовать имеющийся docx в Markdown?

Конечно же, с помощью Pandoc (он ведь преобразует в любую сторону). Конечно, информация о стилях исходного документа при этом потеряется. Возможно, после конвертации потребуется ручная правка. Дополнительные проблемы могут возникнуть с формулами: Pandoc распознаёт в docx-файлах только формулы, набранные средствами Word 2010 (не MS Equation и не MathType). Известен трюк с участием LibreOffice для пересохранения формул MS Equation в Word 2010. Для более позднего MathType он, кажется, не работает.

9. Чем редактировать Markdown?

Любым текстовым редактором, начиная с notepad.exe. Например, для Windows есть Notepad++, для Linux — Emacs, для всех десктопных ОС — Visual Studio Code. Все они бесплатные.
Преимущество текстового представления в том, что вносить правки в текст можно хоть со смартфона в самолёте (и если настроен GitLab CI, вы сразу получаете готовый документ).

10. Что такое Gitlab CI и как мне получить docx, редактируя файл не на Windows?

См. соответствующий раздел руководства. Машина с Windows (удалённая) всё же понадобится, см. раздел «Системные требования».

11. Чем редактировать Markdown так, чтобы сразу видеть результат?

Это сложнее. Вам потребуется или вышеупомянутый Visual Studio Code, или Atom. Потребуется также установить расширение Markdown Preview Enhanced (MPE). Альтернативное расширение — Markdown Preview Plus (MPP), только для Atom. Эти расширения используют Pandoc для того, чтобы делать из вашего Markdown-файла HTML-файл для предпросмотра. Прочие средства редактирования Markdown, в т.ч. онлайновые, рассчитаны на другие диалекты Markdown и не будут отображать Pandoc’s Markdown в полной мере.

Пользовательские настройки для MPE в VS Code таковы:
{
    "markdown-preview-enhanced.usePandocParser": true,
    "markdown-preview-enhanced.pandocArguments":
       "--filter=pandoc-crossref, --filter=pandoc-citeproc"
}
При нажатии Ctrl+k v включается предпросмотр, который, хоть и не совпадает в точности с будущим docx-файлом, аккуратно отображает все формулы, таблицы, блоки кода и изображения (кроме EMF).


12. Таблицы неудобно редактировать в виде текста, что делать?

В Visual Studio Code и Atom существуют многочисленные расширения для упрощения работы с Markdown, в т.ч. с таблицами. Таблицы самого сложного вида (с многоабзацевыми ячейками) они, к сожалению, не поддерживают. Такие таблицы поддерживает Emacs и его table-mode.

13. Мне нужны вещи, которые есть в Word, но отсутствуют в Markdown, что делать?

Если речь идёт об относительно небольшом фрагменте документа, не укладывающимся в формат (например, сложная таблица с объединёнными ячейками), то пользователь может держать этот фрагмент в отдельном docx-файле, редактируя его в Word. Вставка фрагмента в основной текст может делаться скриптом, аналогично тому, как сейчас сам основной текст вставляется в шаблон на место %MAINTEXT%.

Благодарности

В создании GOSTdown принимала активное участие Алёна Водолагина (ИПА РАН), также помощь оказывал Даниил Аксим (ИПА РАН). Разумеется, GOSTdown не был бы возможен без замечательного ПО: Pandoc, pandoc-citeproc и pandoc-crossref (автор последнего — Николай Якимов, МАИ). Ну и Microsoft помогла своими Word COM и Powershell, чего уж там.

Комментариев нет: