Журнал LinuxFormat - перейти на главную

LXF87-88:DocBook

Материал из Linuxformat
Перейти к: навигация, поиск
Hardcore Linux Проверьте себя, участвуя в сложных проектах для продвинутых пользователей.

Содержание

DocBook: Пишем документацию

Что общего у ядра, FreeBSD, KDE и Gnome? Документация! Пол Хадсон рассказывает о новой технологии для ее написания.

Создание документации к программам всегда было пробле мой для программистов: ведь это же тупость – объяснять, как все работает, когда оно ослепительно-очевидно. Наши программы, естественно, всегда понятны нам, потому что мы сами их написали; но есть люди, до сих пор думающие, что компьютеры и программы – это какое-то колдовство. Поэтому необходимо кратко объяснить им, какие кнопки нажимать для выполнения нужных операций. На этом уроке мы изучим DocBook – формат написания документации. Он основан на XML, и с ним можно работать в любом текстовом редакторе. Он используется во многих крупных проектах, включая ядро Linux, FreeBSD и KDE, поэтому рано или поздно вы с ним столкнетесь.

В процессе урока мы будем документировать выдуманную игру Ловля мух. Если у вас еще нет открытого проекта, который вы могли бы задокументировать, то присоединяйтесь к уже существующему, или начните новый!

Ныряем в DocBook

DocBook (как XML) имеет строгую структуру, которой необходимо следовать, но она довольно понятна. Помните, что DocBook – это разновидность XML, разработанная специально для создания документации, поэтому его структурными элементами являются главы, разделы, заголовки, абзацы и так далее. Вот и все, что необходимо знать для создания нашей первой части документации: книги, состоящей из одной главы. Начнем:

 <?xml version=”1.0” ?>
 <!DOCTYPE book PUBLIC “-//OASIS//DTD DocBook XML
 V4.4//EN”
 “http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd”>
 <book>
    <title>Ловля мух!</title>
    <chapter id=”ch01”>
       <title>Введение</title>
       <sect1>
          <title> Добро пожаловать в лучшую в мире игру!</title>
          <para>Да, она действительно так хороша.</para>
       </sect1>
    </chapter>
 </book>

[Необходимо использовать кодировку UTF-8 или указать ее явно в тэге <?xml?> при помощи атрибута ‘encoding’, – прим. ред.] Тип DTD, который мы собираемся использовать – стандарт DocBook 4.4, доступный из сотворившей его организации Oasis. Если хотите, можете скопировать файл .dtd на свою машину – это немного ускорит вашу работу, потому что в противном случае вашему компьютеру для валидации документа придется копировать DTD из сети.

Разберем написанное: наша полностью законченная документация называется книгой (book). Как и большинство книг, она состоит из отдельных глав, разбитых на разделы. В нашем примере с Ловлей мух у нас могут быть следующие главы: Введение, Описание игрового процесса, Многопользовательская игра, Разрешение проблем и Контактная информация.

Каждая глава состоит из разделов и подразделов, это упрощает чтение материала. Например, раздел Многопользовательская игра' может состоять из секций ‘Запускаем сервер’, ‘Подсоединяемся к серверу’ и ‘Настраиваем брандмауэр’. ‘Запускаем сервер’ можно затем подразделить на ‘Выделенный сервер’, ‘Невыделенный сервер’, ‘Обнаружение вашего IP-адреса’ и так далее. В терминологии DocBook эти разделы называются ‘sections’ и вы можете выбирать из <sect1> (раздел верхнего уровня), <sect2>, <sect3> или <sect4>. Обычно в оглавление попадают только первые три уровня – четвертый чуть больше размером, чем жирный текст, и если вы поймаете себя на том, что вовсю используете <sect4>, то придется признать: ваша документация чересчур многословна!

Итак, книга <book> содержит главы <chapter>, которые содержат разделы <sect1>, содержащие подразделы <sect2>, в свою очередь, содержащие <sect3>, а те <sect4>. Вот как все может выглядеть:

 <chapter id=”ch01”>
    <title>Введение</title>
    <sect1>
       <title> Добро пожаловать в лучшую в мире игру!</title>
       <para>Да, она действительно так хороша.</para>
       <sect2>
          <title>Почему же она так хороша?</title>
          <para>На это есть множество причин!</para>
          <sect3>
             <title>Взрослым...</title>
             <para>Много крови, убийств и жутких моментов!</para>
          </sect3>
          <sect3>
             <title>Детям...</title>
             <para>Еще больше крови, убийств и жутких моментов!</para>
          </sect3>
       </sect2>
    </sect1>
 </chapter>

Необходимо строго соблюдать иерархию структуры – вы не можете создать <chapter>, затем сразу <sect3>, или же <sect3>, а затем <sect2>, как показано ниже:

 <chapter id=”ch01”>
    <sect3>
       <sect2>
          <title>Введение</title>
       </sect2>
    </sect3>
 </chapter>

