Archive for the 'AppleScript Studio' Category

2014/11/07 「AppleScriptの穴」の方針転換〜Framework活用します

AppleScriptの命令拡張を行うOSAXという仕組み

AppleScriptは、Classic Mac OSの仕組みを長く引きずってきたために、Classic Mac OSの機能拡張と同様、「スクリプティング機能拡張」(OSAX:Open Scripting Architecture eXtension)をインストールすることで命令を追加する仕組みになってきました。

osax1.png

▲/System/Library/ScriptingAdditionsに入っているOS標準のOSAX

osax2.png

▲/Library/ScriptingAdditionsに入っているサードバーティのOSAX。Adobe関連のものは勝手に入るのでXMLLib OSAXしか自分では入れていない

OSAXはたしかに便利な存在ではありました。インストールさえすれば、自分で書かなくても便利な命令がすぐに使えるようになり、シリアルポートにつないだ機器のコントロールなど、AppleScriptが標準で持たないさまざまな機能を手軽に利用してきました。

しかし、OSAXをインストールしすぎると予約語が衝突(コンフリクト)することもありましたし、せっかくAppleScriptを書いてもOASXの配布に制約が生じている場合には、OASXごと再配布したり納品することもできませんでした。便利なだけではなかったのです。

Mac OS X移行時にOSAX非依存へ方針転換

このため、2001年前後のClassic Mac OSからMac OS Xへの移行時に「OSAXを極力使わない」という方針転換をしました。それまで、システムに200個以上のOSAXをインストールして使っていた自分としては大々的な方針転換です。

当時、「これがなければまともなAppleScriptは書けない」と言われたほど全世界のScripterが依存しまくっていた「Tanaka’s OSAX」を使用しない、という決断をしたわけで、ひじょーに重要な決断です。

自前で各種ライブラリを整備し、OSAX、FileMaker Pro、Jeditに依存しない処理がじょじょに行えるようになってきことから、のちにXcode上でAppleScriptのプログラムを作れる「AppleScript Studio」の仕組みが出てきたときにも、作りためたルーチンが威力を発揮しました。再配布可能な自作のライブラリ群により、GUIベースのアプリケーションが手軽に作れて配布可能になっていたためです。

OSAX自体の開発についてはMac OS Xの誕生当時にCarbonベースで開発リソース(API、資料、サンプルコード)が提供されてきたものの、時代が流れてアプリケーション開発がCarbonからCocoaへ、32bitから64bitへ、PowerPCからIntelへと何度も移行を重ねるうちに、提供されなくなっていきました。

必然的に、サードパーティのOSAXも減っていきました。

OSAX非依存路線への転換は個人的には大正解だったわけですが、AppleScriptの命令拡張を行いたいというScripter側のニーズは満たされないままの状態が続いていました。

OASXの穴を埋めるAppleScript Libraries、ASOC

OS X 10.9でもたらされたAppleScript Librariesの仕組みにより、「AppleScript単体でAppleScriptの命令語を拡張できる」状態になり、OSAXの存在意義がほぼなくなりました。AppleScript LibrariesはAppleScriptObjCでも記述できるため、Cocoaの機能を呼び出すようなものも作れます(オーディオ入出力先の切り替えを瞬時に行うLibrariesを作って便利に使っています)。

さらにOS X 10.10でも大きな変化がもたらされました。通常のAppleScriptにScripting Bridgeが導入されたことで、通常のAppleScriptでCocoaの機能にダイレクトにアクセスできるようになりました。

ただ、この現在の仕組みを支えるScripting Bridgeはまだ修正が必要、とくにASとASOCとの間での値の変換に問題を抱えています(小数点以下の値を含む数値リストの変換時に丸め誤差が出る)。腰の重いAppleのことですから、すぐに修正されたりはしないでしょう。とても困ります。

ASOCとASの橋渡しを円滑化するASObjCExtras.Frameworkを全面的に採用

これまでのサードパーティ製OSAXやフレームワークへの非依存を一部あらため、本ブログ「AppleScriptの穴」〜ひいてはPiyomaru Software自身の開発においてはShane StanleyのASObjCExtras.Frameworkを標準採用することにしました

framework.png
▲/Library/Frameworksか~/Library/FrameworksにインストールするASObjCExtras.Framework

同フレームワークを用いることで、現在のScripting Bridgeが内包しているバグを回避することができるようになり、よりAppleScriptとASOCの相互運用性が高まります。

同フレームワークは再配布無制限で、コードサインも行われていないため、自分で作ったAppleScriptのバンドル中に入れてコードサインすることも可能です。

