Написание документации, часть IV: Texinfo

By Christoph Spiel



Texinfo -- основная система документации в проектах GNU.

Главная цель формата Texinfo -- создание из единого набора исходных файлов (.texi) документы и безупречно выглядящие при печати, и удобные для просмотра и навигации на экране компьютера. Основа высококачественной типографики достигается в Texinfo с помощью "военной хитрости": за основу взят plain TeX (основной язык TeX, как он описан Д. Кнутом. По сути -- это язык описания страниц и графического вывода вообще, как и более поздний язык PostScript. Надеюсь, я тут ни в чем особенно не наврал:) -- прим. перев.), который приспосабливается к специфике Texinfo после чтения файла texinfo.tex (В вашей системе может быть несколько копий этого файла. Проверьте, что используется свежая версия (на момент написания статьи -- 2002-01-04.07)). texinfo.tex выполняет всю работу по настройке TeX-форматирования. Он расширяет TeX, давая возможность распознавания гиперссылок и остальных "прибамбасов", нужных для экранной он-лайновой документации. Будучи скомпилированным для просмотра на экране, из исходника Texinfo получается файл Info (.info).

Info? Это что?

Info -- это файлы в ASCII-формате с возможностью перехода между связанными гиперссылками различными документами и удобные для просмотра на экране. При проектировании предполагалось, что формат будет переносимым между всеми платформами, на которых возможно выполнение программ проекта GNU. Info ориентирован на текст, так что файл Info можно просмотреть и в консоли текстового режима. Высококачественная графика доступна только при выводе на печать. Таким образом, формат Info дублирует возможности HTML, за вычетом некоторых графических добавок. Тем не менее, texi2html(1) может преобразовывать исходники Texinfo (.texi) непосредственно в HTML, о чем можно прочесть в разделе Средства просмотра.

Структура документа

Поскольку Texinfo основан на TeX (см. вторую из статей этой серии "LaTeX плюс latex2html" ), мы ожидаем еще раз столкнуться с делением на заголовок и тело документа. Кроме того, поддержка гиперссылок требует дополнительного структурирования, а именно так называемых узлов [nodes].

Общая структура

Каждый документ Texinfo начинается с команды plain TeX \input , читающей файл texinfo.tex. Это единственное место, где TeX "просачивается" в Texinfo. Часть файла, начиная с включения texinfo.tex и до так называемого корневого узла [Top node] -- об узлах мы поговорим позже -- составляет заголовок документа. Корневой узел или корень документа открывает собой тело документа, простирающееся до заключительной команды @bye.

Все команды Texinfo вводятся символом @ . За at-символом должна быть как минимум одна буква. Немногие команды нуждаются в фигурных скобках для группировки аргументов. С командой @bye, указывающей на конец документа, мы уже встречались. Приведенный ниже пример простейшего файла Texinfo вводит команду @c, обозначающую комментарий. Комментарии Texinfo продолжаются до конца строки, в которой они появились.

\input texinfo


@c === заголовок ===
...


@c === тело ===

@c --- Головной узел [Top Node] ---
...

@c --- Вложенные узлы ---
...


@bye

Заголовок

Заголовок -- необязательная часть файла Texinfo, но она появляется во всех документах. В ней по меньшей мере содержится имя выходного файла для просмотра на экране и заголовок, который используется при выводе на печать.

Имя выходного файла задается командой @setfilename output-filename. Я советую добавлять к имени-выходного-файла расширение .info, поскольку файлы с расширением удобнее для работы -- просто представьте результат ls *.info! Вся строка справа от @setfilename является аргументом команды, так что никаких комментариев после имени выходного файла. Кошмар!

Заголовок устанавливается командой @settitle заголовок-документа . Как и раньше, весь текст до конца строки является аргументом команды. Заголовок (как он задан командой @settitle ) используется для печати колонтитулов. Он не имеет ничего общего с названием документа, которое ставиться на первой странице (если таковая имеется).

Простейший заголовок выглядит так:

    @setfilename example.info

@settitle Пример Texinfo

Другие полезные в заголовках команды:

