macdevcenter.com
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Creating Online Help with Tinderbox
Pages: 1, 2

Give Us the Tools and We Will Finish the Job

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.

Putting It Out There

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
    &nbsp;
   ^endif^
  </td>
  <td valign="top" align="right">
   ^if(^exists(nextSibling)^)^ 
    Next: 
    <a href="^URL(nextSibling)^">^Title(nextSibling)^</a>
   ^else
    &nbsp;
   ^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 a 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.

Final Steps

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 description 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 favorite language.)

The final Apple Help documentation was thus generated as follows:

  1. Quit Tinderbox (just to be on the safe side) and run the XML modification script on the Tinderbox document.
  2. Open the modified XML document with Tinderbox and export it to HTML. This creates a folder full of web pages.
  3. Add to the folder a 16-by-16 PNG to function as our application's icon in Help Viewer's Library menu.
  4. Drop the folder onto the Apple Help Indexing Tool.
  5. Drop the folder into the built Affrus application's package.

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.

Conclusion

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.