When developer Mark Alldritt and I sat down to plan the documentation for Affrus, Late Night Software's new Perl editor and debugger, I made the following suggestion: "Let's not provide a 'narrative' document; let's use online help instead."
This article explains that suggestion, and describes how we ultimately constructed Affrus's online help using a note-taking hypertext outliner called Tinderbox.
A "narrative" help document, such as Mark and I had provided for Version 3 of Late Night's Script Debugger, is essentially an ebook –- a single document of some length, with numbered pages, divided into chapters and sections, presented to the user as a PDF file.
I liked the Script Debugger documentation, but the narrative format had turned out to have some disadvantages:
When I suggested using online help, Mark was skeptical; and this was not surprising. By "online help" I meant help done the official way -- Apple's way, also known as Apple Help. Apple Help has a bad reputation. In Mac OS 9, Apple Guide was a clunky mess; in the early years of Mac OS X, Help Viewer could take more than a minute just to launch. Users resented having to use Apple Help, and developers were correspondingly reluctant to include it.
But Panther's Help Viewer is free of the slow-launch problem; and, looking at the facts in the clear light of day, one sees that Apple Help actually offers several advantages:
Much of Apple Help's bad reputation these days is actually due, not to any systemic flaw, but to bad content. Writing clear, helpful web pages is not easy! In arguing for the Apple Help approach, I envisioned following certain guidelines that would make life easier for both author and reader:
Here's how some of these strictures ultimately manifested themselves in the layout of the Help pages:
Above, you can see one sort of very typical page. The page is mostly navigational in nature; it has some perfunctory content, and that content includes plenty of links. But mostly this page serves simply as a major heading. At the top are the "breadcrumbs"; at the bottom are the Further Details (downward) links and the Up, Previous, and Next links.
Now let's click the first Further Details link:
That is the other sort of typical page, containing actual explanation. The explanation is self-contained and confined to a single topic, it is direct and devoid of fluff, it is short enough to fit in the window without scrolling, and it relies heavily on links to other topics.
The next step was to decide what application we would use to write and generate the web pages that would constitute our Help Book. Initially I plumped for Frontier, now called Radio UserLand, a program that I knew well, and about which I had written a book. In the end, however, we opted for Eastgate's Tinderbox, which I had reviewed for TidBITS. (You might like to pause and read that review now, since it describes Tinderbox even more fully than I do here.)
Tinderbox turned out to be a wonderful choice. It has some limitations as to the nature of the HTML it can easily generate automatically; but it more than makes up for these by the ease with which it functions as a writing tool.
A Tinderbox document is an outline. Items may easily be added, deleted, and moved around the outline simply by dragging.
Each item of the outline is actually a page of styled text. The outline represents each page by its title; the styled text is what ultimately will form the content of the web page. In this text, you can use explicit HTML, but much of the time you don't have to: a paragraph will automatically be wrapped in <p> tags; bold text will get <b> tags, and italic text will get <i> tags. To insert a picture, you just paste it right in; on export to HTML, the picture will be transformed to a PNG along with an <img> tag referencing it.
Links (shown above as blue text in boxes) are easy to make: select the source text, choose Note > Create Link, and click on the outline item you want to link to. Links maintain themselves automatically as you edit the outline (moving outline items around, renaming them, and so forth), and can be copied and pasted.
As a word processor, Tinderbox is pretty rudimentary. But here its simplicity proved to be its virtue. I was able to create and edit the content for the Affrus help documentation very rapidly. I started with the outline; then, for each outline item, all I had to do was type and cut-and-paste and style in the usual way. Very little explicit HTML was needed. To add a picture, I just pasted it in. Most important, because links are so easy to create, I created lots of them. It also helped that Tinderbox provides rapid searchability for a document. Thus I was able to grow an extensive outline-structured, heavily hyperlinked document with amazing speed.
To generate actual web pages, you ask Tinderbox to export the document as HTML. (Tinderbox also lets you preview a single page as HTML, so you can see how things are going as you're developing the document.) The HTML export engine renders each page by pouring it through a template, which is simply a text document. The template contains the HTML for the page as a whole. It can also contain directives, which are instructions to the engine to perform certain functions or to make certain choices. The directive language is very limited and crude, but it was just sufficient to generate the ultimate HTML we wanted.
For example, here's the part of the template that generates the Previous and Next links for every page. The HTML describes a row of a table, consisting of two cells. If there is a previous sibling, the first cell contains the word Previous: followed by a link to that sibling, with the sibling's title as the text of the link. If there is a next sibling, the second cell contains the word Next:, followed by a link to that sibling. If there is neither a previous sibling nor a next sibling, the HTML is wrapped in comment delimiters, so that this row never appears in the table at all.
^if(^not(^exists(previousSibling))) ^if(^not(^exists(nextSibling))) <!-- ^endif ^endif <tr bgcolor="#DDDDDD"> <td width="50%" valign="top" align="left"> ^if(^exists(previousSibling)^)^ Previous: <a href="^URL(previousSibling)^">^Title(previousSibling)^</a> ^else ^endif^ </td> <td valign="top" align="right"> ^if(^exists(nextSibling)^)^ Next: <a href="^URL(nextSibling)^">^Title(nextSibling)^</a> ^else ^endif^ </td> </tr> ^if(^not(^exists(previousSibling))) ^if(^not(^exists(nextSibling))) --> ^endif ^endif
A Tinderbox outline item, aside from its position in the outline, its title, and its text, also contains attributes. An attribute is simply a name-value pair. Several dozen attributes exist by default, and the user can define others on a per-document basis. Thus, a Tinderbox document, in addition to being an outline, is also a kind of elementary flat-file database, where the items are "records" and the attributes are "fields".
Attributes were used to dictate special rendering for certain pages.
For example, the web pages were ultimately to be indexed by the Apple
Help Indexing Tool; this is what makes them searchable in Help Viewer.
But some pages, such as the Debugging page shown above,
don't have any significant content; therefore they should not be indexed,
so that they don't show up unnecessarily in the results of a user search.
The way you tell the Apple Help Indexing Tool not to index a page is
by including a ROBOTS NOINDEX tag in the page's HEAD area. So I created
noindex attribute, and set it to true in those pages I didn't want
indexed. That attribute was picked up by these lines in the template:
^if(^exists(noindex)^)^ <meta name="ROBOTS" content="NOINDEX"> ^endif^
Directives can also appear within a Tinderbox item's text. This was very
important to our export process; in particular, it's how we implemented
the requirement that, where feasible, duplication of text in different
pages was preferable to linking. This could not be accomplished simply
by copying and pasting the same text into different items, since that
would have engendered a maintainability nightmare. Rather, we used the
include directive to copy one page into another at rendering time.
One of the reasons we chose to use Tinderbox is that its documents are simply XML. The value of this was partly defensive: if Tinderbox suddenly vanished from the universe, none of our data would be lost. But we also used this XML proactively, to customize the HTML rendering process.
For example, when the user does a search in Help Viewer, each result consists of two parts: the found page's title, and the found page's description. This description comes from a meta-tag in the page's HTML:
<meta name="description" content="This page is really important!">
If a page lacks this tag, the search result will say "No description
available," and we didn't want that. So we wanted every page to
have a content string. But Tinderbox's directive language was too crude
to allow us to generate this string automatically at rendering time.
Therefore we created a
description attribute, whose value was to be picked
up by the template to form this tag. To assign every page's
attribute a value manually was unthinkable. Therefore we generated the
description value automatically, before rendering time, by means of a script
that modified the XML of the Tinderbox document. (It happens that I
wrote this script in Perl, but obviously you could use XSL or any other
The final Apple Help documentation was thus generated as follows:
Thanks to this architecture, Mark and I were able to work separately,
he on the application and I on the documentation, and conjoin our results
instantly. He had already set the
CFBundleHelpBookFolder entry in Affrus'
Info.plist file appropriately. Every once in a while, he would send
me an email asking for the path of a particular Help page that he wanted
to link to from an Affrus interface item; I'd give him this information,
and he'd code it into Affrus'
localizable.strings file. Thus, at anytime I could send him the latest version of the Help documentation;
he could drop it into the Affrus package and it would simply work.
Thanks to the current improvements in Help Viewer, online Apple Help is now a perfectly viable way for developers to provide their users with documentation, and has several strong advantages, such as searchability and the capability to link interface items in the application to particular Help pages. However, the onus is still on the documentation writer to provide good help. Without good tools, providing good help will be too much trouble, and the documentation (and the user's experience of the application) will suffer accordingly.
In Tinderbox, it's easy to create and rearrange the outline structure of the Help pages; text requires very little explicit HTML, pictures can just be pasted in, and links are extremely easy to create and maintain, so the author can concentrate on content and links. Tinderbox's HTML export engine is sufficient for generating good navigation between pages; page attributes allow the rendering of particular pages to be customized, and directives allow inclusion of one page within another. A Tinderbox document is just XML, so the document can be further customized if Tinderbox's own export engine falls short.
For Affrus' documentation, Tinderbox turned out to be an excellent choice. Thanks to Tinderbox, the documentation was easy to write quickly, easy to maintain, and easy to render as HTML. Developers may well wish to consider Tinderbox as their help authoring tool.
Matt Neuburg is the author of O'Reilly's "AppleScript: The Definitive Guide," "REALbasic: The Definitive Guide," and "Frontier: The Definitive Guide," and is a former editor of MacTech magazine.
Return to MacDevCenter.com.
Copyright © 2009 O'Reilly Media, Inc.