Совет: Все разработки GNU поставляются с документацией в формате Texinfo. Если вы хотите распечатать ее сами, то сначала лучше изменить заголовок файлов Texinfo в соответствии с применяемым размером бумаги (Letter, A4) и используемым оборудованием (принтер для двусторонней печати и т.д.).

Тело документа

Тело документа Texinfo представляет собой смесь команд секционирования, используемых при печати (части TeX-публикации: главы, разделы, подразделы и т.д.) и команд группировки, используемых при просмотре на экране (собственно Info: узлы [nodes]). Теоретически, каждая из этих двух "ипостасей" может задавать свою структуру документа. Такая ситуация, однако, может изрядно обескуражить читателя, а это, вероятно, не входит в план написания технической документации.

Я изложу упрощенный подход к созданию тела документа, в котором структура он-лайновой и печатной версий максимально близки. Ценой незначительного ограничения возможностей навигации это избавляет пишущего от головной боли ручной разбивки документа для экранного просмотра. Упрощенная метода требует, чтобы структура информации в Info-версии соответствовала структуре печатной версии.

Структура Info определяется командами @node node-name , в то время как структура печатного документа задается -- среди прочего -- командами @chapter chapter-title, @section section-title и @subsection subsection-title . Команда @node всегда появляется первой. Вот некоторые примеры:

    @node Введение
@chapter Введение

или

    @node Итеративные-процессы
@section Итеративные процессы

или

    @node Численная стабильность
@subsection Численная стабильность итеративных алгоритмов

Аргумент команды @node присваивает узлу имя node-name . Имя состоит из одного или более слов. Пробелы в node-name вполне допустимы, но точка ``.'', запятая ``,'', двоеточие ``:'' и апостроф ``'`` -- запрещены. В имени узла также рекомендуется избегать команд (чего-либо, начинающегося с "@"). Имена узлов чувствительны к регистру. В документе Texinfo каждый узел должен иметь уникальное имя. Существует соглашение, по которому слова в именах узлов начинают с заглавной буквы, как это делается в именах глав и разделов (автор имеет в виду традицию англо-язычной типографики, согласно которой все значимые слова -- существительные, прилагательные и глаголы, но не предлоги и артикли, пишут с заглавной буквы. прим. пер.).

Узел может либо содержать исключительно данные (а именно текст, таблицы, иллюстрации и перекрестные ссылки), либо узел должен определять меню навигации. Далее узлы "первого рода" я называю терминальными , а узлы второго рода -- узлами-меню.

Терминальные узлы

Структура терминального узла такова

@node имя-узла
@section заголовок-секции

текст-узла-главы

я воспользовался командой @section, как примером команды секционирования.

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

Узлы-меню

Узлы-меню обеспечивают "децентрализованные" оглавления (что уже является мета-информацией), из которых можно быстро "перескочить" к любому из перечисленных в меню разделов.

Структура узла-меню схожа с терминальным узлом за исключением того, что узел-меню заканчивается определением меню навигации. Меню навигации вставляется исключительно в Info-версию и никогда не появляется в печатной версии.

@node имя-узла
@chapter заголовок-главы

необязательный-вводный-текст-и-для-узла-и-для-главы

@menu
* Имя узла для первого раздела :: Синопсис первого раздела
* Имя узла для второго раздела :: Синопсис второго раздела
...
* Имя узла для последнего раздела :: Синопсис последнего раздела
@end menu

Меню навигации заключается "в скобки"

@menu

@end menu

и каждая строка между ними превращается в пункт меню. Каждый пункт должен начинаться с символа "звездочки" ``* '', за которым следует имя узла, на который этот пункт указывает [target node]. Далее идет двойное двоеточие ``::'', а за ним может помещаться необязательное краткое описание "указУемого" раздела:

* Имя раздела :: Необязательное описание раздела

Корень документа
Один узел-меню играет особую роль в каждом документе Texinfo: главный узел, которому "принадлежат" все остальные. Корень документа называется узлом Top и определяется двумя командами:
@node Top
@top имя-корневого-узла