И книга, и глава, и раздел могут иметь свой собственный <title>, то есть заголовок. После этого начинается основная работа: множество элементов <para>, каждый из которых представляет один текстовый абзац.

Как вы понимаете, разобраться с XML здесь не самое сложное – куда сложнее написать качественную документацию!

Структура абзаца

Скорая помощь

Вы можете использовать xmllint с параметром '-o, чтобы сохранить вывод в файле XML. Это особенно полезно, когда используется параметр --xpointer, так что xmllint выполняет директивы XInclude, а затем сохраняет скомбинированный файл.

Набор бесформенных абзацев – занятие нудное, но это легко исправляется тем, что DocBook предоставляет специальные тэги для форматирования. Кроме базовых элементов, типа нумерованных списков и выделения жирным шрифтом или курсивом, вы можете особо выделить листинги программ, цитаты других людей, экранные снимки и многое другое. У DocBook есть тэги для всего, что как-то связано с программами или компьютерами, так что он далеко не прост!

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

 <para>Чтобы организовать собственный сервер Ловли, вы
    <emphasis>должны</emphasis> открыть <acronym>TCP</acronym>
    порт 556 в брандмауэре. <emphasis role=”bold”>Внимание:</
    emphasis> мы не отвечаем за возможные последствия.</para>
 <para>Вы можете найти предустановленные настройки брандмауэра в
 файле <filename>firewall.config</filename> в каталоге с игрой.</para>
 <para>Если проблемы все еще есть, попытайтесь подключиться к
 нашему сайту для проверки брандмауэра
    <systemitem role=”url”>http://www.qaziqargs.com/firewall</
    systemitem>.</para>

Тэг <emphasis> задает либо жирный шрифт, либо курсив: если вы уточните его словом ‘bold’, то текст будет выделен жирным; в противном случае – курсивом. Элемент <systemitem> – довольно хитрый зверь: в зависимости от роли, он может хранить IP-адреса, доменные имена, имена пользователей и, как в моем примере, URL-ы. Кому интересно, знайте, что нет никаких способов указать «текст» ссылки (то есть фразу, которой она будет представлена в документе), потому что DocBook спроектирован для работы с любыми носителями, включая печатные (где, понятное дело, щелкать по URL бессмысленно!).

Мы уже рассмотрели тэги <para> и <title>, однако интерес представляют еще пять тэгов: <orderlist>, <itemizedlist>, <listitem>, <programlisting> и <screen>. Первые три связаны между собой, поэтому начнем с них: покажем, как сделать упорядоченный (нумерованный) и неупорядоченный список (где порядок элементов не важен):

 <para>Существует три способа погибнуть в игре Ловля мух:</para>
 <orderedlist>
   <listitem><para>Быть съеденным лягушкой</para></listitem>
    <listitem><para>Быть съеденным птицей</para></listitem>
    <listitem><para>Быть прихлопнутым мухобойкой</para></listitem>
 </orderedlist>
 <para>Если у вас в наличии один из следующих предметов, вы
 можете избежать смерти:</para>
 <itemizedlist>
    <listitem><para>Ружье</para></listitem>
    <listitem><para>Кустарник</para></listitem>
    <listitem><para>Слабительное</para></listitem>
 </itemizedlist>

Будь это HTML, то <orderlist> был бы <ol>, <listitem> стал бы <li> и так далее – невелика разница, только что тэги DocBook длиннее! Текст внутри <listitem> должен обрамляться тэгами <para>.

Элементы <programminglisting> и <screen> используются подобным образом, но они являются отдельными сущностями и могут быть поразному отформатированы при выводе, если потребуется. Например:

 <para>Для включения режима бессмертия в игре, войдите в консоь
 Ловли и наберите следующие коды:</para>
 <programlisting>
 idkfa
 iddqd
 idspispopd
 </programlisting>
 <para>Вы узнаете, что режим бессмертия активирован, когда увидите
 следующее
 сообщение на экране:</para>
 <screen>
 Сообщаем:
 режим бессмертия активирован!
 </screen>

Все символы-разделители сохраняются в элементах <programminglist> и <screen>, так что набранный вами текст будет отображен на экран в таком же виде.

Работа с несколькими главами

DocBook в роли нормативного формата

DocBook обычно считается «нормативным» форматом, то есть он не предлагается конечному потребителю. Для просмотра его необходимо преобразовать в другой формат. Это позволяет вам сосредоточиться на документации, а не на ее представлении.

LXF88_docbook1.png

DocBook XML как нормативный формат означает, что его можно конвертировать...

LXF88_docbook2.png

как в HTML...,

LXF88_docbook3.png

так и в PDF

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

