{"id":16,"date":"2009-05-11T15:23:53","date_gmt":"2009-05-11T20:23:53","guid":{"rendered":"http:\/\/developer.casgrain.com\/?p=16"},"modified":"2011-02-16T22:56:39","modified_gmt":"2011-02-17T03:56:39","slug":"day-four-integrating-help-in-your-application-using-voodoopad","status":"publish","type":"post","link":"http:\/\/developer.casgrain.com\/?p=16","title":{"rendered":"Day Four: Integrating Help in your application using VoodooPad"},"content":{"rendered":"<p><em>[Update September 12th, 2009: <a href=\"http:\/\/flyingmeat.com\/download\/latest\/voodoopadreleasenotes.html\">VoodooPad 4.2.2<\/a> fixes the one bug in this post. Thanks Gus!.]<\/em><br \/>\n<s><em>[Update June 28, 2009: there is an issue with the Help Indexer script and Snow Leopard. Contact me for the details, which only matter if you have Snow Leopard.]<\/em><\/s><em>[Update August 30th, 2009: now that Snow Leopard has been released, I updated the Help Indexer script to run with <code>hiutil<\/code>.]<\/em><\/p>\n<h3>Documentation<\/h3>\n<p>\nI&#8217;m a big fan of using the right tool for the right job, and I also found myself suffering from &#8220;blank page syndrome&#8221; when it came time to write initial documentation for <a href=\"http:\/\/apps.casgrain.com\/iChibi\/\">iChibi<\/a>.<\/p>\n<p>\nI really like <a href=\"http:\/\/flyingmeat.com\/voodoopad\/\">VoodooPad<\/a> for its ability to quickly transfer ideas from my head to some kind of structured document, which I am free to revise later.<\/p>\n<p>\nVoodooPad even has a web export module, which can create a set of pages that are compatible with Apple Help. Excellent! I could now overcome the blank page and start writing some documentation.<\/p>\n<h3>The process<\/h3>\n<p>If you write all your documentation in VoodooPad, you must follow these steps to create a valid Help folder to integrate in your application:<\/p>\n<ol>\n<li>Export the document to your Help folder.\n<\/li>\n<p><li>Open the main page of your document and insert the <a href=\"http:\/\/developer.apple.com\/documentation\/Carbon\/Conceptual\/ProvidingUserAssitAppleHelp\/user_help_concepts\/apple_help_concepts.html\">appropriate <code>AppleTitle<\/code> and <code>AppleIcon<\/code> tags<\/a>.\n<\/li>\n<p><li>Drag-and-drop your Help folder to Help Indexer (<code>\/Developer\/Applications\/Utilities\/Help Indexer.app<\/code>), to auto-generate the index.\n<\/li>\n<\/ol>\n<p>That&#8217;s still a lot of clicking.<\/p>\n<h3>Integrating with Xcode<\/h3>\n<p>In order to make sure that when I release software, I ship the latest of everything I like to add build phases to Xcode and have it perform all these tasks automatically. I sometimes run these scripts in Release builds only, because I don&#8217;t want to waste any time in the compile-link-debug cycle of a Debug build.<\/p>\n<p>\nHere is the script I use within Xcode. You can use it too, just add a new &#8220;Run Script&#8221; phase to your target:<\/p>\n<p>\n<img loading=\"lazy\" decoding=\"async\" src=\"\/images\/run_script_build_phase.gif\" width=\"878\" height=\"302\" hspace=\"4\" vspace=\"8\" alt=\"Run Script build phase in Xcode\"><\/p>\n<pre>\r\nif [[ ${CONFIGURATION} == \"Release\" ]]\r\nthen\r\n\t# Set to whatever you have as CFBundleHelpBook in your Info.plist\r\n\tHELP_FOLDER=\"$TARGET_BUILD_DIR\/$UNLOCALIZED_RESOURCES_FOLDER_PATH\/English.lproj\/Help\/\"\r\n\tHELP_DOC=\"iChibi Help.vpdoc\"\r\n\t# Clean folder, so we don't have extra junk in there\r\n\trm -r \"$HELP_FOLDER\"\r\n\techo \"Generating documentation...\"\r\n\topen \"$SRCROOT\/doc\/$HELP_DOC\"\r\n\tosascript -e \"tell application \\\"VoodooPad Pro\\\"\" \\\r\n\t\t-e \"tell document \\\"$HELP_DOC\\\"\" \\\r\n\t\t-e \"web export to \\\"$HELP_FOLDER\\\" with properties {fileExtension:\\\"html\\\"}\" \\\r\n\t\t-e \"end tell\" -e \"end tell\"\r\nfi<\/pre>\n<p>\n(You will want to replace the name and path of your VoodooPad Help document and output folder, of course.)<\/p>\n<p>\nWhat this does is delete the current Help folder, and re-generate it using AppleScript to tell VoodooPad to export the proper document to the Help folder.<\/p>\n<h3>But wait, there&#8217;s more!<\/h3>\n<p>In this Xcode build script, there is nothing about setting the <code>AppleTitle<\/code> or the <code>AppleIcon<\/code>, nor is there any Help Indexer. Those are all handled by VoodooPad using built-in scripts.<\/p>\n<p>\nVoodooPad&#8217;s Web Export behavior can be overriden by <a href=\"http:\/\/flyingmeat.com\/wikka\/VoodooPadAdvancedWebExport\">specially-named pages<\/a>:<\/p>\n<ul>\n<li>WebExportPageTemplate<br \/>\nThis page overrides the Export Module selection in the Web Export function.<br \/>\nThis is your basic html page, with extra markup for the actual page content (<code>$page$<\/code>). The only notable addition I made was to add two comments in the <code>&lt;head&gt;<\/code> section:<\/p>\n<p><pre>\r\n\t&lt;!-- AppleTitle --&gt;<br>\r\n\t&lt;!-- AppleIcon --&gt;\r\n<\/pre>\n<p>These will be used postflight script below.\n<\/li>\n<p><li>WebExportPostflightScript<br \/>\nThis page will be run as a shell script with a few interesting environment variables, notably <code>$VPWebExportOutputDirectory<\/code>. Here is the content of the page:<\/p>\n<p><pre>\r\n#!\/bin\/sh\r\n\r\n# Replace AppleTitle comment in index.html with appropriate value\r\nperl -pi -e 's\/&lt;!-- AppleTitle --&gt;\/&lt;meta name=\\\"AppleTitle\\\" content=\\\"iChibi Help\\\"&gt;\/' \"$VPWebExportOutputDirectory\/index.html\"\r\n\r\n# Replace AppleIcon comment in index.html with appropriate value\r\nperl -pi -e 's\/&lt;!-- AppleIcon --&gt;\/&lt;meta name=\\\"AppleIcon\\\" content=\\\"appicon16.png\\\"&gt;\/' \"$VPWebExportOutputDirectory\/index.html\"\r\n\r\n# Index documentation\r\nif [ -a \"\/usr\/bin\/hiutil\" ]; then\r\n  # Using hiutil on Snow Leopard\r\n  \/usr\/bin\/hiutil --create \"$VPWebExportOutputDirectory\"Help\/\" --file \"$VPWebExportOutputDirectory\"Help\/Help.helpindex\"\r\nelse\r\n  # Using Help Indexer.app\r\n  \"\/Developer\/Applications\/Utilities\/Help Indexer.app\/Contents\/MacOS\/Help Indexer\" \"$VPWebExportOutputDirectory\"Help\/\"\r\nfi\r\n\r\nexit 0\r\n\r\n<\/pre>\n<\/li>\n<\/ul>\n<p><em>Tip: in the Page Info, check &#8220;Skip on Export&#8221; for those two files since they are not needed by the Help Viewer.<\/em><\/p>\n<p>\nYou can <a href=\"\/files\/ichibi_help.zip\">download iChibi&#8217;s Help document<\/a> (VoodooPad format) and use it as a starting point for your Help document.<\/p>\n<p><a name=\"#Bugs\"><\/p>\n<h3>Bugs to iron out<\/h3>\n<p><\/a><\/p>\n<p><s><br \/>\nThe build script activates VoodooPad (brings it forward) and leaves the Web Export dialog active. You have to manually dismiss this dialog, or use AppleScript to tell VoodooPad to quit. I don&#8217;t like the heavy-handed &#8220;quit&#8221; approach because I may be working in other VoodooPad documents, and don&#8217;t want them to disappear even if they are auto-saved (thanks, VoodooPad!).<\/p>\n<p>\nThere is probably a way to dismiss the dialog using AppleScript and accessibility (e.g. <code>\"tell button 3 of dialog 'Web Export' to perform action\"<\/code>) but that strikes me as even more of a hack. I hope Gus can fix it in an upcoming release of VoodooPad :-).<br \/>\n<\/s><\/p>\n<p>\n<em>This is fixed in <a href=\"http:\/\/flyingmeat.com\/download\/latest\/voodoopadreleasenotes.html\">VoodooPad 4.2.2<\/a>.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>[Update September 12th, 2009: VoodooPad 4.2.2 fixes the one bug in this post. Thanks Gus!.] [Update June 28, 2009: there is an issue with the Help Indexer script and Snow Leopard. Contact me for the details, which only matter if you have Snow Leopard.][Update August 30th, 2009: now that Snow Leopard has been released, I [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-16","post","type-post","status-publish","format-standard","hentry","category-sixdays"],"_links":{"self":[{"href":"http:\/\/developer.casgrain.com\/index.php?rest_route=\/wp\/v2\/posts\/16","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/developer.casgrain.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/developer.casgrain.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/developer.casgrain.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/developer.casgrain.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=16"}],"version-history":[{"count":13,"href":"http:\/\/developer.casgrain.com\/index.php?rest_route=\/wp\/v2\/posts\/16\/revisions"}],"predecessor-version":[{"id":112,"href":"http:\/\/developer.casgrain.com\/index.php?rest_route=\/wp\/v2\/posts\/16\/revisions\/112"}],"wp:attachment":[{"href":"http:\/\/developer.casgrain.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=16"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/developer.casgrain.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=16"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/developer.casgrain.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=16"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}