Skip to content

Техническая документация

wizardjedi edited this page Mar 14, 2015 · 23 revisions

Одной из наиболее важных сфер разработки ПО является создание технической документации. В данном документе описан способ подготовки технической документации с использованием Markdown + GPP + Pandoc + LaTeX.

Используемое ПО и обозначения

  • Markdown - облегчённый язык разметки. Документы с использованием markdown могут быть прочитаны и написаны человеком без специализированного ПО, однако содержат в себе как наполнение, так и структуры документов. Основной инструмент для работы с markdown - это текстовый редактор, однако, из разметки markdown можно получить хорошо выглядящие документы в HTML и т.д. В связи с тем, что разметка очень простая и ненавязчивая, то markdown используется в Wiki и других системах, где требуется использование разметки.
  • Pandoc - это конвертер файлов различных форматов, написанный на Haskell. Pandoc поддерживает множество форматов: html, epub, docx, odt, html, TeX, pdf (через LaTeX), markdown, fb2 и т.д.
  • GPP - General Purpose PreProcessor. Это препроцессор файлов, который очень полезен при обработке текстов. Фактически, данный прекпроцессор позволяет использовать директивы как в С++ (например, #include или #define).
  • LaTeX (читается как латех, а не латекс ) - это расширение системы подготовки документации TeX, написанной Дональдом Кнутом.
  • texlive - наиболее полный дистрибутив TeX-ориентированных инструментов. texlive содержит как основные инструменты, так и расширения, библиотеки, шрифты и т.д.

Принцип single source documentation

Принцип SSD (single source documentation) - это подход к разработке документации, при котором технические писатели, разработчики, тестировщики и т.д. работают с одним документом, который семантически разделён на разделы, содержит структуры и т.д. При подготовке документации фактически происходит компиляция исходных файлов для получения документации в различных форматов, для разных сборок и на разных языках.

Что будем делать?

  • Разработаем workflow для подготовки документации на основе системы контроля версий GIT.
  • Создадим скрипты и указания для сборки документации из единого источника.
  • Создадим шаблоны для сборки документации в разных форматах.
  • Разработаем механизмы для получения документации в следующих видах:
    • Язык документации: русский, английский.
    • Форматы документации: HTML, DOCX, PDF.
    • Специфическое распространение дистрибутива: LINUX, Windows (добавим в документацию разделение на план установки отдельно для каждой из операционных систем)
  • Добавим построение списка изменений по истории коммитов из GIT
  • Создадим скрипты для автоматизации процесса сборки документации.
  • В качестве основы документа будем использовать Markdown.

Установка ПО

Установка ПО может быть проведена следующим образом:

Установка wget, libgmp10 и pandoc.

$ apt-get update 
$ apt-get install -y wget libgmp10
$ cd /tmp
$ wget --no-check-certificate https://github.com/jgm/pandoc/releases/download/1.13.2/pandoc-1.13.2-1-amd64.deb
$ dpkg -i pandoc-1.13.2-1-amd64.deb
$ rm pandoc-1.13.2-1-amd64.deb

Установим texlive, texlive-full и gpp.

$ apt-get install -y texlive texlive-full gpp

Сам texlive занимает почти 2Gb, поэтому чтобы не захламлять систему можно воспользоваться образом в Docker, который собран для использования pandoc+gpp+texlive. https://registry.hub.docker.com/u/wizardjedi/pandoc-latex/

$ docker pull wizardjedi/pandoc-latex

а использовать как-то так:

$ docker run --rm -it -v `pwd`:/source wizardjedi/pandoc-latex pandoc -f markdown -t html /source/somefile.md

Почему и зачем?

  • Почему Markdown,а не docbook? - DocBook - это формат для технической документации, основанный на XML. DocBook - гораздо более продвинутый чем Markdown, но и гораздо более сложный. Не каждый переводчик или технический писатель справиться с DocBook, а Markdown не требует дополнительных знаний. Синтаксис Markdown учится за несколько минут, а на DocBook надо потратить много времени. Преобразование форматов для DocBook дело не простое, вот пример статьи как построить процесс с DocBook Разработка документации при помощи DocBook.
  • Зачем какой-то странный формат, если можно подготовить документацию в Word/OpenOffice и преобразовать в HTML/PDF? - можно воспользоваться и Word, но: у всех, кто вносит изменения в документ должен быть установлен Word; желательно, чтобы у всех были одинаковые версии ПО; вы не можете положить документ в систему контроля версий, точнее не увидите изменений; при малейшем изменении необходимо перевёрстывать документ и делать изменения во всех документах; автоматизация крайне затруднена; понадобился новый формат документации - забудь!; на сайте версия PDF-файла, а где исходник? Потерян! и т.д.

Шаг 0. Создание пустого репозитория.

Создадим пустой репозиторий как заготовку для технической документации.

$ git init
$ mkdir sources

В коммитах будем указывать ключевое слово _techdoc_, чтобы отличать коммиты, которые попадут в историю изменений в документе.

Ветка с примером: pres_0_12_0 https://github.com/wizardjedi/my-spring-learning/tree/pres_0_12_0

Шаг 1. Создание основного файла и первичные знания о препроцессинге.

Сам Pandoc является только системой по преобразованию форматов. Соответственно, для автоматизации процесса сборки и добавлению таких фич, как объединение файлов, необходимо воспользоваться внешними инструментами. Так как всё (почти всё) в нашей документации будет текстовыми файлами, то мы можем воспользоваться GPP для препроцессинга файлов для создания итоговой документации.

Создадим в директории sources/ следующие файлы.

  • main.md - основной файл. Он содержит только ссылки на другие главы
  • title_page.md - содержит основную информацию по названию книги (документа)
  • introduction.md - будет содержать введение

Содержимое файлов: main.md

#include title_page.md
#include introduction.md

title_page.md

---
title: Подготовка технической документации с помощью Pandoc и Latex
...

introduction.md

# Введение

В данном документе описан механизм/подход к созданию технической документации с использованием следующих инструментов:
 * [Pandoc](http://johnmacfarlane.net/pandoc/index.html)
 * [GPP](http://en.nothingisreal.com/wiki/GPP)
 * [LaTeX](http://www.latex-project.org/)
 * [Docker](https://www.docker.com/)

Ветка с проектом: pres_0_12_1 https://github.com/wizardjedi/my-spring-learning/tree/pres_0_12_1

Пара слов про разметку:

  • [text](URL) - Задаёт ссылку
  • * - задаёт список
  • # - задаёт раздел

Более подробно с разметкой можно познакомиться по ссылке: https://help.github.com/articles/github-flavored-markdown/

Попробуем подвергнуть файл препроцессингу:

$ gpp sources/main.md 
---
title: Подготовка технической документации с помощью Pandoc и Latex
...
# Введение

В данном документе описан механизм/подход к созданию технической документации с использованием следующих инструментов:
 * [Pandoc](http://johnmacfarlane.net/pandoc/index.html)
 * [GPP](http://en.nothingisreal.com/wiki/GPP)
 * [LaTeX](http://www.latex-project.org/)
 * [Docker](https://www.docker.com/)

Как видим, файл main.md после препроцессинга выдаёт текст с добавлением дополнительных материалов.

Шаг 2. Дополнительные возможности GPP

Встраивать файлы в другой файл мы научились, расммотрим, что ещё умеет GPP.

Условная компиляция (условный препроцессинг)

Для GPP можно определить макросы, например, так.

Создадим макрос URL для упрощения создания ссылок.

#define URL(text,url) [text](url)

Test: URL(Some text,http://some.url.tld/)

А теперь обработаем файл с помощью GPP.

На выходе получим:

Test: [Some text](http://some.url.tld/)

То есть, макрос с параметрами был преобразован в markdown разметку.

Теперь рассмотрим условный препроцессинг.

Объявим макрос.

#define LANG ru

#ifdef LANG
Language is: LANG
#else
Language is not defined
#endif

После обработки получим вывод:

Language is: ru

Но в данном случае макрос LANG объявлен прямо в файле, а в GPP можно передавать макросы через командную строку. Изменим файл для примера.

#ifdef LANG
Language is: LANG
#else
Language is not defined
#endif

И обработаем файл без указания макроса:

$ gpp sources/test1.txt 
Language is not defined

и с указанием языка

$ gpp -DLANG=ru sources/test1.txt 
Language is: ru

Выполнение внешних комманд

GPP умеет добавлять вывод от внешних команд. Например, можно указать текущее время.

$ cat sources/test1.txt 
#exec date
$ gpp -x sources/test1.txt 
Чт. марта 12 17:57:19 MSK 2015

Можно делать даже сложные команды с разделением через pipes. Например, добавим вывод истории из GIT, но только тех коммитов, которые относятся к документации.

$ cat sources/test1.txt 

Logs:
#exec git log --format='%ci %s %an' | grep '_techdoc_' | sed -r 's/_techdoc_//g'
$ gpp -x sources/test1.txt 

Logs:
2015-03-12 17:31:12 +0300  Added initial source files for docs. Sayapin Alexander

Важно, что для работы макроса #exec требуется опция -x при запуске gpp.

Добавим в наш файл время создания документации и список изменений.

Мы добавили файл history.md и изменили main.md

main.md

#include title_page.md
#include history.md
#include introduction.md

# Сводная информация
Дата генерации: #exec date "+%Y-%m-%d %H:%M:%S"

history.md

|Дата|Изменение|Пользователь|
|-|-|-|
#exec git log --pretty=format:"|%ci|%s|%an|" | grep '_techdoc_' | sed -r 's/_techdoc_//g' 

Ветка с проектом расположена по адресу: pres_o_12_2 https://github.com/wizardjedi/my-spring-learning/tree/pres_0_12_2

Вывод GPP.

$ gpp -x sources/main.md 
---
title: Подготовка технической документации с помощью Pandoc и Latex
...
|Дата|Изменение|Пользователь|
|-|-|-|
|2015-03-12 18:28:44 +0300| Added history page and internal info: building date.|Sayapin Alexander|
|2015-03-12 17:31:12 +0300| Added initial source files for docs.|Sayapin Alexander|

# Введение

В данном документе описан механизм/подход к созданию технической документации с использованием следующих инструментов:
 * [Pandoc](http://johnmacfarlane.net/pandoc/index.html)
 * [GPP](http://en.nothingisreal.com/wiki/GPP)
 * [LaTeX](http://www.latex-project.org/)
 * [Docker](https://www.docker.com/)

# Сводная информация
Дата генерации: 2015-03-12 18:28:54

Пара слов о разметке таблиц. Таблицы задаются так:

|Столбец 1|Столбец 2|
|-|-|
|Значение 1|Значение 4|
|Значение 2|Значение 5|
|Значение 3|Значение 6|

Шаг 3. Макросы по умолчанию и сообщения об ошибках.

Как и было указано, мы создаём документацию для разных систем и разных языков. Язык документации передаётся в макросе _LANG_, а тип системы в _SYSTEM_.

В качестве языка по умолчанию будет использоваться русский, а вот если не указана система, то необходимо выдавать ошибку.

Изменим файл main.md.

main.md

#ifndef _LANG_
#warning _LANG_ is not defined. 'ru' will be used for _LANG_
#define _LANG_ ru
#endif

#ifndef _SYSTEM_
#error _SYSTEM_ must be specified
#endif

#include title_page.md
#include history.md
#include introduction.md

# Сводная информация
Дата генерации: #exec date "+%Y-%m-%d %H:%M:%S"
Язык генерации: _LANG_
Система: _SYSTEM_

макрос #error вывод сообщение об ошибке и завершает выполнение. макрос #warning только выводит сообщение об ошибке, но не прерывает выполнение.

Попробуем проверить работу.

Зададим и язык и систему.

$ gpp -x -D_SYSTEM_=linux -D_LANG_=en sources/main.md 
---
title: Подготовка технической документации с помощью Pandoc и Latex
...
|Дата|Изменение|Пользователь|
|-|-|-|
|2015-03-12 18:28:44 +0300| Added history page and internal info: building date.|Sayapin Alexander|
|2015-03-12 17:31:12 +0300| Added initial source files for docs.|Sayapin Alexander|

# Введение

В данном документе описан механизм/подход к созданию технической документации с использованием следующих инструментов:
 * [Pandoc](http://johnmacfarlane.net/pandoc/index.html)
 * [GPP](http://en.nothingisreal.com/wiki/GPP)
 * [LaTeX](http://www.latex-project.org/)
 * [Docker](https://www.docker.com/)

# Сводная информация
Дата генерации: 2015-03-12 19:24:30
Язык генерации: en
Система: linux

Зададим только систему.

$ gpp -x -D_SYSTEM_=linux sources/main.md 
sources/main.md:3: warning: _LANG_ is not defined. 'ru' will be used for _LANG_


---
title: Подготовка технической документации с помощью Pandoc и Latex
...
|Дата|Изменение|Пользователь|
|-|-|-|
|2015-03-12 18:28:44 +0300| Added history page and internal info: building date.|Sayapin Alexander|
|2015-03-12 17:31:12 +0300| Added initial source files for docs.|Sayapin Alexander|

# Введение

В данном документе описан механизм/подход к созданию технической документации с использованием следующих инструментов:
 * [Pandoc](http://johnmacfarlane.net/pandoc/index.html)
 * [GPP](http://en.nothingisreal.com/wiki/GPP)
 * [LaTeX](http://www.latex-project.org/)
 * [Docker](https://www.docker.com/)

# Сводная информация
Дата генерации: 2015-03-12 19:25:18
Язык генерации: ru
Система: linux

А теперь не будем задавать ни систему, ни язык.

$ gpp -x sources/main.md 
sources/main.md:3: warning: _LANG_ is not defined. 'ru' will be used for _LANG_

sources/main.md:8: error: _SYSTEM_ must be specified

Видим сообщение об ошибке.

Ветка с проектом: pres_0_12_3 https://github.com/wizardjedi/my-spring-learning/tree/pres_0_12_3

Шаг 4. Задание названия для английской версии и первое использование pandoc.

Итак, наша система уже умеет достаточно много.

Зададим название для английской версии документации.

sources/title_page.md

$ cat sources/title_page.md 
---
#ifeq _LANG_ en
title: Prepare technical documentation using Pandoc and LaTeX
#else
title: Подготовка технической документации с помощью Pandoc и LaTeX
#endif
...

Попробуем обработать файлы.

$ gpp -x -D_SYSTEM_=linux -D_LANG_=en sources/main.md 
---
title: Prepare technical documentation using Pandoc and LaTeX
...
|Дата|Изменение|Пользователь|
|-|-|-|
|2015-03-12 18:28:44 +0300| Added history page and internal info: building date.|Sayapin Alexander|
|2015-03-12 17:31:12 +0300| Added initial source files for docs.|Sayapin Alexander|

# Введение

В данном документе описан механизм/подход к созданию технической документации с использованием следующих инструментов:
 * [Pandoc](http://johnmacfarlane.net/pandoc/index.html)
 * [GPP](http://en.nothingisreal.com/wiki/GPP)
 * [LaTeX](http://www.latex-project.org/)
 * [Docker](https://www.docker.com/)

# Сводная информация
Дата генерации: 2015-03-12 19:34:42
Язык генерации: en
Система: linux

Как видим изменения вступили в силу и название "книги" изменено на английскую версию.

Теперь пришло время попробовать сконвертировать что-нибудь. Выполним следующие команды:

$ mkdir target
$ gpp -x -D_SYSTEM_=linux -D_LANG_=en sources/main.md > target/input.md
$ docker run --rm -it -v `pwd`:/source wizardjedi/pandoc-latex pandoc -f markdown_github+pipe_tables+yaml_metadata_block -s -t latex -o /source/target/doc.pdf /source/target/input.md
$ docker run --rm -it -v `pwd`:/source wizardjedi/pandoc-latex pandoc -f markdown_github+pipe_tables+yaml_metadata_block -s -t html -o /source/target/doc.html /source/target/input.md

Рассмотрим команды более подробно.

  • mkdir ... - создадим директорию для вывода
  • gpp -x -D_SYSTEM_=linux -D_LANG_=en sources/main.md > target/input.md - обработаем входной файл с заданием соответствующих переменных и создадим заготовку input.md
  • docker run --rm -it -v pwd:/source wizardjedi/pandoc-latex pandoc -f markdown_github+pipe_tables+yaml_metadata_block -s -t latex -o /source/target/doc.pdf /source/target/input.md - это вызов pandoc'а в контейнере Docker. Данная команда обработает входной файл и создаст pdf-версию документации. Пробежимся по опциям docker'а и pandoc'а.
    • -v - монтирует директорию в Docker-контейнер
    • -f - входной формат (markdown_github+pipe_tables+yaml_metadata_block) - это markdown от GitHub с использованием расширений pipe_tables и yaml_meta_block
    • -s - режим создания полного документа
    • -t - выходной формат
    • -o - выходной файл

После выполнения команд в директории target должны появится следующие файлы:

$ ls target/
$ ls -lah target/
итого 96K
drwxrwxr-x 2 wiz  wiz  4,0K марта 12 20:10 .
drwxrwxr-x 5 wiz  wiz  4,0K марта 12 19:40 ..
-rw-r--r-- 1 root root 1,9K марта 12 20:03 doc.html
-rw-r--r-- 1 root root  80K марта 12 20:02 doc.pdf
-rw-rw-r-- 1 wiz  wiz   798 марта 12 20:02 input.md

Есть небольшой недостаток в том, что выходные файлы созданы от пользователя root, но мы исправим этот недостаток позднее.

А вот скриншоты получившихся файлов: html pdf

Теперь добавим выбор языка для существующих файлов и реализуем скрипты для препроцессинга и сборки. Препроцессинг будем проводить в хост машине, а вот сборку в docker-контейнере.

Создадим следующие файлы: bin/convert.sh

#!/bin/bash

LANG=$1
SYSTEM=$2

rm -rf generated

mkdir generated

gpp -x -D_LANG_=$LANG -D_SYSTEM_=$SYSTEM sources/main.md > generated/input.md

rm -rf target

mkdir target

docker run --rm -it -v `pwd`:/source wizardjedi/pandoc-latex /bin/bash /source/bin/pandoc_convert.sh $LANG $SYSTEM

bin/pandoc_convert.sh

#!/bin/bash

LANG=$1
SYSTEM=$2

/usr/bin/pandoc -f markdown_github+pipe_tables+yaml_metadata_block -s -t latex -o /source/target/doc_$SYSTEM.$LANG.pdf /source/generated/input.md
/usr/bin/pandoc -f markdown_github+pipe_tables+yaml_metadata_block -s -t html -o /source/target/doc_$SYSTEM.$LANG.html /source/generated/input.md

chmod -R 777 /source/target/*

Запустим сборку и посмотрим на результат:

$ bin/convert.sh en linux
$ ls -lah target/
итого 92K
drwxrwxr-x 2 wiz  wiz  4,0K марта 12 20:55 .
drwxrwxr-x 7 wiz  wiz  4,0K марта 12 20:55 ..
-rwxrwxrwx 1 root root 1,9K марта 12 20:55 doc_linux.en.html
-rwxrwxrwx 1 root root  80K марта 12 20:55 doc_linux.en.pdf

Ветка с проектом: pres_0_12_4 https://github.com/wizardjedi/my-spring-learning/tree/pres_0_12_4

Шаг 5. Создание шаблона для построения русскоязычного PDF-файла.

Создавать PDF-файлы для английской версии документации мы научились, а вот с русской версией есть небольшая проблема. Latex не поддерживает русский язык по умолчанию. Необходимо добавить несколько инструкций к шаблону TeX документа, чтобы научить его видеть русский язык.

\usepackage[T2A]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[russian,english]{babel}
\usepackage[margin=1cm]{geometry}

Pandoc уже поставляется с множеством шаблонов, поэтому заберём шаблон по умолчанию из Pandoc и добавим необходимые инструкции.

$ mkdir templates
$ docker run --rm -it wizardjedi/pandoc-latex pandoc -D latex > templates/latex.tex

Внесём изменения и изменим сборку PDF-файла.

Теперь сборка рускоязычного PDF-файла проходить удачно.

Ветка pres_0_12_5 https://github.com/wizardjedi/my-spring-learning/tree/pres_0_12_5

Clone this wiki locally