Over the last two articles, I have worked through producing a small website exported from Tinderbox 7, which I then turned into a Help Book for use in a Mac application. The end result not only works, but looks quite good, and is more than adequate for small apps.
It has one puzzling bug, in that HelpViewer appears unable to open its pages when they are returned from a search, and there are a few remaining rough edges. This article looks at how to tackle those, and how to neaten up this type of export. I’d like to thank Mark Anderson for suggesting most of these improvements.
First, the original method required a loose file, the CSS stylesheet, and needed minor surgery on the export folder to trash unused files and folders. With a little planning, we can get Tinderbox to write the stylesheet, and suppress its writing anything we don’t need.
Although you might not want to use Tinderbox to develop stylesheets, for this sort of project it’s a good place to store them. There’s a built-in prototype named Code, accessible from the Built-In Prototypes command in the File menu, which will start us off nicely. I added this, then made a note named
basic in which to keep
basic.css, and export it when ready to build the Help Book.
It needs its own export template, named
plain, which simply writes out the content of the note without further fuss.
I set that note to use the file extension
.css, to use the
plain export template, and not to export Markup Text. Another way that you could ensure that its output is not marked up is to write out
^value($Text)^ rather than
^text^, as I’ll discuss later.
With that set up, I simply pasted in the contents of my
InfoPlist.strings if you really want.
Suppressing the export of unwanted folders and files is even simpler. I noted how the Prototypes container was exported as a folder, and its prototypes as HTML files. Select the container and disable Export and Export Children, and that won’t happen again.
Another tweak which I have made is to provide links back to the
index.html page from each of the body pages, again using Quick Links. I don’t know how I survived without them in Tinderbox 6.
I noted in the last article how Apple’s HelpIndexer threw many errors, but still produced a usable Help Book. My next task was to try to eliminate those errors, in the hope that search would work properly.
I turned to the start of the (X)HTML export templates, and revised the code which preceded the header. Most rendering engines now accommodate a wide range of different headers, but it looks as if HelpIndexer and the command tool
hiutil are more pernickety than, say, WebKit.
That cleared many of the errors, but some related to the included images. Inspecting this carefully suggests that HelpIndexer expects the closing markup for an image to be />, rather than default >, so I made
$HTMLImageEnd a key attribute for the
BodyPage prototype and changed it to read />. Most of the standard markup for HTML can be customised in this way. If you are unsure what to change, Mark Anderson’s amazing Tinderbox Reference File, aTbRef, fills in details which are not in Tinderbox’s excellent documentation.
There was then just one remaining error when I ran HelpIndexer: I had foolishly exposed an ampersand.
This illustrates an important point with Tinderbox and export: there is a difference between using
^value($Text)^, and sometimes neither generates quite what you’d like. The screenshot shows me taking advantage of exporting
^text^, and working around an issue in doing so.
When you access the value of a String attribute, including
$Text, the main body text of a note, using (e.g.)
^value($Text)^, you get a plain text representation of what is there. You lose bold and italic markup, for example. If you want markup within that text, you’ll have to put it there yourself.
When you access
^text^, you get the same content, but with basic HTML markup for bold, italic, paragraph breaks, and so on. But that doesn’t extend to many character conversions, and it doesn’t of course include any custom markup, here using my stylesheet. In this section of text, this was causing a problem because I had an ampersand embedded, which was not being converted into the traditional HTML of
& so I have to mark that up in the note. But I can exploit the fact that < and > are not converted into their equivalents < and > and insert markup to use my custom Code style.
In some apps, navigating your way through what is converted and what is not can be a nightmare succession of trials and errors. Tinderbox has several great aids to help you: it has a light touch which can be tuned by settings and attributes, and you can readily see what your HTML is going to look like, and most importantly you can preview its appearance when rendered.
So you don’t have to export a note to inspect the HTML which will be generated when you do that.
And you can preview the rendered page using your stylesheet. These make the tuning of export templates and added markup much more reliable.
Not only does HelpIndexer now generate the index without any errors, but the added styling has significantly improved the readability of the Help Book.
The one area in which there remain issues is the custom handling of images. I have emphasised that HTML export does not attempt to scale images which you have placed in your notes, and there is no way to place the exported JPEG files in another folder, such as img. Mark Anderson much prefers working with external images, which can of course be kept in a separate folder. If that is important and you need better control, that is clearly the way to go.
For a basic Help Book like this, I much prefer the images to remain in my notes, and there shouldn’t be any need to tuck them into a different folder.
Build and test
Having created my new content and indexed it, I then incremented the version numbers in the Help Book’s
Info.plist file, gave the folder the magic
.help extension, and replaced the existing Help bundle in my Xcode project. I next ran a Clean to remove the previous built version of the app, to ensure that the new help file was included, and incremented the app’s version number.
Building and running that new version within Xcode confirmed my previous experience: the new version, with its superior Help Book, still accessed the old Help Book. Copying the built app to a folder in my Home folder made no difference either.
This is because HelpViewer is asked to access the Help Book by its identifier – in this case
co.eclecticlight.lockrattler.help. It then uses the information previously compiled by
helpd, which watches the /Applications folder, which still contained the previous version of LockRattler. So instead of using the new Help Book in the app’s bundle, HelpViewer kindly opened that in my old app’s bundle.
This was fixed by replacing the copy in my /Applications folder with the new version, which immediately found the right Help Book. And the search bug remains, unaffected by all this effort. I’ll be back when I’ve fixed it…