本日、Shaneから依頼されてチェックやら評価を行ってきたASObjCExtras.Frameworkの最新版(v1.1.0)が、以下のページからダウンロードできるようになったためお知らせします。

http://www.macosxautomation.com/applescript/apps/ASObjCExtras.html

2010/05/04 Xcode 3.2.2+Snow LeopardでAppleScript Studio環境を復活させる

Twitter経由で、「AppleScript applications with Xcode 3.2.2」なる記事を見つけました。

記事を読んで、最初はわけが分からなかったのですが……以下の手順でできることを確認しました。

(1)S.J. Louw氏が配布している「AppleScript-App-Templates-Xcode32.pkg」をダウンロードしてインストール。「Download Link」の文字が、黒地にグレーの文字で見つけにくいので要注意!!

downlink.jpg
▲視力検査なのか?!

inst0.jpg

(2)Terminal上で、「defaults write com.apple.InterfaceBuilder3 IBEnableAppleScriptStudioSupport -bool YES」を実行

inst011.jpg

(3)Xcode 3.2.2を起動して、「Application」テンプレートの中に新たにできた「AppleScript Application」をクリック

ass1.jpg

以下、従来どおりのAppleScript Studio環境(Xcode+Interface Builder)がMac OS X 10.6.3+Xcode 3.2.2の環境で使えることを確認しました。

ただ、Interface Builder上で使用できるGUI部品に一部制限があるようで、新しいルック&フィールをベースにしたGUI部品はAppleScript Studio環境では表示されなかったりします。

それでも、AppleScript Studio環境がMac OS X 10.6上で使用できることの意義は大きいと思います。長い目で見ればAppleScript ObjCに移行した方が「できること」が大幅に増えるので、移行すべきだとは思うのですが……そうそう急にAppleScript ObjCによる開発の仕事が発生するものでもないですし(汗)

以下、インストール手順を紹介します。

inst011.jpg

TerminalからAppleScript Studio復活コマンドを実行。以前からAppleがこれを紹介していたが、そのとおりにやってもASSは復活しなかった。Appleはダンマリを決め込んだまま……。ちなみに、これってインストーラーパッケージの中で実行するようにしておけばいいんじゃないかと>S.J. Louw氏

注釈:S.J.Louw氏本人からコメントがあって、「インストーラのScript中で実行しているから、わざわざコマンドラインで実行する必要はないよ」だそうです(汗) 話が早くてけっこうなことで。

inst1.jpg

▲インストーラをダウンロードして実行

inst2.jpg

▲Xcodeが起動中であればいったん終了させてくれ、とメッセージ表示。Interface Builderも同様

ass1.jpg

▲なつかしの、AppleScript Studioテンプレートが選択可能に

ass2.jpg

▲Xcode 3.2.2上でAppleScript Studioプロジェクトを新規作成したところ

ass3.jpg

▲XcodeでXibファイルをダブルクリックしてInterface Builderを起動。IBのインスペクタでAppleScript Studioの各種イベントハンドラが指定可能になっていることを確認できます

ass4.jpg

▲かる〜いご挨拶。これ1行を書いただけでバグが発覚したXcodeの恥ずかしいリリース版とかも過去にありました

ass5.jpg

▲ビルドして実行したところ。きちんと日本語が表示されています

2009/11/08 AppleScriptの文字列比較(1)

AppleScriptについて聞かれるのが、文字列比較についての独特な表現についてです。

とりあえず、基本的な文字列比較について挙げておきましょう。

なお、イコールの表記についてはいくつか同義語が定義されており、「同じことを書くのに人によって記法が異なる」という傾向を生み出しています。

「is equal to」「is」「=」の3つがすべてイコールとして機能します。

なまりの強いAppleScriptのプログラムを手本とした場合に、よその人が書いたAppleScriptを見ても理解できなかったりするところです。

本Blogでは、海外のScripterとの交流の中で感じた、なるべく平易で分かりやすい記法を重視していますが、1つだけ例外があります。

不等号や等号付き不等号などにも別の表記方法があり……極力記号を使いたいところですが……これまでAppleScript Studio環境ではそれらの等号付き不等号がコンパイル時にハネられるとか、エラー発生原因になることが多く、UTF-8でソースコードを書けるようになったMac OS X 10.5までは、等号つき不等号を英語的な別の表記で書かざるを得なかった、という歴史的経緯があります。

等号つき不等号については、記号で書いた方が分かりやすいのですが、仕方なく英語的表記で記述していた、ということです。

スクリプト名:文字列比較
set a to “abc”
set b to “c”

–イコールかどうか?
if a is equal to b then
  display dialog “Equal”