Файл, в который включают другие файлы, использует стандарт XInclude, в котором вы можете определить URL, загружаемый при обработке файла. Это позволит вам переложить часть работы на коллег, а затем собрать все документы вместе. Чтобы распределить главы по отдельным файлам, ваша XML-книга должна выглядеть примерно так:

 <?xml version=”1.0”?>
 <!DOCTYPE book PUBLIC “-//OASIS//DTD DocBook XML
 V4.4//EN”
 “http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd”>
 <book>
    <title> Ловля мух!</title>
    <include xmlns=”http://www.w3.org/2001/XInclude”
 href=”chapter01.xml”/>
    <include xmlns=”http://www.w3.org/2001/XInclude”
 href=”chapter02.xml”/>
    <include xmlns=”http://www.w3.org/2001/XInclude”
 href=”chapter03.xml”/>
    <include xmlns=”http://www.w3.org/2001/XInclude”
 href=”chapter04.xml”/>
 </book>

Начало положено, но это не облегчит людям чтение: если вы скажете «смотри раздел 3 главы 4», то им придется искать, где находится это место. Обычно DocBook-конверторы создают оглавление, содержащее номера страниц (или HTML-ссылки), но такой подход требует, чтобы пользователи поднимались к оглавлению, находили ссылку, переходили по ней, а затем нажимали кнопку Назад два раза, чтобы вернуться туда, откуда пришли.

Мы можем облегчить им задачу, используя тэг <xref>, позволяющий делать ссылки на главы, разделы и некоторые другие блоки. Взглянув на наш первый пример с книгой, вы заметите строку:

<chapter id=”ch01”>

Именно атрибут “id” позволяет нам устанавливать ссылки. Например, если мы хотим сделать ссылку на главу 1, то можем написать следующее:

<para>Если ваша игра не устанавливается, вернитесь и прочтите
инструкции в <xref linkend=”ch01” />.</para>

Нам не требуется писать «прочтите инструкции в главе 1» – такой текст будет получен после преобразования документа в требуемый формат. Например, если документ преобразуется в HTML, <xref> станет гиперссылкой с текстом типа «главе Руководство по установке», указывающей на начало этой самой главы.

Можно применить атрибуты id и к разделам, но когда вы делаете ссылки на отдельные блоки <para>, ссылки обычно создаются на начало раздела, содержащего требуемый блок.

Оформление страницы

Скорая помощь

Если вы хотите сравнить два XML-документа, используйте xmldiff, а не обычную утилиту diff. xmldiff запрограммирована так, чтобы находить разницу в структуре, а не просто разницу текстов.

Документация – это не только текст. На самом деле, из проповедей Кэти Сиерра вы узнаете, что текст – лишь небольшая часть вашей работы! DocBook позволяет добавлять таблицы и картинки, а если вы добавите к ним атрибут id, то сможете ссылаться на них с помощью тэга <xref>.

Чтобы вставить рисунок, нам необходим сам рисунок и подпись к нему. Вот как это выглядит в DocBook XML:

 <figure id=”ch01-fig12”>
    <title>Муха-гигант охотится за человеком</title>
    <graphic fileref=”figs/mxkyl.png”/>
 </figure>

Обратите внимание на атрибут id: сначала указан номер главы, а затем номер рисунка. Такой формат необязателен, но с ним удобнее отслеживать рисунки в большом проекте.

Работать с таблицами немного сложнее, потому что нам необходимо определить тип требуемой таблицы, указать, сколько в ней столбцов и строк и, наконец, ввести содержимое ячеек. Простейшая таблица выглядит так:

 <informaltable>
    <tgroup cols=”2”>
       <tbody>
       <row>
          <entry>F1</entry>
          <entry>Помощь</entry>
       </row>
       <row>
          <entry>F2</entry>
          <entry>Сменить оружие</entry>
       </row>
       </tbody>
    </tgroup>
 </informaltable>

В терминах HTML, <informaltable> – это <table>, <row><tr>, а <entry><td>. Мы можем превратить нашу <informaltable> в обычную таблицу <table> с добавлением заголовка:

 <table>
    <title>Клавиатурные сокращения</title>
    <tgroup cols=”2”>

Исходя из наличия элемента <tbody>, можно предположить, что должен быть и элемент <thead>, определяющий заголовки столбцов. Наша таблица хранит названия клавиш и их действия; ее можно модифицировать следующим образом:

 <table>
    <title>Клавиатурные сокращения</title>
    <tgroup cols=”2”>
       <thead>
          <row>
             <entry>Клавиша</entry>
             <entry>Действие</entry>
          </row>
       </thead>
       <tbody>

Как <thead>, так и <tbody> существуют и в HTML (впрочем, используются там нечасто), так что они могут быть вам уже знакомы.

Проверка и преобразование

