知られているようで、案外知られていないかもしれないかもしれない(?)AppleScript ネタの整理。
最初にお断り。以下の文章内で「«」と「»」がでてきますが、「«」 は、Option キー + バックスラッシュキー。「»」 は、Option キー + Shift キー + バックスラッシュキー。HTML では、そのまま表示できない文字なので代替です。特に細かい部分を説明せずにずらずらと並べていきます。
まず、ダイアログを表示せずにログアウトするスクリプト。
tell application "loginwindow" to «event aevtrlgo»
次は、ファイル書き出し関連。まずは、以下のスクリプトを試してみます。
the clipboard as record
このスクリプトを実行する前に TextEdit なんかで複数のフォントや色を使った文字列をコピーしておきます。コピーしてから上記のスクリプトを実行すると結果の部分にずらずらっと AppleScript が表示できないデータが表示されます。このデータの中に «class utf8» とか «class rtf » 等があります。次のようにすると clipboard から UTF-8 で文字列を取り出すことができます。
«class utf8» of (the clipboard as record)
例えば、次のようにすることで UTF-8 でファイルに書き出すことができます。
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 ファイルとして書き出すこともできます(画像はついてきませんが)。
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 PARK の Tips に詳しいです。
通常、ハンドラは複数の引数と単一の戻り値で作られます。たとえば、先のファイル書き出しハンドラ writeFile(theFile, theData) は、二つの引数をとり、真偽値を返します。しかし、エラーが起きたときにはエラーの内容をダイアログで表示させたいときがあります。このようなとき、エラー番号とエラーメッセージを返すようにハンドラを変更するか、ハンドラ内でダイアログで表示する、という方法が考えられます。
上記のファイル書き出しハンドラなどでは、ダイアログを表示しても問題ないので困ることはないのですが、Image Events 等、一部のバックグラウンドアプリケーションは、tell ブロック内でダイアログを表示できないので困るときがあります。そこで、以下のようにして a reference to を用いてハンドラの返り値以外にエラー情報をやり取りします。
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 では、機能を制御する方法としていくつかのタグが用意されています。例えば、
say "100"
とすると、『One Hundred』とそのまま英語で読み上げます。これをそのまま数値として読ませるには、[[nmbr LTRL]] というタグを使います。
say "[[nmbr LTRL]]100"
こうすると、『One Zero Zero』と発話します。文字列をアルファベットとして読ませるには、[[char LTRL]] タグを使います。
say "[[char LTRL]]AppleScript"
使いたいタグを文中にそのまま埋め込むといいので、利用は至って簡単です。音量を変えたいときは、[[volm real]] を使います(real は、0.1 から 1.0 の実数)。早さを変えたいときは、[[rate int]] を使います(int は、140 から 210 の整数値)。
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 秒)。
say "To be or not to be. [[slnc 2000]]That is the question."
これで 2 秒間停止します。また、強調の [[emph -]] や [[emph +]] 等もあります。これらは、次のようにして組み合わせて指定することができます。
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 で探してみたけど、見当たらない。探し方が悪いのかな?
最後に。意外に知られていないのが、これ。
strings of {11, "A", "B", 112}
こうするとリストの中から文字列だけを取り出せます。他にも numbers、reals、integers、lists、records なんかも使えます。また、count 命令はクラスを指定することでそのクラスの数を数えることができます。
count of numbers in {11, "A", "B", 112, {10, 20, 30}, 1.2, 5.6}
そんなこんなで、今年はこれで最後です。では、また。