おばあちゃんの知恵袋

知られているようで、案外知られていないかもしれないかもしれない(?)AppleScript ネタの整理。

最初にお断り。以下の文章内で「«」と「»」がでてきますが、「«」 は、Option キー + バックスラッシュキー。「»」 は、Option キー + Shift キー + バックスラッシュキー。HTML では、そのまま表示できない文字なので代替です。特に細かい部分を説明せずにずらずらと並べていきます。

まず、ダイアログを表示せずにログアウトするスクリプト。

Script Editor で開く

tell application "loginwindow" to «event aevtrlgo»

次は、ファイル書き出し関連。まずは、以下のスクリプトを試してみます。

Script Editor で開く

the clipboard as record

このスクリプトを実行する前に TextEdit なんかで複数のフォントや色を使った文字列をコピーしておきます。コピーしてから上記のスクリプトを実行すると結果の部分にずらずらっと AppleScript が表示できないデータが表示されます。このデータの中に «class utf8» とか «class rtf » 等があります。次のようにすると clipboard から UTF-8 で文字列を取り出すことができます。

Script Editor で開く

«class utf8» of (the clipboard as record)

例えば、次のようにすることで UTF-8 でファイルに書き出すことができます。

Script Editor で開く

on writeFile(theFile, theData)
    set fh to open for access file theFile with write permission
    try
        set eof fh to 0
        write theData as «class utf8» to fh
        close access fh
        return true
    on error errMessage number errNumber
        try
            close access fh
        end try
        return false
    end try
end writeFile

読み込むときも同様で as «class utf8» で UTF-8 で読み込むことができます。また、Safari で表示している Web ページ等をコピーして次のようにして RTF ファイルとして書き出すこともできます(画像はついてきませんが)。

Script Editor で開く

set theData to «class RTF » of (the clipboard as record)

set theFile to (path to desktop folder as Unicode text) & "Write-RTF.rtf"
set fh to open for access file theFile with write permission
try
    set eof fh to 0
    write theData to fh
    close access fh
on error eMessage number eNumber
    try
        close access fh
    end try
    return {eNumber, eMessage}
end try

どんどん進みましょう。次は、a reference to について。

a reference to は、リストの処理を高速に行いたいときなどに使われることがよくありますが、ハンドラとのデータのやり取りに利用することができます。この辺りのことは AppleScript PARKTips に詳しいです。

通常、ハンドラは複数の引数と単一の戻り値で作られます。たとえば、先のファイル書き出しハンドラ writeFile(theFile, theData) は、二つの引数をとり、真偽値を返します。しかし、エラーが起きたときにはエラーの内容をダイアログで表示させたいときがあります。このようなとき、エラー番号とエラーメッセージを返すようにハンドラを変更するか、ハンドラ内でダイアログで表示する、という方法が考えられます。

上記のファイル書き出しハンドラなどでは、ダイアログを表示しても問題ないので困ることはないのですが、Image Events 等、一部のバックグラウンドアプリケーションは、tell ブロック内でダイアログを表示できないので困るときがあります。そこで、以下のようにして a reference to を用いてハンドラの返り値以外にエラー情報をやり取りします。

Script Editor で開く

on run
    set imageFile to choose file without invisibles
    set saveFile to choose file name
    set errorInfo to {|errorNumber|:missing value, |errorMessage|:missing value}
    set infoRef to a reference to errorInfo
    my resizeImage(imageFile, saveFile, 320, infoRef)
    errorInfo
end run

on resizeImage(theFile, saveFile, maxSize, theInfoRef)
    tell application "Image Events"
        try
            launch
            set imageRef to open file theFile
            scale imageRef to size maxSize
            save imageRef in file saveFile as JPEG without icon
            metadata tag "adfser" of imageRef -- わざとエラーを発生
            close imageRef
            return true
        on error eMessage number eNumber
            try
                close imageRef
            end try
            set contents of theInfoRef to {|errorNumber|:eNumber, |errorMessage|:eMessage}
            return false
        end try
    end tell
end resizeImage

このようにすると、ちゃんと処理が完了したかどうかは返り値で調べることができ、エラーが起きたときはエラーの内容を調べることができます。ハンドラには参照を渡し、ハンドラ内部では参照の内容を直接書き換える...と、まとめればこういうことです。a reference to の使い方としては、当たり前といえば当たり前なんですが、あまり話題にされることがないような利用方法だと思ったので...。あ、ちなみに個人的によく引っかかってしまうのですが、Image Events を使うときに最初に launch するのをよく忘れてしまいます。launch していないとエラーになるんですね。Image Events って。

毛色の変わったところで say コマンド。英語しかしゃべれない可愛いやつ(?)なんですが、say コマンドで発話のスピードを変更したり、数秒間止まらせたり...そんな方法の紹介。

say では、機能を制御する方法としていくつかのタグが用意されています。例えば、

Script Editor で開く

say "100"

とすると、『One Hundred』とそのまま英語で読み上げます。これをそのまま数値として読ませるには、[[nmbr LTRL]] というタグを使います。

Script Editor で開く

say "[[nmbr LTRL]]100"

こうすると、『One Zero Zero』と発話します。文字列をアルファベットとして読ませるには、[[char LTRL]] タグを使います。

Script Editor で開く

say "[[char LTRL]]AppleScript"

使いたいタグを文中にそのまま埋め込むといいので、利用は至って簡単です。音量を変えたいときは、[[volm real]] を使います(real は、0.1 から 1.0 の実数)。早さを変えたいときは、[[rate int]] を使います(int は、140 から 210 の整数値)。

Script Editor で開く

say "[[volm 0.1]]To be or not to be.[[volm 0.5]] That is the question." -- 音量
say "[[rate 140]]To be or not to be. That is the question." -- 遅く
say "[[rate 210]]To be or not to be. That is the question." -- 速く

読み上げている途中で一時停止させるには、[[slnc int]] を使います(int は、整数値。秒の指定。1000 で 1 秒)。

Script Editor で開く

say "To be or not to be. [[slnc 2000]]That is the question."

これで 2 秒間停止します。また、強調の [[emph -]] や [[emph +]] 等もあります。これらは、次のようにして組み合わせて指定することができます。

Script Editor で開く

say "[[volm 0.3 ; rate 165]]To be or not to be. [[volm 0.8 ; slnc 2000 ; rate 210]]That is the question."

他にも音程の調整等がありますが、これぐらいあれば英語の勉強(?)には十分でしょう。これらのタグは、Apple の資料に記載されているものですので、興味がある方は、参照してみるといいかもしれません。と、思って Apple Developer Connection で探してみたけど、見当たらない。探し方が悪いのかな?

最後に。意外に知られていないのが、これ。

Script Editor で開く

strings of {11, "A", "B", 112}

こうするとリストの中から文字列だけを取り出せます。他にも numbers、reals、integers、lists、records なんかも使えます。また、count 命令はクラスを指定することでそのクラスの数を数えることができます。

Script Editor で開く

count of numbers in {11, "A", "B", 112, {10, 20, 30}, 1.2, 5.6}

そんなこんなで、今年はこれで最後です。では、また。