|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
Introduction
This article will cover a number of topics, but it's main point is to show you how to get up an running with producing documentation using the DocBook help processor, and then creating customizations for producing plain html file for use on the web or offline, or in making a single Microsoft HTML Help file (.chm) for windows. By the end of the article I'll show you how to create and process your own DocBook file(s), customize the style sheets for it's output, and create a simple makefile to run the whole thing from a command line. The article will mention a number of technologies, and my aim is not to explain in detail how they work, but mainly explain how to use them to create html based documentation for Win32 (though much of this is generic to pretty much any OS that can run the various DocBook tools) systems. This is based on my experiences with DocBook in using it to produce the documentation for my VCF project that I spend much of my time on. DocBook is a very cool XML-based syntax that allows you to author documentation in a single format, and then run it through various processors to create your final documentation output. From a single DocBook source you can output html, PDF, latex, rtf, and many other formats. We'll focus on dealing with html and HTML Help. Once you have written your DocBook files you have a choice in how they are processed. The original way was through a DSSSL processor such as Jade or OpenJade. DSSSL has a lisp like syntax and is a bit unwieldy to use. The other way, and the one apparently most people use, is XSL style sheets run through an xsl processor, like xsltproc. You can use other processors for XSL but many of them will not work correctly, and xsltproc is nice because it doesn't require a Java runtime to be installed. I found this out the hard way after spending the better part of a day downloading and trying several different XSL processors! One of the many neat things about DocBook, is that from the single, plain text source, the customization style sheets can automatically produce index, table of contents, and all sorts of extra stuff, all without you having to put much effort into it in terms of extra writing in your documentation. Before we do anything though, we are going to have to get some tools set up. When working with DocBook on Windows, half the hassle is getting the tools and your environment set up right. So, first get the following tools:
Now open up your bash command line and type (you can do this via Start > Programs > Cygwin > Cygwin Bash Shell): xsltproc -version
You should get: $ xsltproc -version
Using libxml 20423, libxslt 10013 and libexslt 705
xsltproc was compiled against libxml 20417, libxslt 10013 and libexslt 705
libxslt 10013 was compiled against libxml 20417
libexslt 705 was compiled against libxml 20417
Or something similar. If you don't get this and instead see an error message you may have to go and get the libxslt package - see above about notes on the Cygwin installer. Now we can write a simple test. Create a file called simple.xml and copy and paste the following into it: <?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" >
<book>
<title>Simple Book</title>
<titleabbrev>Simple</titleabbrev>
<preface><title>Introduction</title>
<para>
Hello! Here's an introduction!
</para>
</preface>
<chapter><title>On Foo's</title>
<para>
Stuff about Foo's goes here.
</para>
</chapter>
<chapter><title>On Bars's</title>
<para>
Stuff about Bars's goes here.
</para>
</chapter>
</book>
This is a simple example that create a basic unit, a "book", and adds a title, preface, and two chapters. Your basic building blocks in terms of organizing the various sections are a book, a chapter, and a section. Chapters can nest under a book, and sections can nest under a chapter or another section. Paragraphs are wrapped with the To produce our html lets run this file through our XSL processor. To use the xsltproc program, you pass it the file name of an XSL style sheet to use, and a file name of the XML file to process. The file that gets processed must be a valid XML file, if not xsltproc will whine and complain and will not process it. Specifically, you must have the So lets type (assuming your DocBook XSL files are in the d:\docbook-xsl-1.60.1 directory ): xsltproc --nonet D:/docbook-xsl-1.60.1/htmlhelp/htmlhelp.xsl simple.xml
Running this will produce output like this $ xsltproc --nonet D:/dork/DocBook/xsl/htmlhelp/htmlhelp.xsl simple.xml
Attempt to load network entity http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd
Writing pr01.html for preface
Writing ch01.html for chapter
Writing ch02.html for chapter
Writing index.html for book
Writing htmlhelp.hhp
Writing toc.hhc
Now you can open up index.html in a browser and view your documentation!
The --nonet option tells xsltproc to not attempt to connect via the network and attempt to verify the DTD. I use this so I don't have to fight with producing documentation when I don't have a valid or reasonable fast network connection. For other kinds of XSL processing this may be an issue, but for DocBook processing --nonet seems to work just fine. The first thing you may want to do is break up your documentation into multiple files, as a single file may not be the easiest thing to work with. Luckily this is easy to do. If you create a two files, chap1.xml and chap2.xml, and copy and paste the following into chap1.xml <chapter><title>On Foo's</title>
<para>
Stuff about Foo's goes here.
</para>
</chapter>
And the following into chap2.xml <chapter><title>On Bars's</title>
<para>
Stuff about Bars's goes here.
</para>
</chapter>
And modify simple.xml's contents like so: <?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY chap1 SYSTEM "chap1.xml">
<!ENTITY chap2 SYSTEM "chap2.xml">
]>
The use of the xsltproc --nonet D:/docbook-xsl-1.60.1/htmlhelp/htmlhelp.xsl simple.xml
Again we get the same output as before and we have now broken apart our documentation into multiple files for easier editing. Now lets generate our chm. To do this we simply call the command line HTML help compiler (hhc.exe) and pass the generated hhp file. hhc htmlhelp.hhp
And voila! we now have our chm file:
Adding an indexNow that we can create out DocBook output and create our chm file, lets get a little fancier and add support for an index. In DocBook it's so simple we can do this in a single line, so let's modify simple.xml like so: <?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY chap1 SYSTEM "chap1.xml">
<!ENTITY chap2 SYSTEM "chap2.xml">
]>
This now gives indexing support. However to actually ensure an item is placed in the index, we have to indicate which items we want to mark as being indexed. Doing so is simple, we just use the chap1.xml: <chapter><title>On Foo's</title>
<para><indexterm><primary>About Foo's</primary></indexterm>
Stuff about Foo's goes here.
</para>
</chapter>
chap2.xml: <chapter><title>On Bars's</title>
<para><indexterm><primary>About Bar's</primary></indexterm>
Stuff about Bars's goes here.
</para>
</chapter>
Now just run it through the xsltproc to produce our html output. Then run the compile step again with hhc. Now one thing to note at this point, there seems to be a bug, because once you add index support, the HTML Help compiler will complain about a mysteriously missing ix01.html file. It will however properly generate the chm file, complete with indexing support, so I don't know what the deal is. However it can cause problems with other programs that may run the hhc program from a script as it will now return an error code, despite successfully creating the chm! We'll address this a bit more later on. And now for our obligatory screenshot:
Kewl! Now, lets add one more thing: how to produce a single html file, such as we might want if we were to use DocBook to write an article for CodeProject. To do this, we'll use the same XML file(s), remember, single documentation source, multiple outputs, but this time specify a different XSL style sheet to use. We will also not produce any chm file, but only a single html output file. To run the processor we simply type: xsltproc --nonet D:/docbook-xsl-1.60.1/html/docbook.xsl simple.xml
Note the change in style sheets, and the fact that it simply dumps the output to stdout. No worries though - we can just dump the output to a file like so: xsltproc --nonet D:/docbook-xsl-1.60.1/html/docbook.xsl simple.xml > simple.html
Now we can look out our DocBook documentation, complete with index!
More DocBook tagsAll right, up till now we've only seen some pretty basic usage of the various DocBook tags available. While I am not going to attempt to cover all of them, I will try cover some of the more useful one, at least in my experience. For a more thorough article on this, please see the online version of "DocBook: The Definitive Guide" from O'Reilly. Meta dataWith DocBook you can describe various peices of information about the documentation, such as the author, legal notices, book version, and copyright(s) notice. We start this by adding a <?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY chap1 SYSTEM "chap1.xml">
<!ENTITY chap2 SYSTEM "chap2.xml">
]>
Now we can add a quick legal notice, author, and copyright sections to our simple.xml file: <book>
<bookinfo>
<legalnotice>
<para>
Here a short legal notice: You agree that all your base
belongs to me!
</para>
</legalnotice>
<author>
<firstname>Bob</firstname>
<surname>Grey</surname>
</author>
<copyright>
<year>2003</year>
<year>2021</year>
<holder>Pennywise the Clown</holder>
</copyright>
</bookinfo>
<title>Simple Book</title>
<!-- ... -->
</book>
TablesTables are critical for just about any kind of documentation, and DocBook fully supports them. Lets add a simple one to our chap1.xml file: <chapter><title>On Foo's</title>
<para><indexterm><primary>About Foo's</primary></indexterm>
Stuff about Foo's goes here.
</para>
<para>And now for some data in a table:
<table frame="none" pgwide="1">
<tgroup cols="3" align="left" colsep="1" rowsep="1">
<thead>
<row>
<entry>Column 1</entry>
<entry>Column 2</entry>
<entry>Column 3</entry>
</row>
</thead>
<tbody>
<row>
<entry>Heres</entry>
<entry>A</entry>
<entry>Row entry!</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
</chapter>
Notice the
Note that DocBook automatically add table numbering for you and ties it to your chapters numbers. If we had 3 tables in chapter 2, we'd see them numbered as Table 2.1, Table 2.2, and Table 2.3. We'll see how to turn off the table numbering later on. LinksIn DocBook there are several way to link to things. I'll show you how to link to external URL's and to items within your DocBook documentation. To link to external URL's you use the chap2.xml: <chapter><title>On Bars's</title>
<para><indexterm><primary>About Bar's</primary></indexterm>
Stuff about Bars's goes here.
</para>
<para>To learn more about the wonderful world of Bar's look
<ulink url="http://www.google.com/search?q=Bars">
here
</ulink>
</para>
</chapter>
The GraphicsNow we certainly couldn't write documentation without graphics! Adding graphics into your documentation is accomplished with the chap2.xml: <chapter><title>On Bars's</title>
<para><indexterm><primary>About Bar's</primary></indexterm>
Stuff about Bars's goes here.
</para>
<para>To learn more about the wonderful world of Bar's look
<ulink url="http://www.google.com/search?q=Bars">
here
</ulink>
</para>
<para>
Don't forget: Graphics are important!
<graphic fileref="smiley.bmp"></graphic>
</para>
</chapter>
Note the NotesAdding notes is another really cool feature of DocBook. A note is a little paragraph that stands out, usual with some kind of extra, or special case documentation about a feature. For example: chap2.xml: <chapter><title>On Bars's</title>
<para><indexterm><primary>About Bar's</primary></indexterm>
Stuff about Bars's goes here.
</para>
<para>To learn more about the wonderful world of Bar's look
<ulink url="http://www.google.com/search?q=Bars">
here
</ulink>
</para>
<para>
Don't forget: Graphics are important!
<graphic fileref="smiley.bmp"></graphic>
</para>
<note>
Not only can DocBook do graphics, but it can handle notes as well!
Isn't that just cool?
</note>
</chapter>
DocBook renders this as:
Special FormattingIn general formatting is not something that is relevant to DocBook. The idea is that DocBook is for specifying content and formatting is handled via CSS style sheets. However there are a few tags you can use. For example, the most common is the chap1.xml file: <chapter><title>On Foo's</title>
<para><indexterm><primary>About Foo's</primary></indexterm>
Stuff about Foo's goes here.
</para>
<para>And now for some data in a table:
<table frame="none" pgwide="1">
<tgroup cols="3" align="left" colsep="1" rowsep="1">
<thead>
<row>
<entry>Column 1</entry>
<entry>Column 2</entry>
<entry>Column 3</entry>
</row>
</thead>
<tbody>
<row>
<entry>Heres</entry>
<entry>A</entry>
<entry>Row entry!</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
Not only are Foo's important to proper software development, but they are
critical to understanding the synergistic relationship between Neo
<emphasis>and</emphasis> Trinity.
</para>
</chapter>
DocBook renders it like so:
Plain text formattingSometimes you'll want to include program listings, or plain unformatted text, say a console dump to demonstrate a command line program. For source listing, a frequent way to do this is the chap1.xml file: <chapter><title>On Foo's</title>
<para><indexterm><primary>About Foo's</primary></indexterm>
Stuff about Foo's goes here.
</para>
<para>And now for some data in a table:
<table frame="none" pgwide="1">
<tgroup cols="3" align="left" colsep="1" rowsep="1">
<thead>
<row>
<entry>Column 1</entry>
<entry>Column 2</entry>
<entry>Column 3</entry>
</row>
</thead>
<tbody>
<row>
<entry>Heres</entry>
<entry>A</entry>
<entry>Row entry!</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
Not only are Foo's important to proper software development, but they are
critical to understanding the synergistic relationship between Neo
<emphasis>and</emphasis> Trinity.
</para>
<para>
Here's an example of a code listing:
<programlisting>
int foo = 12 * 23;
multiply_endlessly( foo );
</programlisting>
</para>
</chapter>
A frequent thing you need in a program listing is the use of the chap1.xml file: <chapter><title>On Foo's</title>
<para><indexterm><primary>About Foo's</primary></indexterm>
Stuff about Foo's goes here.
</para>
<para>And now for some data in a table:
<table frame="none" pgwide="1">
<tgroup cols="3" align="left" colsep="1" rowsep="1">
<thead>
<row>
<entry>Column 1</entry>
<entry>Column 2</entry>
<entry>Column 3</entry>
</row>
</thead>
<tbody>
<row>
<entry>Heres</entry>
<entry>A</entry>
<entry>Row entry!</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
Not only are Foo's important to proper software development, but they are
critical to understanding the synergistic relationship between Neo
<emphasis>and</emphasis> Trinity.
</para>
<para>
Here's an example of a code listing:
<programlisting>
<![CDATA[
int foo = 12 * 23;
std::vector<int> vec;
vec.push_back( foo );
]]>
</programlisting>
</para>
</chapter>
Using the FaqsWriting FAQ's is common with technical documentation, particularly if it is documentation that is destined for online usage. DocBook provides some neat tags that support this as well. To do this, lets create a new xml file, faqs.xml, and add the appropriate entity to our main xml file, like so: <?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY chap1 SYSTEM "chap1.xml">
<!ENTITY chap2 SYSTEM "chap2.xml">
<!ENTITY faqs SYSTEM "faqs.xml">
]>
Now edit your faqs.xml like so: <section><title>FAQs</title>
<qandaset><title></title>
<qandaentry>
</qandaentry>
</qandaset>
</section>
Faqs can be organized in question and answer sets, which provide a way to organize the individual questions and answers into logical groups. The sets can be broken into entries ( <section><title>FAQs</title>
<qandaset><title>The Big Questions</title>
<qandaentry>
<question>
<para>Why did the chicken cross the road?</para>
</question>
<answer>
<para>
To get to the chicken feed.
</para>
</answer>
<question>
<para>Will anyone, in fact, ever need more than 640K of memory?</para>
</question>
<answer>
<para>
Two words: "Doom III".
</para>
</answer>
</qandaentry>
</qandaset>
<qandaset><title>Even Bigger Questions!</title>
<qandaentry>
<question>
<para>Is Neo really the One?</para>
</question>
<answer>
<para>
That all depends on your perception of both reality, and your
understanding of sub-atomic quantum scale micro causality. In
addition, this will require a support call to Technical Support.
Please call 1-888-232-1NEO.
</para>
</answer>
<question>
<para>Is VB really cooler than C++?</para>
</question>
<answer>
<para>
No. Thanks for playing.
</para>
</answer>
</qandaentry>
</qandaset>
</section>
Save this, process it, and we see something like:
Customizing the Style SheetSo far we have covered the basics of producing our DocBook content, but at some point you're going to want to control what it's output looks like. As an example of what you can do, I humbly submit my own work with it, the VCF Documentation. This content is simply regular DocBook, but through heavy customization of the style sheets I have been able to control things like header, footers, CSS, where standard DocBook images are looked for, and even how internal links are formatted. So to get started lets create our style sheet, and call it simple.xsl. Then lets add the boiler plate basics: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:import href="D:/docbook-xsl-1.60.1/htmlhelp/htmlhelp.xsl"/>
</xsl:stylesheet>
Note the xsltproc --nonet simple.xsl simple.xml
This will now replace the default HTML Help style sheet with our custom style sheet, which we will now start to add our specific changes to. The style sheets use XSL which is, as I understand it, and I am by no means an expert here, a sort of XML like programming syntax that lets you tell the processor (in our case xsltproc) what to do with the XML tree that is built as a result of a successful parsing of the XML source file (in our case simple.xml). Our first customizations will be simple ones, where we'll see how to turn on (or off) various parameters that DocBook uses in it's style sheets. So the first thing we'll do is to ensure that the legal info we have is generated (and linked to) as a separate output file (in this case html). To do this we add the following: simple.xsl: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:import href="D:/docbook-xsl-1.60.1/htmlhelp/htmlhelp.xsl"/>
<xsl:param name="generate.legalnotice.link" select="1"/>
</xsl:stylesheet>
Note how we did this: by add a new line using the Next we'll make sure that the "Next" and "Back" navigation links at the bottom of each page is enabled. When generating HTML Help output, the default style sheet turns this off, meaning that we won't see it. We are going to turn it on here: simple.xsl: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:import href="D:/docbook-xsl-1.60.1/htmlhelp/htmlhelp.xsl"/>
<xsl:param name="generate.legalnotice.link" select="1"/>
<xsl:param name="suppress.navigation" select="0"/>
</xsl:stylesheet>
We select 0, or false, into the The next set will tell the DocBook to make use of the standard DocBook graphics for tags like | |||||||||||||||||||||||