Asciidoc. Что это вообще такое?

Asciidoc — это язык разметки текста для написания технических материалов. Он даёт инструменты для сборки документов в разных форматах, включая HTML и PDF. Написан на Ruby и позволяет настраивать генерацию документов множеством способов.

Мой опыт

Word для меня неудобен, так как настройка шаблонов в нём довольно неочевидна и он требует подгонять стили для каждого абзаца отдельно.

Поэтому я для себя сам собрал шаблон для Asciidoc максимально приближенный к ГОСТ 7.32-2017 (Отчёт по научно-исследовательской работе), написал скрипт на Powershell, который собирает отчёт в PDF. Документы редактирую в Visual Studio Code с плагином Asciidoctor.

Шаблон доступен на Github.

Установка Asciidoc

Для Windows я использую Chocolatey. Это удобный консольный менеджер пакетов и приложений. Инструкции по установке здесь

Затем, в терминале с правами администратора, выполните:

Terminal window
choco install ruby

Затем в терминале без прав администратора:

Terminal window
gem install asciidoctor asciidoctor-pdf

Чтобы убедиться, что установка прошла успешно, выполните

Terminal window
asciidoctor-pdf --version

Настройка шаблона

Создайте файл template.adoc в какой-нибудь папке (файл общий для всех документов), и вставьте туда это:

:ministry: Министерство науки и высшего образования Российской Федерации
:fullname1: <Полное название универа (первая строка)>
:fullname2: <Полное название универа (вторая строка)>
:shortname: <Аббревиатура универа>
:cathedra1: <Название кафедры (первая строка)>
:cathedra2: <Название кафедры (вторая строка)>
:subjectFull: по дисциплине «{subject}»
:themeFull: Тема: «{theme}»
:madeBy: Выполнил
:groupFull: студент {group}
:checkedBy: Принял
:city: <Название города>
:title: {work} №{worknumber}
:doctype: book
:reproducible:
:listing-caption: Листинг
:figure-caption: Рисунок
:table-caption: Taблица
:appendix-caption: Приложение
:toc-title: Содержание
:source-highlighter: rouge
:toclevels: 2
:imagesdir: ./images

Скрипты, изменяющие логику рендера

Эти скрипты удобно разместить рядом с шаблоном из предыдущего раздела в папке custom

Титульная страница

Этот скрипт заменяет стандартную титульную страницу на корректную, согласно ГОСТу 7.32

class PDFConverterCustomTitlePage < (Asciidoctor::Converter.for 'pdf')
register_for 'pdf'
def ink_title_page doc
move_cursor_to page_height * 0.9
theme_font :title_page_subtitle do
ink_prose doc.attributes['ministry'], align: :center, color: theme.base_font_color, line_height: 1, margin: 0
ink_prose doc.attributes['fullname1'], align: :center, color: theme.base_font_color, line_height: 1, margin: 0
ink_prose doc.attributes['fullname2'], align: :center, color: theme.base_font_color, line_height: 1, margin: 0
ink_prose doc.attributes['shortname'], align: :center, color: theme.base_font_color, line_height: 1, margin: 0
ink_prose doc.attributes['cathedra1'], align: :center, color: theme.base_font_color, line_height: 1, margin: 0
ink_prose doc.attributes['cathedra2'], align: :center, color: theme.base_font_color, line_height: 1, margin: 0
end
move_cursor_to page_height * 0.5
doctitle = doc.doctitle partition: ' | '
theme_font :title_page do
theme_font :title_page_title do
ink_prose doctitle.title, align: :center, color: theme.base_font_color, line_height: 1, margin: 0
ink_prose doc.attributes['subjectfull'], align: :center, color: theme.base_font_color, line_height: 1, margin: 0 if doc.attributes['subject']
ink_prose doc.attributes['themefull'], align: :center, color: theme.base_font_color, line_height: 1, margin: 0
end
end
move_cursor_to page_height * 0.3
theme_font :title_page_subtitle do
ink_prose doc.attributes['madeby'], align: :right, color: theme.base_font_color, line_height: 1, margin: 0
ink_prose doc.attributes['groupfull'], align: :right, color: theme.base_font_color, line_height: 1, margin: 0
ink_prose doc.attributes['author'], align: :right, color: theme.base_font_color, line_height: 1, margin: 0
ink_prose "", align: :right
ink_prose doc.attributes['checkedby'], align: :right, color: theme.base_font_color, line_height: 1, margin: 0
ink_prose doc.attributes['tutorposition'], align: :right, color: theme.base_font_color, line_height: 1, margin: 0 if doc.attributes['tutorposition']
ink_prose doc.attributes['tutorname'], align: :right, color: theme.base_font_color, line_height: 1, margin: 0
end
move_cursor_to page_height * 0.07
theme_font :title_page_subtitle do
ink_prose doc.attributes['city'] + " " + doc.attributes['localyear'], align: :center, color: theme.base_font_color, line_height: 1, margin: 0
end
end
end
Титульная страница отчёта
Титульная страница отчёта