Поскольку корневой узел оказывается первым каждый раз, когда документ загружается для просмотра на экране (если нет явного указания начинать просмотр с какого-либо иного узла), то желательно включить в него вводный текст. Такой вводный текст обычно не годится для печатной версии. Не забыли, что в печатной версии вообще нет меню? Поэтому нам надо исключить вводный текст из печатной версии, что достигается с помощью команд условной трансляции : парных команд @ifinfo и @end ifinfo. Несложный корневой узел выглядит следующим образом:

@ifinfo
@node Top
@top Пример
Это пример документа Texinfo.

@end ifinfo

@menu
* Имя первой главы:: Синопсис первой главы
* Имя второй главы:: Синопсис второй главы
* Имя третьей главы:: Синопсис третьей главы
@end menu

Вот мы и готовы написать полный документ Texinfo.

   
\input texinfo
@setfilename example.info
@settitle Texinfo Example

@ifinfo
@node Top
@top Пример
Это пример документа Texinfo.
@end ifinfo

@menu
* Введение:: Определения, Меры, Сложность
* Исчисление полиномов:: Изучение обычных операций
@end menu

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

@menu
* Определения:: Основы
* Меры эффективности:: Как измерять эффективность
* Ограничения сложности:: Типичные ограничения сложности
@end menu

@node Определения
@section Определения
...

@node Меры эффективности
@section Меры эффективности
...

@node Ограничения сложности
@section Ограничения сложности
...

@node Исчисление полиномов
@chapter Исчисление полиномов
...
@bye

Синтаксис

Мы уже заметили, что команды Texinfo начинаются с символа "собаки" -- "@". За ним либо следует единственный небуквенный символ, либо один или несколько букв. Вот несколько команд первой группы:

@@
Вставляет собственно символ коммерческого at ("@ ").
@"символ
Выводит "умляут-эквивалент" символа, где под символом понимается один из символов ASCII, например "a". То же самое относится к буквам, "украшенным" акцентами (@'символ ), циркумфлексом (@^символ) или цедилью (@,символ). За подробностями обратитесь к узлу "Вставка акцентов [Inserting Accents] в документации Texinfo.

а вот примеры из второй группы:

@contents
Вставляет содержание в месте вхождения команды @contents.
@page
Начинает новую страницу.
@findex имя-функции
Заносит имя-функции в индекс всех функций.

Команда может требовать один, два, три и более аргументов или не требовать их совсем. Некоторые команды требуют, чтобы аргументы заключались в фигурные скобки, например команда перекрестной ссылки @xref{имя-узла , имя-перекрестной-ссылки, заголовок-раздела }. Мы уже видели команды, считающими своим аргументом остаток той строки, в которой они появляются (например, команда @setfilename ).

Задание структуры и разбиение на разделы

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

Главные команды секционирования введены в разделе Тело документа. Команды @node группируют вводимый текст и разбивает его на куски, пригодные для чтения с экрана. Сопровождающие их TeX-подобные команды секционирования делают то же самое, но при печати. В частности, Texinfo предлагает следующие команды разделов: chapter, section , subsection и subsubsection .

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

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

Сделать приличную титульную страницу легко. Команда @titlepage , а также дополнительные команды [sub-commands] @title, @subtitle (необязательно) и @author, берут на себя заботы о компоновке титульной страницы. Если вы хотите, чтобы материал, следующий за титулом, располагался на нечетной странице -- нужно добавить разрыв страницы непосредственно после @end titlepage .

Пример:

    @titlepage

@title Образец документа Texinfo

@subtitle Пробуем, как Texinfo форматирует текст

@author Joanne H. Acker

@page @c -- начинаем последующий текст с нечетной страницы

@end titlepage

Условная трансляция

В разделе Корень документа мы столкнулись с командами условной трансляции @ifinfo/@end info . Условная трансляция означает, что определенные части документа направляются на вход только одного определенного транслятора (в нашем примере это makeinfo), или же, в случае @ifnotinfo/@end notinfo , что определенный транслятор не используется при обработке части документа.

На одной строке вместе с открывающей (@ifformat ) и закрывающей (@end format) последовательностью команд условной трансляции не должно быть больше ничего.

Имеются три парных директивы включения (исключения) части материала при конвертации документа в формат Info, TeX и HTML соответственно.

    @iftex

...

@end tex

    @ifinfo

...

@end info

    @ifhtml

...

@end html

    @ifnottex

...

@end nottex

    @ifnotinfo

...

@end notinfo

    @ifnothtml

...

@end nothtml

Списки

В Texinfo есть возможность создавать перечисления тех основных типов, которые ожидает найти любой автор: ненумерованные и нумерованные списки. Списки определений оформляются в терминах таблиц.

Все списки могут быть вложенными.

Команда @item начинает элемент списка или таблицы. Элемент списка может охватывать несколько абзацев текста или других списков. Я уже говорил, что все списки могут быть вложенными? Так и есть!

Ненумерованный список
@itemize маркер списка
@item Первый пункт
@item Второй пункт
...
@item Последний пункт
@end itemize

Символ маркера списка будет помещен перед каждым пунктом. Обычными у практичными вариантами маркера списка являются @bullet, @minus и * .

Нумерованные списки
@enumerate селектор нумератора
@item Первый пункт
@item Второй пункт
...
@item Последний пункт
@end enumerate

Селектор нумератора указывает тип счетчика (числовой или буквенный) и его начальное значение. Если селектор нумератора пропущен, то список будет оформлен с использованием арабских цифр начиная с единицыe.

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

Texinfo не умеет работать со списками, пронумерованные римскими цифрами.

Списки определений
Я уже упоминал, что в Texinfo нет поддержки "настоящих" списков определений и что такие списки эмулируются с помощью таблиц из двух колонок. Итак, для списков определений имеется следующий синтаксис:
@table селектор формата
@item Первый термин
Описание первого термина
@item Второй термин
Описание второго термина
...
@item Последний термин
Описание последнего термина
@end table

Селектор формата определяет, как будет выглядеть термин. Если вы, в случае простого списка определений, не хотите использовать дополнительного форматирования, то в качестве селектора формата следует использовать @asis. Если в качестве терминов оказываются элементы программного кода, примеры пользовательского ввода, программного вывода, переменных или комбинаций клавиш, то можно воспользоваться @code, @samp, @var или @kbd соответственно. За подробностями обращайтесь к разделу Прямое форматирование .

Внутри такой таблицы, аргументом @item служит весь текст от самой команды @item до конца строки. Обратите внимание на это отличие от ненумерованных и нумерованных списков! Определением в таком "списке определений" должно занимать не более одной строки. Текст после такой @item-строки и до следующего элемента @item или конца таблицы становится описанием термина. Описание может состоять из нескольких абзацев, содержать другие списки и т.д.

Поскольку иногда нам нужны дополнительные термины на отдельных строках. Поскольку @item помещает свой аргумент на одной строке, для этого требуется другая команда: @itemx помещает дополнительный термин непосредственно под уже существующим. Команда @itemx допустима только сразу после команд @item или @itemx.

Перекрестные ссылки

В формате Texinfo поддерживается несколько типов перекрестных ссылок: с дополнительным текстом и без него, ссылки в пределах одного и того же файла, на определенные места в других файлах Texinfo и, наконец, ссылки, указывающие куда-то "во внешний мир".

Узлы [Nodes] -- самые частые "мишени", на которые "нацеливаются" ссылки. Команда @anchor{имя-метки} создает в документе дополнительную метку [anchor], на которую можно ссылаться из другого места. Сама по себе команда @anchor в оттранслированном документе не видна. Имена меток не должны конфликтовать с именами узлов.

@xref

Вставляет "декорированную" перекрестную ссылку. Команда @xref создает оформление для ссылки в начале предложения.

Пример:

    ... является основой для нескольких многоточечных

методов. @xref{Multi-point Methods}. Мы

изучаем одноточечные методы ...

@pxref

@pxref ведет себя подобно @xref, но предназначен для использования внутри скобок.

Пример:

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

более высокого порядка (@pxref{Higher Order Root}) и

корней первого порядка, заданных неверными условиями.

@ref

Вставляет простую (не "декорированную") перекрестную ссылку. В остальном ведет себя подобно @xref.

До сих пор мы использовали команды создания перекрестных ссылок с одним аргументом. Команды эти, однако, могут принимать до пяти параметров. Ниже представлены примеры того, как, в зависимости от числа аргументов, изменяется внешний вид оттранслированного текста. Я привожу примеры "гибкого" использования команды @xref

Один аргумент
@xref{имя-метки}

дает на выходе

*Note имя-метки::

при трансляции в Info и

Смотри раздел имя-раздела [ имя-метки], страница номер-страницы

при трансляции для печати, здесь имя-радела и номер-страницы -- соответственно название раздела и номер страницы, где в версии для печати располагается метка "имя-метки".

Два аргумента
@xref{имя-метки, имя-перекрестной-ссылки}

после трансляции даст:

*Note имя-перекрестной-ссылки: имя-метки

и

Смотри раздел имя-раздела [ имя-метки], страница номер-страницы

Три аргумента
@xref{имя-метки, имя-перекрестной-ссылки, заголовок-темы }

дает:

*Note имя-перекрестной-ссылки: имя-метки

и

Смотри раздел имя-раздела [ заголовок-темы], страница номер-страницы

Пять аргументов
@xref{имя-метки, имя-перекрестной-ссылки, заголовок-темы , имя-файла-info, заголовок-печатного-руководства }

в результате трансляции получаем:

*Note имя-перекрестной-ссылки: (имя-файла-info)имя-метки

и

Смотри раздел "заголовок-темы " в заголовок-печатного-руководства

Прямое форматирование

Texinfo определяет обширный набор команд прямого или "физического" форматирования, помечающих части текста, как код, пользовательский ввод, имя файла и т.д.

Инструменты

makeinfo

makeinfo преобразует файлы Texinfo (.texi) в

  1. Файлы Info

    По умолчанию, makeinfo создает файл Info с именем, указанным параметром @setfilename. Опция --no-split не разрешает makeinfo дробить выходной файл на отдельные файлы [chunks] приблизительно по 50KB каждый.

    Помимо всего прочего, обработка файла Texinfo программой makeinfo тщательно проверяет его синтаксическую структуру.

  2. Текстовой файл ASCII

    Опция --no-headers требует от makeinfo создать простой текстовой ASCII-файл. Формат текстового файла полезен при вычитке экранной версии и удобен для проверки правописания с помощью, например, diction(1).

texi2html

По названию команды вы, наверное, уже догадались, что texi2html преобразует файлы Texinfo в HTML. С помощью опции -monolithic вывод осуществляется в виде одного файла. Другая опция, -split указывает создать отдельный файл для каждого узла.

По умолчанию texi2html транслирует секции @iftex и не использует разделы @ifinfo. С помощью опции -expandinfo можно получить противоположный результат.

Обратите внимание на то, что опции texi2html начинаются с одного дефиса.

texi2dvi

Создает из исходного файла Texinfo файл в независимом от устройства формате .dvi. Применение dvips(1) к файлу .dvi позволяет получить на выходе код Postscript. Я нахожу полезными опции --clean и --quiet. Первая удаляет промежуточные файлы, оставляя только файл .dvi. А вторая отключает вывод необязательных сообщений (тут автор использует "непереводимую игру слов": ``No gnews is good gnews!'', т.е. "Отсутствие гнуовостей -- хорошая гнуовость" -- прим. перев. ).

texi2pdf

texi2pdf за "один присест" создает из исходного файла Texinfo файл в формате Переносимого Документа [Portable Document File] ( .pdf). Можно использовать те же опции, что и в случае texi2dvi. Я, однако, заметил, что texi2pdf определенно требуется опция --pdf, иначе он останавливается, громко требуя файл .dvi , даже когда этот файл точно существует. Гр-р! Так что я обычно выполняю следующее:

    texi2pdf --quiet --clean --pdf foobar.texi

Программы просмотра (браузеры)

От других рассмотренных нами систем подготовки документации Texinfo отличается тем, что для целей экранного просмотра документы Texinfo могут быть транслированы в отличный от HTML формат, а именно -- в формат Info. Естественно, что для формата экранного просмотра требуется браузер!

info

info, прародитель всех браузеров Info, это простой, но, тем не менее, эффективный браузер просмотра файлов Info в консоли.

Для того, чтобы просмотреть страницы Info по теме Тема используйте вызов

    info Тема

Для просмотра файла Info файл-info к вызову info добавьте параметр --file=файл-info, где файл-info содержит полный путь к нужному файлу Info.

Если вы желаете начать просмотр с конкретного узла имя-node , добавьте параметр --node=имя-node.

Моя любимая ошибка -- смешивание темы с -- -- файлом-info, т.е. набор команды

    info ./cache-profiler.info

вместо подразумеваемого

    info --file=./cache-profiler.info

pinfo

Это основанный на curses(3) браузер с навигацией в стиле lynx(1). pinfo очень красиво раскрашивает страницы Info

emacs

Скриншот доказывает улучшение возможностей просмотра фалов Info в emacs 21.x.

Я знаю, что это лишь Emacs Info, но оно мне сильно-сильно нравится! Я его даже люблю!

Можно просмотреть установленную документацию в формате Info (`C-h i', info). Или же можно загрузить файл Info и командой Info-on-current-buffer превратить буфер в браузер Info (обратите внимание на заглавную букву "I"). Если нет желания переключаться между рабочими буферами и режимом просмотра Info, то можно открыть файл в режиме просмотра (`C-x 5 f', find-file-other-frame ). Для того, чтобы открыть новый фрейм с браузером Info, переключитесь в буфер *info* в текущем окне emacs и выполните команду view-buffer-other-frame.

Чтобы получить от "браузенья" дополнительное удовольствие, попробуйте команду Info-speedbar-browser.

xinfo

xinfo -- древнейшая программа для просмотра Info-файлов в среде X11. Цветовой разметки текста нет. Более всего меня в нем раздражает -- до такой степени, что я его никогда не использую -- то, что навигация и отображение полностью разделены. Я имею в виду, что для перехода по ссылке в одной панели, приходиться "кликать" мышью по панели верхнего уровня. Щелчки мыши по самому меню ни к чему не приводят.

Скриншот можно посмотреть здесь.

tkinfo

Ну, это мой любимый браузер Info для X! В нем есть все "приятности" info(1): он быстро стартует, а его окно удобно устроено.

gnome-help-browser

Если вы используете Gnome, то, наверное, знакомы сgnome-help-browser(1x) . В нем можно просматривать и страницы Info.

kdehelp

То же самое относится и к пользователям KDE... Вы, вероятно, знакомы с kdehelp(1x). Среди других форматов в нем поддерживается и страницы Info.

kdehelp легко убедить показать конкретный Info-файл:

    kdehelp ./cache-profiler.info

Просто на большой!

konqueror тоже показывает файлы info (по крайней мере konqueror 2.2.2): просто надо напечатать "info:" в строке адреса.

Обзор распространенных программ просмотра Info

Обзор распространенных Info-браузеров. "Поддержка других форматов" означает умение показывать документы в других форматах. "требует X11" означает, что программа работает только в среде X Window. "Навигация в стиле info " означает, что в программе дублируется команды навигации info(1) .
Приложение Поддержка других форматов требует X11 Навигация в стиле info
info нет нет да
pinfo нет нет нет
emacs нет нет да
xinfo нет да да
tkinfo нет да да
gnome-help-browser да да нет
kdehelp да да нет

Плюсы и минусы

За
Против

Дополнительные материалы

Домашняя страница Texinfo, на которой можно найти много справочной информации http://texinfo.org/

Существующие конвертеры Texinfo перечислены здесь: http://www.fido.de/kama/texinfo/texinfo-en.html

Кристоф Шпиль [Christoph Spiel]

Крис руководит расположенной в Верхней Баварии (Германия) компанией, консультирующей по вопросам Open Source Software. Не смотря на то, что по образованию он физик (он получил ученую степень Доктора Философии в Мюнхенском Технологическом Университете), его главные интересы вращаются вокруг численных методов, гетерогенных сред программирования и разработки программного обеспечения. Связаться с ним можно по адресу [email protected] .


Copyright (C) 2002, Christoph Spiel.
Copying license http://www.linuxgazette.com/copying.html
Published in Issue 76 of Linux Gazette, March 2002