else
  display dialog “Not Equal”
end if

–前方一致
if a begins with b then
  display dialog “begins with”
else
  display dialog “Not begins with”
end if

–後方一致
if a ends with b then
  display dialog “ends with”
else
  display dialog “Not ends with”
end if

–部分一致
if a contains b then
  display dialog “contains”
else
  display dialog “not contains”
end if

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2008/12/20 特定の文字ではじまるリスト要素を削除して返す

改行によって区切られたテキストのうち、コメント行や改行のみの行を除外するために作成したサブルーチンです。AppleScript Studioのプロジェクトで、text viewに各種データを記入してもらうようにしておいて、その中にコメントを記入できるようにすることを意図したものです。
(more…)

2008/08/11 ポップアップメニュー項目の高速生成

AppleScript Studioで、ポップアップメニューの項目を追加する場合には、一度popup buttonのmenu内のmenu itemを削除してから、リストに入った項目をひたすらループで追加していくのが常でしたが……海外のMLの過去ログを調べてみたら、call method命令で一括追加する方法を発掘しました。

InDesign CS3用のScriptアプリで、使用可能な書体をすべて取得してpopup menuに追加しようとしたら……システム中に600書体ぐらいあって(汗) さらに、1画面中にそれが複数個あったりして(汗) popup buttonにメニュー項目を追加したときに、それなりに待たされてしまうので困っていました。このルーチンを使うと、激的に高速化できます。

call method命令だとオーバーヘッドが大きいので(cocoa分らないと書けないし、、、)、よほどの効果が期待できないかぎり、使わないようにしているものですが……このぐらい速度向上が著しい場合には、使うべきでしょう。

menuObjectにpopup buttonへのオブジェクト参照(popup button 1 of window 1とか)を入れ、textListにpopup menuに入れるテキストのリスト({”melon”, “apple”, “mango”}など)を入れて本ルーチンを呼び出せばOKです。

スクリプト名:ポップアップメニュー項目の高速生成
ポップアップメニューの初期化(2008/8/11超高速化)
on initPOPUPMenu(menuObject, textList)
  
tell menuObject
    
tell menu 1
      
delete every menu item
    
end tell
  
end tell
  
  
call method addItemsWithTitles: of menuObject with parameter textList
end initPOPUPMenu

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2008/05/29 ファイルのMac OS形式のフルパスのテキストから、ファイル名のみを取得

AppleScript Studioのアプリケーション中では、ファイルの名称を取得するのが大変です。Finderに対して命令してもダメ、System Eventsに命令してもダメ。アプリケーションにドラッグ&ドロップしたファイルの名称を取得してウィンドウのタイトル欄に表示しようとしても……できないということになります。Adobeのアプリのバグの多さにもうんざりさせられますが、Appleのバグの多さにも困ったものです。

注:普通のAppleScriptでは、Finderにファイルの名前を聞けば教えてくれます。本ルーチンはむしろ特殊環境用(AppleScript Studio用)です。

そこで、Mac OS形式のファイルパス(例: Macintosh HD:Users:someone:Documents:test.txt)を文字列として評価し、「:」で区切られたアイテムのうち、一番最後にあるものをファイル名として取り出します。

念のために書いておきますが、AppleScript Studioアプリケーション中ではない、通常のAppleScriptでは……ファイル名を求めるのはFinderに対してファイルのnameを取得するだけで楽勝で取得できます(4行ぐらい)。ここで紹介しているやりかたは、この通常の手段が利用できない場合の非常用の手段です。お間違えなく。

スクリプト名:ファイルのMac OS形式のフルパスのテキストから、ファイル名のみを取得
set a to choose file
set aStr to a as string
set aStr to aStr as Unicode text
set aRes to getLastLayerOfDirData(aStr) of me

テキストで与えられたパスデータから、最終階層のテキストのみを返す
on getLastLayerOfDirData(aData)
  set aColon to:as Unicode text
  
copy aData to bData
  
if bData ends with:then
    set bData to text 1 thru -2 of bData
  end if
  
  
set aLen to length of bData
  
set rData to reverse of (characters of bData)
  
set rData to rData as string
  
set dPos to offset of aColon in rData
  
set resData to text (aLen - dPos + 2) thru -1 of bData
  
return resData
  
end getLastLayerOfDirData

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2008/05/02 入り組んだリストの中に指定要素が存在するかどうかをチェック

{{1, 2, 3}, {4, 5, 6}, {7, 8, 9, {-1, -2, -3}}} ……のような入り組んだリスト型変数の中に、指定の要素が含まれていないかどうかをチェックするサブルーチンです。
(more…)