Подпись приложения

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

require 'asciidoctor'
Asciidoctor::Extensions.register do
tree_processor do
process do |doc|
(doc.find_by context: :section).each do |section|
next unless section.sectname == 'appendix'
section.caption = section.caption.sub ':', ''
end
nil
end
end
end

Подпись рисунка

Аналогично заменим точку после номера рисунка на длинное тире:

class CustomFigurePdfConverter < (Asciidoctor::Converter.for 'pdf')
register_for 'pdf'
def convert_image node
node.caption = node.caption.sub '. ', ' — ' if node.title?
super
end
end

Тема

Настроим шрифты, отступы и прочие стили согласно ГОСТу. Это yml файл, который нужно положить в resources/themes/report-theme.yml

extends: base
font:
catalog:
merge: false
Times New Roman:
normal: times-new-roman-normal.ttf
italic: times-new-roman-italic.ttf
bold: times-new-roman-bold.ttf
bold_italic: times-new-roman-bold-italic.ttf
Jetbrains Mono:
normal: jetbrains-mono-nerd.ttf
italic: jetbrains-mono-nerd.ttf
bold: jetbrains-mono-nerd.ttf
bold_italic: jetbrains-mono-nerd.ttf
page:
layout: portrait
margin: 20mm 15mm 20mm 30mm
size: A4
numbering:
start-at: title
base:
font-family: Times New Roman
font-size: 14
hyphens: true
line-height: 1.5
heading:
text-align: center
h2:
text-transform: uppercase
font-style: normal
h3:
font-style: bold
prose:
text-indent: 1.25cm
code:
font-family: Jetbrains Mono
codespan:
font-family: Jetbrains Mono
font-size: 13
caption:
font-style: normal
footer:
border-width: 0
columns: =100%
recto: &shared_footer
center:
content: '{page-number}'
verso: *shared_footer
image:
align: center
caption:
text-align: center

Шрифты

Затем скачайте шрифты Times New Roman и Jetbrains Mono (есть в репозитории) и разместите их в папке resources/fonts

Документ

Скрипт, который я приведу ниже, предполагает что файл документа называется report.adoc. В этом файле будем писать разметку документа. Шпаргалка по синтаксису.

:doctype: book
:work: Отчёт по лабораторной работе
:workNumber: 1
:subject: Название предмета
:theme: Название темы
:author: Имя автора
:group: Номер группы
:tutorPosition: Должность проверившего
:tutorName: Имя проверившего
include::<абсолютный-путь-до-template.adoc>[]
= {work} №{worknumber}
:title-page:
:toc:
== Цель работы
== Выполнение работы
== Вывод

Скрипт запуска

Для генерации отчёта используется скрипт на powershell, который я кладу в папку scripts рядом с документом. <путь-до-папки-с-шаблоном> нужно заменить на фактический путь до ресурсов шаблона.

$group = "номер-группы"
$subject = "название-предмета"
$workNumber = "номер-работы"
$author = "фамилия-автора"
$command = "asciidoctor-pdf"
$arguments = "-T <путь-до-папки-с-шаблоном>", "-r <путь-до-папки-с-шаблоном>/custom/10titlePage.rb", "-r <путь-до-папки-с-шаблоном>/custom/20appendixCustomCaption.rb", "-r <путь-до-папки-с-шаблоном>/custom/30customFigureCaption.rb", "-a pdf-fontsdir=<путь-до-папки-с-шаблоном>/resources/fonts", "-a pdf-themesdir=<путь-до-папки-с-шаблоном>/resources/themes", "report.adoc", "--theme=report", "-o '$group-$subject-$workNumber-$author.pdf'"
try {
$process = Start-Process -FilePath $command -ArgumentList $arguments -NoNewWindow -Wait -PassThru
if ($process.ExitCode -eq 0) {
Write-Host "Report generated!"
}
else {
throw "Error generating report. Exit code: $($process.ExitCode)"
}
}
catch {
Write-Error $_.Exception.Message
}

После запуска этого скрипта на выходе получим файл номер-группы-название-предмета-номер-работы-фамилия-автора.pdf.

Итоговый документ
Итоговый документ
Итоговый документ
Итоговый документ

Вывод

Для меня asciidoc стал удобным инструментом быстрого написания красивых отчётов лабораторных работ для универа. В этой статье я поделился своим опытом организации процесса создания таких отчётов и готовым шаблоном, максимально приближенным к ГОСТ 7.32-2017