Скорая помощь

Вы можете заставить tidy автоматически преобразовывать HTML в XHTML, если хотите, но для этого ей может понадобиться CSS.

На вашей улице праздник: документация готова! Все, что осталось сделать – это раздобыть пользователей, способных в уме преобразовать XML в человеко-читаемый вид. Или поступить умнее: выполнить это преобразование автоматически. Если вы не издатель, то, скорее всего, выберете в качестве выходного формата HTML, тем более, что средства, позволяющие выполнить эту работу, наверняка у вас уже есть.

В Linux это инструменты xmllint (часть libxml2library, включенной на наш DVD) и xmlto. Первая утилита выполняет проверку синтаксиса и валидацию вашей книги. Вторая утилита – XML-конвертор, она позволит создать HTML из DocBook. Обе утилиты доступны в большинстве дистрибутивов (включая Fedora, SUSE и Ubuntu), хотя вы можете найти, что xmlto требует довольно много места на диске, поскольку устанавливает LaTeX, необходимый для создания выходных файлов в формате PDF.

Для начала проверим наш XML-файл:

xmllint --noout ch01.xml

Параметр --noout предписывает не выводить ваш XML-файл на экран, а печатать только возможные ошибки. Если XML-файл корректен, то на экран ничего не выведется. С помощью этой команды xmllint проверяет, является ли ch01.xml правильно сформированным XML ['все тэги закрыты и т.п., – прим. ред.]. Однако он не проверит, является ли этот документ правильным документом DocBook XML [<sect3> всегда идет после <sect2> и т.п., – прим. ред.]. Чтобы это сделать, необходимо запустить команду:

xmllint --valid --noout book.xml

Теперь xmllint скопирует из сети DTD и выполнит валидацию на его основе. На этот раз вы можете увидеть кучу ошибок. Что же случилось? Наш XML-файл – это контейнер для четырех глав, использующий XInclude, который является отдельным стандартом. Пытаясь проверить Xinclude на соответствие DocBook DTD, мы не получим ничего, кроме ошибок.

XML редакторы

Вы можете набирать XML, используя любой текстовый редактор – это одно из его преимуществ. Некоторые текстовые редакторы (вроде Kate) умеют подсвечивать синтаксис, что позволяет выявить ошибки. Другие, типа Conglomerate, просто путаются под ногами со своими ошибками. Редактор Oxygen XML получил 9/10 в нашем обзоре – посмотрим, что скажете вы!

Решение – попросить xmllint обработать директивы XInclude (то есть включить XML-файлы в book.xml), а уж затем проверять получившийся документ. Вот команда, которая это осуществляет:

xmllint --xinclude --postvalid --noout book.xml

Если все будет хорошо, никаких сообщений от xmllint не появится – это значит, что ваш XML-документ прошел валидацию и готов к выводу!

Использовать конвертор xmlto легко: укажите желаемый тип файла для вывода, а потом имя файла. Об Xinclude не волнуйтесь, все будет сделано автоматически. Для преобразования документа в формат, например, PDF, команда будет такой:

xmlto pdf book.xml

Вместо pdf можете подставить одно из следующих значений: html (каждая глава будет находиться в собственном файле), html-nochunks (весь текст будет помещен в один документ), man, txt (обычный текст), xhtml и xhtml-nochunks.

Ложка дегтя в xmlto – отсутствие «красивого» вывода (pretty print). Проблема невелика, так как в web-браузере HTML-формат смотрится нормально, но если вы собираетесь вручную редактировать HTML-код, она может стать большой.

Для ее решения существует программа tidy, имеющаяся в менеджере пакетов большинства дистрибутивов. Небольшая программа призвана получить на вход набитый тэгами (X)HTML файл и реализовать все эти табуляции, переводы строки и верхние регистры. Установив tidy, запустите ее следующим образом:

tidy -mqci book.html

Параметр m сообщает tidy, что файл book.xml надо модифицировать прямо на месте, q подавляет вывод ненужных сообщений, c очищает код, а i вставляет отступы, создавая визуальную структуру. Команда отработает, и ваш труд окончен: документация написана, преобразована в HTML и подготовлена для дальнейшего выпуска. Можете развалиться в кресле, ожидая аплодисментов… LXF

Печатаем код

Если ваш код или экранный вывод включает символы, которые поставят XML в тупик (а именно <, > или ), то лучше обрамлять их тэгом CDATA – это XML-тэг для необрабатываемых символьных данных. Вот как это выглядит:

 <programlisting>
 <![CDATA[
 set Name = “<b>Квадзилла</b>”;
 ]]>
 </programlisting>

То, что внутри CDATA, не игнорируется (в смысле, идет на вывод), но и не обрабатывается как XML.

Персональные инструменты
купить
подписаться
Яндекс.Метрика