MacのElectronアプリに、MacのHelp Bookを組み込む

Macでヘルプで検索した時に起動するアレ。Help Book。

MacでElectronアプリを作るのであれば、
Help Bookにヘルプ機能を作り込めば、よりMacライクなアプリになるのではないか。
そう考えてトライしたのであった。

作業手順

1. Help Bookを作る
2. ElectronアプリにHelp Bookを組み込む
3. ElectronアプリからHelp Bookを立ち上げる

Help Bookを作ろう

まず、ヘルプを作る。手順は下のようになる。
面倒くさい。
ヘルプ作成用のアプリを使った方が良いかもしれない。Help Crafter(http://www.putercraft.com) とか

1. ディレクトリ構造を組み立てる
2. ヘルプをHTMLで書く
3. 索引を作る
4. ExactMatch.plistを用意する


Help Bookの資料は、このあたりにあります。
https://developer.apple.com/library/archive/documentation/Carbon/Conceptual/ProvidingUserAssitAppleHelp/authoring_help/authoring_help_book.html
http://macwiki.osdn.jp/wiki/index.php/ヘルプ作成のノウハウ


ただ、これだけだと資料が足りない。
次の本にもHelp Bookの説明が書いてあるらしい。
https://www.amazon.co.jp/Cocoa-Recipes-Mac-OS-X-ebook/dp/B003HOXLGG

Help Bookのディレクトリ構造を作る

AppleのHelp Bookの資料は↓のようになっている。
なのだけど、ディレクトリ名とか、ヘルプファイルの置き場所は、推奨から変えても動作する。

SampleApp.help/
    Contents/
        Info.plist                  -- 設定
        Resources/
            shrd/                   -- アイコンなど共通の素材入れる
            index.html              -- トップページ
            search.helpindex        -- 索引
            ja.lproj/
                ExactMatch.plist    -- このキーワードで検索したら、このanchorに遷移させる、という設定
                InfoPlist.strings
                pgs/
                    about.html      -- ヘルプの各ページ
                    voicecode.html
                gfx/                -- 画像
                scrpt/              -- JavaScriptなど
                sty/                -- スタイルシート
ヘルプを書く

ヘルプはHTMLで書く。
SafariのHelp Bookをみると、割と新しいめのHTMLの書き方でも良いようです。
jQueryとか使ってた。
ハイパーリンクも、Help Book特有の書き方しなくて良い。

/Applications/Safari.app/Contents/Resources/Safari.help


HTMLは閉じタグが必要。
XMLとしてパースできないと、あとの索引作成の処理でエラーになる。

<html lang="ja">
<head>
  <meta charset="UTF-8" />
  <meta name="ROBOTS" content="ANCHORS" />
  <meta name="KEYWORDS" content="about" />
  <meta name="AppleIcon" content="shrd/icon.png" />
  <meta name="description" content="SampleAppについて" />
  <meta name="AppleTitle" content="SampleApp Help" />
  <title>SampleApp Help</title>
  <link rel="stylesheet" type="text/css" href="../assets/css/snap.css" />
  <link rel="stylesheet" type="text/css" href="../assets/css/nav.css" />
</head>
<body>
<div class="snap-drawers" id="sidebar">
  <div class="snap-drawer snap-drawer-left">
    <div>
      <h4>アプリに関わること</h4>
      <ul>
        <li><a href="apps-about.html">SampleAppについて</a></li>
        <li><a href="apps-voicecode.html">音声記号列</a></li>
        <li><a href="apps-trouble.html">トラブルシューティング</a></li>
        <li><a href="apps-update.html">アプリを更新するには</a></li>
        <li><a href="apps-uninstall.html">アンインストールするには</a></li>
        <li><a href="apps-backup.html">設定をバックアップするには</a></li>
        <li><a href="apps-license.html">AquesTalkのライセンスについて</a></li>
        <li><a href="apps-contact.html">連絡先</a></li>
      </ul>
    </div>
  </div>
  <div class="snap-drawer snap-drawer-right"></div>
</div>

<div id="content" class="snap-content">
  <div id="toolbar">
    <a href="#" id="open-left"></a>
    <h1>SampleApp Help</h1>

    <div class="docs">
      <a name="about"></a>
      SampleAppについて
    </div>

  </div>
</div>

<script src="../assets/js/snap.min.js"></script>
<script type="text/javascript" src="../assets/js/nav.js"></script>
</body>
</html>
索引を作る

hiutilコマンドを実行して索引ファイルを作る。拡張子は.helpindex
タイトルページと同じ場所に置く。

cd SampleApp.help/Contents/Resources/ja.lproj; hiutil -C -agv -f search.helpindex .
ExactMatch.plist

ExactMatch.plistで指定すると、あるキーで検索した時に指定したanchorが検索でヒットするようになる。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>about</key>
        <string>about</string>
        <key>ABOUT_SAMPLEAPP</key>
        <string>about</string>
    </dict>
</plist>


別に空っぽも良い。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
    </dict>
</plist>

ElectronアプリにHelp Bookを組み込もう

作ったHelp BookをクリックしてHelpViewerを起動しても、このままではヘルプは表示されない(うげー)。


システムにHelp Bookを登録する。
アプリのInfo.plistで指定しておくと、アプリ起動時に自動的に登録してくれる。

1. Info.plistでHelp Bookを指定する
2. アプリをビルドする
3. 作ったHelp Bookを、ElectronアプリのResourcesにコピーする
4. アプリを起動して、Help Bookを登録する
Info.plistでHelp Bookを指定する

このInfo.plistは、Help BookのInfo.plistではなくて、ElectronアプリのInfo.plist。


こんな感じのxmlファイルを用意して、

  • extend.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>CFBundleHelpBookFolder</key>
    <string>SampleApp.help</string>
    <key>CFBundleHelpBookName</key>
    <string>SampleApp Help</string>
  </dict>
</plist>
アプリをビルドする

作ったxmlファイルをextend-infoで指定して、Electronアプリをビルドする。
ElectronアプリのInfo.plistに書き加えられる。

electron-packager . SampleApp --platform=darwin --arch=x64 --electronVersion=2.0.8 --overwrite --asar.unpackDir=execmd --extend-info=extend.plist
作ったHelp Bookを、ElectronアプリのResourcesにコピーする

Help BookをElectronアプリのResources直下にコピーする。
Help Bookはアプリと一緒に配ることになる。

SampleApp.app/Contents/Resources/SampleApp.help
アプリを起動する

アプリを起動すると、Help Bookがシステムに登録されて、Help Bookをクリックした時に起動するようになる。
YATTAZE!!!

アプリからHelp Bookを起動する

さて、Help Bookを作ったのは良いが、
Electronアプリから起動するにはどうしたら良いだろう(えー)


AppleScriptを使うのが良いかな?
↓をマルパクリした。
http://piyocast.com/as/archives/2661


これでヘルプが起動した。

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

set anAppName to "SampleApp"
set aTargAnchor to "about"

set hRes to openHelpBook(anAppName, aTargAnchor) of me

on openHelpBook(anAppName, aTargAnchor)
    set locBookName to getHelpBook(anAppName) of me
    if locBookName = false then return false
    current application's NSHelpManager's sharedHelpManager()'s openHelpAnchor:aTargAnchor inBook:locBookName
end openHelpBook

on getHelpBook(anAppName)
    set aWorkspace to current application's NSWorkspace's sharedWorkspace()
    set appPath to aWorkspace's fullPathForApplication:anAppName
    if appPath is equal to missing value then return false

    set locBookName to (current application's NSBundle's bundleWithPath:appPath)'s objectForInfoDictionaryKey:"CFBundleHelpBookName"
    if locBookName is equal to missing value then return false
    return locBookName
end getHelpBook
var exec = require('child_process').exec
var epath = require('electron-path');

var unpackedPath = epath.getUnpackedPath();
var cmd = unpackedPath+ '/execmd/launch.scpt';

var el = document.getElementById('launch');
el.addEventListener('click', function(){
    exec('/usr/bin/osascript '+ cmd, {}, function(err, stdout, stderr) {
        //alert(err);
    });
});

完装した感想

さて、ElectronアプリにHelp Bookを組み込んだ感想ですが。

  • BrowserWindowでヘルプを表示するのに比べて、HelpViewerの起動が遅い。
  • 取り立てて、HelpViewer上のヘルプが読みやすいわけではない。
  • Help Bookにしたら、ヘルプを書きやすくなるようなこともない。
  • Macでしか動かない。
  • 一応、他のプラットフォームに流用が効くようにヘルプを書けなくもない。
  • 検索機能はついてる。


微妙かな!!


おわり。