Archive for 11月, 2009

2009/11/28 AppleScriptObjc 3分間クッキング

AppleScriptObjCで、TextFieldに入力した内容をダイアログに表示するという簡単なサンプルを作って、その模様をMac OS X 10.6の機能を使って録画、YouTubeにアップしてみました。

■プロジェクトのダウンロード
asoctest_1.zip
(more…)

2009/11/28 変数値のスワップ

複数の変数の内容を入れ替えるAppleScriptサンプルです。

一度、他の変数に値を退避させて順次代入……などと回りくどいことをしなくても、一度に指定すればシンプルに記述できます。

InDesignドキュメントを2枚オープンして、ウィンドウの座標値からどちらが画面上の左に位置していて、どちらが右に位置しているかを検出。左側ドキュメントから右側ドキュメントにScript Labelを手がかりにデータを転送するAppleScriptを書いていたときに、これらの左右を入れ替える機能を実装する羽目になって、そういえば変数値のスワップって面倒かもしれない……などと思いながら、1行で書いてみたらたいへんにシンプルな記述で済んだ……ということがありました。

その時には変数にはInDesignのLayout Windowオブジェクトへの参照が入っていたわけですが、このような一番かんたんなレベルに立ち返ってその場で試してみて、挙動を確認しつつ実際のプログラムに反映させました。記述サンプルとしては、難しくて複雑なプログラムよりも、簡単で分りやすくて短いものの方が役立つことが多いように感じています。

スクリプト名:変数値のスワップ
set a to 1
set b to 2

set {a, b} to {b, a}
–> {2, 1}

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

ちなみに……2つ以上の変数の場合でも、とくに問題はありません。

スクリプト名:変数値のスワップ2
set a to 1
set b to 2
set c to 3

set {a, b, c} to {c, b, a}
–> {3, 2, 1}

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

2009/11/25 擬似的にPropertyファイルを使ってカウントアップ

保存ファイルを~/Library/Preferencesに作成し、カウントアップを行います。

カウンター値を保持する場合には、propertyでScript中に保持しておくのが一番簡単ですが、AppleScriptのプログラムを書き換えてしまうと初期値に戻ってしまいます。そこで、初期設定ファイル(もどき)を作成して、リストの値をそのまま保存。こうしておけば、プログラムを書き換えて実行しても、カウント内容が維持されます。

本物のplistファイルで値を保持してもいいのですが、より簡単かつ安直にファイルに書き込んで使ってもよいだろう、というアプローチです。

スクリプト名:Propertyファイルを使ってカウントアップ
set aRes to countUp(“jp.piyomarusoft.counter.pref”) of countUpKit

script countUpKit
  –カウントアップ
  
on countUp(anIDentifier)
    set apDir to (path to preferences folder from user domain) as string
    
set a to apDir & anIDentifier
    
tell application “Finder”
      set fRes to exists of file a
      
if fRes = false then
        –初期設定ファイルがなければ初期化(1からカウントアップし直し)
        
write_to_file_AsList({1}, a) of me
        
return 1
      else
        set aCount to read file a as list
        
set aaCount to (item 1 of aCount as number) + 1
        
write_to_file_AsList(aaCount, a) of me
        
return aaCount
      end if
    end tell
  end countUp
  
  
–ファイルの追記ルーチン「write_to_file_AsList」  (リストとして書き込み)
  
–データ、対象ファイル
  
on write_to_file_AsList(this_data, target_file)
    try
      set the target_file to the target_file as text
      
set the open_target_file to open for access file target_file with write permission
      
set eof of the open_target_file to 0
      
write this_data to the open_target_file starting at eof as list
      
close access the open_target_file
      
return true
    on error error_message
      try
        close access file target_file
      end try
      
return error_message
    end try
  end write_to_file_AsList
end script

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

2009/11/21 Mac OS X 10.6上でAppleScriptの実行が遅い?

本Blogへの検索キーワードを調べていたら、Mac OS X 10.6上でのAppleScriptの実行が遅い、といったものがあったので、実際に調べてみました。

いつも、新しいマシンが出るたびにAppleScriptで1000万回の単純ループ速度を調べてきました。数値演算やテキスト操作、プロセス制御やアプリケーションコントロールなどさまざまなジャンルの処理を試してみるべきですが、店頭でその場で入力して試すのには単純ループぐらいが手ごろでよかったためです。

現在のIntel MacではPowerPCの時代にくらべてはるかに高速にAppleScriptを実行するため(1000万回ループで1秒以下)、もはや1000万回では負荷にすらならなくなって……1億回ループで調べています。

その1億回ループを、MacBook Pro CoreDuo 2.0GHz メモリー2GBのマシンで、Mac OS X 10.4.11、10.5.8、10.6.2とOSを変え、スクリプトエディタ(10.6はAppleScriptエディタ)、スクリプトメニュー、アプリケーションバンドル形式で書き出したアプレットの3つの異なるランタイム環境で調べてみました(単位:秒)。

bench.jpg

実行結果を見てみると……単純ループの実行ではとくに10.6環境で遅くなっているわけではないようです。そうはいっても、単純ループだけでは判断できず……Mac OS X 10.5リリース直後の時にも「do shell script命令が遅い(遅かった)」といった問題が指摘されており、特定の処理だけ遅くなる可能性もあるため、何か10.6環境で特定の処理が遅いという話があれば、ぜひ調べてみたいところです。

スクリプト名:Loop10000000times
set sDate to current date
repeat 100000000 times
end repeat
set edate to current date
display dialog (edate - sDate) as string

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

2009/11/20 Excel 2008でオープン中のワークブック内のワークシート名称を取得してテキストに

Microsoft Excel 2008でワークブック内にあるワークシートの各名称をまとめて、改行つきのテキストとしてまとめるAppleScriptです。

Excel書類で受け取った資料の一覧をまとめようとして、Excelのワークシート名をひととおり取得しなければならない……とかいった場合に、いちいち手でコピーしたり、Excelを見ながら各ワークシート名をキーボードから入力するというのはナンセンスです。

exc1.jpg

というわけで、その場で1分ぐらいで作りました。これは、作ってよかった! こういう派手さはないが実用的でさっさと作れるAppleScriptの御利益は大きいところ。

exc2.jpg

ここまで自動化できると、フォルダ内に入っているExcelのファイルをすべてオープンしてウィンドウの画面キャプチャをとって、ワークシート名をPowerPointなりKeynoteなりに展開して資料化するところまで自動化したいところです。

……PowerPointは実際にScriptingをやってみると「?」な挙動のオンパレードだし、Keynoteはそれほど自動化の機能がないという状況。いっそ、InDesign上にでも展開したほうが楽そうなところです。

スクリプト名:Excel 2008でオープン中のワークブック内のワークシート名称を取得してテキストに
tell application “Microsoft Excel”
  tell workbook 1
    set wList to name of every worksheet
  end tell
end tell

set aRes to retDelimedText(wList, return) of me

on retDelimedText(aList, aDelim)
  set aText to “”
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retDelimedText

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

2009/11/19 Cyberduck 3.3のAppleScript非対応はケアレスミス?

cyberd.jpg

FTP/SFTPなどの多機能対応ファイル転送クライアント「Cyberduck」は、かつてのClassic Mac OS時代における「Fetch」のポジションにあるMac OS X用の超定番FTP転送ソフトですが、このソフトのAppleScript対応機能がv3.3betaで失われていたことを確認していました。

あるAppleScriptの開発でSFTPサーバーにファイルのアップロードを指定されたので、Cyberduckで転送するようにしてみたところ……Snow Leopard対応のCyberduck 3.3betaがAppleScriptから命令を受け付けないことが分かり、あわてて古いバージョンをダウンロードした次第。

2009年11月13日、待ちに待ったv3.3の正式版がリリースされましたが、これもScriptableになっていないので……不思議に思ってCyberduckのバンドル・パッケージ内部を調べてみると……AppleScript用語辞書ファイルであるsdefファイルが転がっており、アプリケーション自体はScriptableになっている雰囲気が濃厚。

まさかと思ってInfo.plistを調べてみると……

infoplist.jpg

Scriptableのスイッチが入っていません(汗) 書き直して再度立ち上げてみると、何事もなかったようにAppleScriptエディタで辞書をオープンすることができました。バグレポートをしておいたので、じきに直ることでしょう。修正を待てないという方は、CyberduckのバンドルをFinder上で開けて、Plist EditorでInfo.plistのエントリを書き換えてみてください。

追記:

v3.3では一部のオブジェクトをAppleScriptから指定できないようです。アプリのバージョンを取得したりプロパティを取得するぐらいなら問題なく実行できますが、なぜか「browser」オブジェクトにアクセスしようとするとエラーになります(それでは何もできません)。

この問題をクリアできていないために、暫定的にScriptableでなくしているのではないか? という可能性も出てきました。

2009/11/18 System Events経由でQuickTimeムービーのannotationにアクセスする

System Events経由でQuickTimeムービーのannotation(注釈)の情報にアクセスするAppleScriptです。

スクリプト名:System Events経由でQuickTimeムービーのannotationにアクセスする
set movie_file to (choose file) as Unicode text

tell application "System Events"
  set movie_contents to QuickTime file movie_file
  
set anotL to every annotation of movie_contents
  
set ano1 to first item of anotL
  
properties of ano1
  
–> {name:"Full Name", class:annotation, full text:"Terminator Salvation", id:"©nam"}
end tell

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

2009/11/18 System Events経由でQuickTimeムービーにアクセスする2

System Events経由でQuickTimeムービーの情報にアクセスするAppleScriptです。

movie fileオブジェクトではなく、QuickTime fileオブジェクト経由でアクセスしているものです(MLに流れていたものです)。

スクリプト名:System Events経由でQuickTimeムービーにアクセスする2
set typeList to {}
set aFile to ((choose file) as text)

tell application "System Events"
  set qtFile to QuickTime file aFile
  
set trackList to (get every track of qtFile)
  
repeat with aTrack in trackList
    set end of typeList to (name of aTrack)
    
set end of typeList to (type class of aTrack)
    
set end of typeList to (audio channel count of aTrack)
    
set end of typeList to (audio sample rate of aTrack)
    
set end of typeList to (audio sample size of aTrack)
    
    
log typeList
    
–> (*Video Track, current application, 0, 0.0, 0, Sound Track, current application, 0, 0.0, 0*)
  end repeat
end tell

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

2009/11/18 System Events経由でQuickTimeムービーにアクセスする

System Events経由でQuickTimeムービーの情報にTrack単位でアクセスするAppleScriptです。

System Eventsには、QuickTimeムービーのファイルにアクセスする命令群が用意されており、さまざまな情報が取得できます。ただし、そのプロパティの多くはr/o(Read Only)であり、書き換えるようなことはできません。

従来のQuickTime Playerの延長線上にあるQuickTime Player 7は、おそらく次のMac OS X 10.7では廃止になることでしょう。QuickTime Player 7が持つ豊富な機能は、後継のQuickTime Player XとSystem EventsのQuickTime系機能を足してもカバーし切れるものではなく……今後の動向が注目されるところです。

System Eventsは、もともとClassic Mac OS時代のFinderが持っていた命令群を移管する「避難先」として、さまざまな雑多な命令が統合されてきました。途中、Script Menuの実行機能がAppleScript Runnerに移された以外は、機能は減ることなく増える一方です。

もし、iPhone OS上でAppleScriptが使えるようになったら……Finderがなくなり、このSystem Eventsがファイルアクセスなどの機能を肩代わりしそうな気配さえ感じる……といったら妄想がすぎるでしょうか。

スクリプト名:System Events経由でQuickTimeムービーにアクセスする
set aFile to (choose file) as Unicode text

tell application “System Events”
  set movie_contents to contents of movie file aFile
  
set track1_props to properties of track 1 of movie_contents
end tell
track1_props

–> {visual characteristic:false, href:missing value, data size:367752336, duration:1451720, modification time:date “2009年10月13日火曜日 4:41:49″, high quality:false, kind:missing value, creation time:date “2009年10月13日火曜日 4:41:49″, audio sample size:0, name:”Video Track”, type:missing value, data rate:0, audio characteristic:false, audio sample rate:0.0, enabled:true, class:track, video depth:0, dimensions:{1920.0, 1080.0}, start time:0, type class:missing value, audio channel count:0, data format:missing value}

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

2009/11/18 AppleScriptObjC-Dev MLが新設された

US Appleがホスティングしているメーリングリストに新たなML、「applescriptobjc-dev」が追加されていました。アナウンスはとくになかったので……今日まで気付きませんでした。

AppleScript系のMLとしては

AppleScript Users ML:ふつうのAppleScriptに関する話題。AppleScript StudioとかAppleScriptObjCの話題をポストしてはいけない

AppleScript Studio ML:Mac OS X 10.5までAppleScriptのGUIつきプログラム開発環境「AppleScript Studio」(Xcode+Interface Builderを使って書く)に関するML。Mac OS X 10.6のリリース以降、AppleScriptObjCの話題はこちらにポストされていた。

Applescript-implementors ML:アプリケーションへのAppleScript対応機能を実装する開発者のためのML。

Automator Dev ML:Automatorのactionを開発する開発者のためのML。Objective-C系の開発者とAppleScript系の開発者とUNIX系の開発者の間で話題が合うわけもなく、閑古鳥が鳴いている状態。

Automator Users ML:Automatorを使ってワークフロー開発を行うユーザーのためのML。Automator Devよりは流量があるが、それほど話題があるわけではない。

などがあります。AppleScript Studioで作った自作アプリケーション「ML Ranking」で流量に応じたランキングを計算すると、こんな感じ(↓)です。昨日の00:00から1日半ほどの間の流用で集計してみたのですが、AS系ではAppleScript Users MLの流量が多いことが一目瞭然。AppleScript Studio MLから分離したApplescriptObjC Dev MLの今後を見守りたいと思います。

mlranking.jpg

2009/11/17 AppleScriptObjCベースのAutomator Actionのサンプルが公開される

AppleのAppleScriptプロダクトマネージャであるSal Soghoianが、AppleScriptObjCベースのAutomatorアクションのサンプルプロジェクトを公開したことをAppleScript Users MLに投稿していました。

scrn2.jpg

リンク先のページの右側にある「BEFORE YOU BEGIN」にダウンロードファイルへのリンクがあります(分かりづらいなあ)。

scrn1.jpg

FileMaker Proのデータベースに入れた内容をPages上に割り付けるActionの、Xcodeプロジェクトが配布されており……インストーラーでインストール。…………どこへ???

scrn3.jpg

インストールした内容は、/Developper/Examples/Automatorに入ります(説明ないよ、、、)。

scrn4.jpg

掲載しているサイト「Macosxautomation.com」は「Appleがホスティングしているサイトではない」と書かれており……ドメインもSal Soghoian個人の持ち物のようです。そして、今回公開されたサンプルはApple社員によるものではないことが見てとれます。割と画期的な動きというか……Apple.comのサイトでは更新が窮屈ということなのでしょうか?

今回のAutomatorアクションのサンプルは、かなり気合いが入ったものですが……ただ、サンプルという意味ではもっとシンプルなものが数多くあったほうがいいように思います。

2009/11/12 AppleScriptObjCのプロジェクトのビルド後のソースを読めないようにする

Xcode 3.2.1上でAppleScriptObjCのプロジェクトを作成し、ビルドスタイル「Release」を選択してビルドしても、ビルドされたアプリケーションの「/Contents/Resources/」フォルダ内にあるAppleScriptのファイルは、AppleScriptエディタでオープンできてしまいます。

なんで、ReleaseビルドでReadableなままの設定にしてあるのか、Appleのデフォルト値の設定内容にひじょうに疑問が残ります(罠?)。

これを、読めないようにするためには…………

xc10.jpg

Xcodeのウィンドウで(デフォルト状態)、左上のプロジェクト書類の青いアイコンをクリックしておいて、ツールバーの「i」ボタンを押すと、プロジェクト全体のインスペクタが表示されます。

xc11.jpg

インスペクタの「ビルド」タブを選び、ポップアップメニューから「Release」を選びます。

xc12.jpg

「Release」ビルドの設定の一番下に……

xc13.jpg

「OSAcompile - ビルドオプション」にチェック項目があり、これをチェックするとビルドしたバイナリ中のAppleScriptObjCのソースを見ることも編集することも不能な状態になります。これで、安心して配布できます。

xc14.jpg

2009/11/11 Web共有がオンになっているかどうかを検出する

Web共有がオンになっているかどうかを検出するAppleScriptです。

スクリプト名:Web共有がオンになっているかどうかを検出する
set webRes to retWebSharingEnabled() of me

–Web共有がオンになっているかどうかを検出する
on retWebSharingEnabled()
  return (do shell script "ps -ax | grep httpd") contains "/usr/sbin/httpd"
end retWebSharingEnabled

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

2009/11/11 System EventsでScreen Saverの設定にアクセスする

System Eventsで、Screen Saver関連の設定情報を取得するAppleScriptです。

Screen Saverが動作中かどうかなど、かなり細かい情報を取得できます。

スクリプト名:System EventsでScren Saverの設定にアクセスする
–System EventsでScren Saverの設定にアクセスする
tell application “System Events”
  set pObj to a reference to screen saver preferences
  
tell pObj
    properties
    
–> {running:false, show clock:false, class:screen saver preferences object, delay interval:1200, main screen only:false}
  end tell
end tell

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

2009/11/11 System EventsでScreen Saverの情報にアクセスする

System Events経由でScreen Saverの情報にアクセスするAppleScriptです。

使用中のシステムにインストールされているScreen Saverの情報を取得したり、使用中のScreen Saver(current screen saver)の情報を取得したり、Screen Saverを動作(start)させたり停止(stop)したりします。

スクリプト名:System EventsでScreen Saverの情報にアクセスする
–System EventsでScreen Saverの情報にアクセスする
tell application "System Events"
  
  
–システムにインストールされているScreen Saverの情報を取得する
  
set sList to every screen saver
  
–> {screen saver "QuaternionJulia", screen saver "Word of the Day", screen saver "Paper Shadow", screen saver "MacLampsSS", screen saver "Beach", screen saver "Flurry", screen saver "A Very 3D Christmas", screen saver "Shell", screen saver "iTunes Artwork", screen saver "screensaver.shuffle", screen saver "Abstract", screen saver "Computer Name", screen saver "FloatingMessage", screen saver "RSS Visualizer", screen saver "Forest", screen saver "Spectrum", screen saver "Random", screen saver "Cosmos", screen saver "ElectricSheep2", screen saver "Big Time", screen saver "Time Machine", screen saver "Arabesque", screen saver "Nature Patterns", screen saver "NightLights"}
  
  
–使用中のScreen Sverの情報を取得する
  
set curSaver to properties of current screen saver
  
–> {path:file "Macintosh HD:System:Library:Screen Savers:Shell.qtz", displayed name:"Shell", class:screen saver, picture display style:missing value, name:"Shell"}
  
  
–使用中のScreen Saverを実行する
  
start current screen saver
  
end tell

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

2009/11/08 アドレスブックでPersonを検索

アドレスブックでPersonを検索するAppleScriptです。アドレスブックにはfindといった検索を想起させるようなコマンドはありませんが、フィルタ参照で絞り込み検索を行うことになります。

たとえば、苗字(last name)が「長野谷」のpersonを検索するには、

スクリプト名:アドレスブックを苗字で検索
tell application “Address Book”
  set the lastName to every person whose last name is equal to “長野谷”
end tell

–> {person id “094F257D-ED10-4844-B9FD-59FD995D3A69:ABPerson” of application “Address Book”, person id “22764B75-CC04-4274-BAE7-E8B75579F639:ABPerson” of application “Address Book”, person id “E4D07039-29ED-4A79-AD9F-A0CBA9E8DA02:ABPerson” of application “Address Book”, person id “BE0D07E5-A6A5-47D7-8E72-B72ED924A7A8:ABPerson” of application “Address Book”}

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

のようにします。条件に該当するpersonオブジェクトのリストが返ってくるので、あとはプロパティを取得するなりしてデータを取り出すだけです。

first name(名前)、last name(姓)、phonetic first name(名前よみがな)、phonetic last name(姓よみがな)などが使用できます。

adb1.jpg

姓よみがなに「ながの」を含むpersonを取得する場合には、

スクリプト名:アドレスブックを苗字のよみがなで検索
tell application “Address Book”
  set the lastName to every person whose phonetic last name contains “ながの”
end tell
–> {person id “094F257D-ED10-4844-B9FD-59FD995D3A69:ABPerson” of application “Address Book”, person id “22764B75-CC04-4274-BAE7-E8B75579F639:ABPerson” of application “Address Book”, person id “E4D07039-29ED-4A79-AD9F-A0CBA9E8DA02:ABPerson” of application “Address Book”, person id “BE0D07E5-A6A5-47D7-8E72-B72ED924A7A8:ABPerson” of application “Address Book”, person id “E067C14E-8BA3-481B-81AC-EBD4D3A5E339:ABPerson” of application “Address Book”}

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

となります。

電話番号と住所については、1つのpersonの下に複数持てるようになっているので、電話番号や住所を検索条件にする場合には、少々コーディングが必要になります。

あるいは、spotlight(do shell script経由でmdfindコマンドを使用)でアドレスデータを検索したほうが簡単かもしれません。

2009/11/08 継続記号(continuation mark)の使用

AppleScriptには、プログラムの1行が長くなった場合に、可読性を維持するため途中で改行を行う「継続記号」(continuation mark)というものがあります。

継続記号は、キーボードから[option]+[L]で入力できます。

continu1.jpg

継続記号が入っても、プログラムの意味が変わるわけではありません。

継続記号が入力できるのは、あくまで命令やデータの区切り目であり、ダブルクォートで区切られた文字列データの途中などには入力できません。

ただし、例によってMac OS X 10.4までのAppleScript Studio環境でこの継続記号を使おうとしても、構文確認時にハネられてきたので、本Blogでも極力使わないようにしています。

2009/11/08 等号つき不等号の同義語

AppleScriptを日本語環境下で記述する場合に、英語やフランス語など他の言語環境では問題にならないにもかかわらず、日本語環境では使えない文字がありました。それが、等号つき不等号です。

A≦B(AはB以下): A is not greater than B
A≧B(AはB以上):A is not less than B

また、不等号については、以下のような記述になります。

A≠B(等しくない):A is not equal to B

なお、等号付き不等号をMac OS X 10.6上のAppleScriptエディタに入力する場合には、「>=」と入力して「構文確認」を行うと「≧」が入力され、「< =」と入力して構文確認すると「≦」が入力されます。

note.jpg

自分は、AppleScriptエディタのコンテクストメニューから入力できるようにしています。等号つき不等号(の英語表記)をそのままキーボードから入力するのは骨が折れるので、、、、

2009/11/08 AppleScriptの文字列比較(5)〜句読点の考慮/無視

AppleScriptでは、considering punctuation/ignoring punctuationで文字列比較時の句読点の考慮/無視を行うことができるようになっています。

句読点として一般的に用いられる記号は、「、」と「。」ですが、論文などにおいては全角のカンマと全角のピリオドが使われることもあり、これらを句読点として認識するかどうか試してみたところ、OKでした。

スクリプト名:文字列比較5
set a to "かきくけこ"
set b to "かき、くけこ"
set c to "かき、くけこ。"
set d to "かき,くけこ."

–読点「、」が入っている文字列との比較
ignoring punctuation –ピリオドなどの記号を無視する
  if a is equal to b then
    display dialog "Equal 1"
  end if
end ignoring

considering punctuation –ピリオドなどの記号を考慮する
  if a is equal to b then
    display dialog "Equal 2"
  end if
end considering

–読点「、」と区点「。」が入っている文字列との比較
ignoring punctuation –ピリオドなどの記号を無視する
  if a is equal to c then
    display dialog "Equal 3"
  end if
end ignoring

considering punctuation –ピリオドなどの記号を考慮する
  if a is equal to c then
    display dialog "Equal 4"
  end if
end considering

ignoring punctuation –ピリオドなどの記号を無視する
  if a is equal to d then
    display dialog "Equal 5"
  end if
end ignoring

considering punctuation –ピリオドなどの記号を考慮する
  if a is equal to d then
    display dialog "Equal 6"
  end if
end considering

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

2009/11/08 AppleScriptの文字列比較(4)〜日本語の大文字/小文字

AppleScriptはconsidering case/ignoring caseで大文字小文字を区別/無視できるようになっていますが、日本語における大文字と小文字とは何を指しているのでしょうか?

実際に試してみると「あ」と「ぁ」、「い」と「ぃ」などの関係を大文字/小文字と見なしているようです。

スクリプト名:文字列比較4
set a to "ぁ"
set b to "あ"

if a = b then
  display dialog "equal 1"
end if

considering case –大文字小文字を考慮
  if a = b then
    display dialog "equal 2"
  end if
end considering

ignoring case –大文字小文字を無視
  if a = b then
    display dialog "equal 3"
  end if
end ignoring

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

2009/11/08 AppleScriptの文字列比較(3)〜濁点/半濁点の考慮/無視指定

AppleScriptで文字列比較を行う際に、濁点/半濁点を考慮したり無視したりできます。

ここまでできているのに、Mac OS X 10.5以降ではひらがなとカタカナを区別できないというあたりが不思議ですが、、、、

スクリプト名:文字列比較3
set a to “ガギグゲゴ” –濁点つき
set b to “カキクケコ”
set c to “はひふへほ” –ひらがな
set e to “ハヒフヘホ” –カタカナ
set f to “ぱぴぷぺぽ” –半濁点つき

considering diacriticals –濁点/半濁点を考慮する
  if a is equal to b then
    display dialog “「” & a & “」と「” & b & “」は等しい(濁点/半濁点を考慮)。”
  end if
end considering

ignoring diacriticals –濁点/半濁点を無視する
  if a is equal to b then
    display dialog “「” & a & “」と「” & b & “」は等しい(濁点/半濁点を無視)。”
  end if
end ignoring

considering diacriticals –濁点/半濁点を考慮する
  if c is equal to f then
    display dialog “「” & c & “」と「” & f & “」は等しい(濁点/半濁点を考慮)。”
  end if
end considering

ignoring diacriticals –濁点/半濁点を無視する
  if c is equal to f then
    display dialog “「” & c & “」と「” & f & “」は等しい(濁点/半濁点を無視)。”
  end if
end ignoring

–これだけ考慮しても日本語のひらがなとカタカナを区別できない(10.5以降)
considering white space –空白
  considering punctuation –ピリオドなどの記号
    considering hyphens –ハイフンおよび全角スペース
      considering case –大文字小文字
        considering diacriticals –濁点と半濁点
          if c is equal to e then
            display dialog “Equal 3″
          end if
        end considering
      end considering
    end considering
  end considering
end considering

considering white space, punctuation, hyphens, case and diacriticals –上記をまとめて1行に書いてみた
  if c is equal to e then
    display dialog “Equal 4″
  end if
end considering

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

2009/11/08 AppleScriptの文字列比較(2)〜considering, ignoring

AppleScriptの文字列比較で特徴的なのが、比較を行う場合に条件を設ける構文があるということです。それが、「考慮する」というconsideringと「無視する」というignoring。AppleScriptの基本構文として用意されており、1994年(一部には1993年に公開)の誕生以来、標準で用意されてきたものです。

このconsidering/ignoringでは、「大文字/小文字」(case)、「濁点/半濁点の有無」(diacriticals)、「ハイフンおよび全角スペース」(hyphens)、「ピリオドなどの記号」(punctuation)、「空白、改行文字、タブ」(white space)を指定。複数の条件を同時に宣言したり、consideringとignoringをネスティングさせて同時に使用することもできます。

スクリプト名:文字列比較2
set a to “abc”
set b to “C” –大文字にしてみた
set c to ” a b C “ –スペースを入れてみた

–大文字小文字を無視する
ignoring case
  if a is equal to b then
    display dialog “Equal 1″
  end if
end ignoring

–大文字小文字を考慮する
considering case
  if a is equal to b then
    display dialog “Equal 2″
  end if
end considering

–半角スペースを無視する
ignoring white space
  if a is equal to c then
    display dialog “Equal 3″
  end if
end ignoring

–半角スペースと大文字小文字を無視する
ignoring white space and case
  if a is equal to c then
    display dialog “Equal 4″
  end if
end ignoring

ignoring white space –半角スペースを無視する
  considering case –大文字小文字を考慮する
    if a is equal to c then
      display dialog “Equal 5″
    end if
  end considering
end ignoring

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

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

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

2009/11/07 10.5以降でRemote AppleEvent操作時にdisplay dialog等を使えない

Mac OSではAppleScriptでLANごしに他のマシンに命令を投げられるようになっています。「システム環境設定」の「共有」で、「リモートアップルイベント」にチェックを入れておけば、外部からのAppleScript等による操作を受け付けるようになります。

ただし、いくつかの制約事項があります(確認中に素朴なワナにひっかかってMLに質問して恥をかいたり、、、)。

(1)display dialogなどユーザー操作を要求する命令は、Mac OS X 10.5以降ではremote操作時に使えない
(2)リモートマシン上のアプリケーションに命令を出す場合、対象のアプリケーションは起動した状態でなければならない(activateやlaunchを送っても起動しない)
(3)remote AppleEventを拒否するアプリケーション(FileMaker Proなど)もある。そのような場合にはリモートマシン上でAppleScriptアプレットを起動しておいて、アプレット経由で操作することになる

記述例:

tell application “iCal” of machine “eppc://user:password@bonjourMachineName.local”
  activate
end tell

マシン名称はBonjour名称、あるいはIPアドレスで指定します。

2009/11/07 Xcode 3.2.1でプロジェクトの属性情報を取得する

Xcode 3.2.1で、プロジェクトの論理的な内部構造にアクセスするためのオブジェクトが、どうやら「project」オブジェクトのようです。このprojectオブジェクトの下にブラ下がっているオブジェクトに対して階層的にアクセスを行うことで、AppleScriptでどのような処理を行うことができるかが明らかになります。

特徴的なのは、ビルド結果の実行ファイル(executables)にアクセスできるのと、プロジェクト内のファイルへのアクセスが、一般的なファイルパスで行うのではなく「file reference id ”4F422FE710A3F035008C18C1”」といった形式で行う必要があるということです。他のさまざまなbuild targetなどもこのようなid形式で管理されているため、アプリケーション側の流儀に合わせてアクセスする必要があります。

★何らかのXcodeプロジェクトをオープンした状態で実行してください

スクリプト名:Xcode 3.2.1でプロジェクトの属性情報を取得する
–Xcode 3.2.1でプロジェクトの属性情報を取得する
tell application “Xcode”
  tell project 1
    properties
    
–> {project roots:{”"}, intermediates directory:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/build/ASOC Task List.build/Debug”, root group:group id “29B97314FDCFA39411CA2CEA” of project “ASOC Task List” of application “Xcode”, active architecture:”x86_64″, active target:target id “8D1107260486CEB800E47090″ of project “ASOC Task List” of application “Xcode”, organization name:missing value, active executable:executable id “4FE9A6DD109F2002003C067D” of project “ASOC Task List” of application “Xcode”, real path:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/ASOC Task List.xcodeproj”, path:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/ASOC Task List.xcodeproj”, full path:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/ASOC Task List.xcodeproj”, read only:false, name:”ASOC Task List”, default build configuration type:build configuration type id “C01FCF5008A954540054247B” of project “ASOC Task List” of application “Xcode”, active build style:missing value, id:”29B97313FDCFA39411CA2CEA”, active build configuration type:build configuration type id “C01FCF4F08A954540054247B” of project “ASOC Task List” of application “Xcode”, class:project, project directory:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList”, user file reference:file reference id “4F422FE710A3F035008C18C1″ of project “ASOC Task List” of application “Xcode”, active SDK:missing value, product directory:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/build/Debug”, currently building:false, project file reference:file reference id “4F422FE810A3F035008C18C1″ of project “ASOC Task List” of application “Xcode”}
  end tell
end tell

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

2009/11/07 Xcode 3.2.1で最前面のWindowでオープンしているファイルを取得

Xcode 3.2.1で、最前面のウィンドウ(window 1)でオープンしているファイルを取得するAppleScriptです。

Xcodeにかぎらず、アプリケーションがオープンしている書類にアクセスする手段には大きくわけて2つがあり、1つがドキュメント(実在するファイルであることが多い)、もう1つがウィンドウです。実データにアクセスする場合にはドキュメントからたどって行く場合が多く、documentオブジェクト経由のアクセスがほとんどです。

ただし、現在表示されているドキュメント(最前面に表示されているドキュメント)が何なのかを調べたり、ドキュメントの表示方法(複数の表示モードが存在するような場合)を調べるような場合にはWindow経由でアクセスすることになります。

まさに、Xcode 3.2.1で最前面のウィンドウで何を表示しているのかを取得するようなケースでwindow経由のアクセスを行うことになります。

xc1.jpg

Xcodeでは、1つのウィンドウを分割して複数のソースコードを表示できるようになっていますが、Windowオブジェクトが返す書類はつねに1つで、1ウィンドウ内に複数のファイルを表示している場合には、フォーカスが当たっている方(カーソルがアクティブになっている方)を返すようです。1ファイル=1ウィンドウの設定(ウィンドウがたくさんひらく)の場合にも同じです。

windowオブジェクトで注目すべきは、「associated file name」です。Windowでオープン中のドキュメントのフルパスを(aliasではなくPOSIX pathで)取得できます。フルパスを渡すための属性値ということで、正しくは「associated file path」という名前が正解だと思うのですが、なんでこのような名前にしてしまったのか、たいへん不思議です。

★何らかのXcodeプロジェクトをオープンした状態で実行してください

スクリプト名:Xcode 3.2.1で最前面のWindowでオープンしているファイルを取得
–Xcode 3.2.1で最前面のWindowでオープンしているファイルを取得
tell application “Xcode”
  tell window 1
    properties
    
–> {associated file name:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/TaskListAppDelegate.applescript”, bounds:{34, 129, 1307, 1028}, main:false, miniaturized:false, key:false, script:missing value, level:0, sheet:false, modal:false, document edited:false, position:{34, 129}, closeable:true, released when closed:false, name:”TaskListAppDelegate.applescript ― ASOC Task List”, content view:content view of window id 1 of application “Xcode”, minimized title:”TaskListAppDelegate.applescript ― ASOC Task List”, background color:{61166, 61166, 61166}, has shadow:true, has resize indicator:true, miniaturizable:true, maximum size:{5000, 5053}, first responder:text view id 11 of content view of box id 10 of view id 9 of split view id 8 of view id 7 of view id 6 of tab view id 5 of view id 4 of view id 3 of view id 2 of window id 1 of application “Xcode”, resizable:true, current field editor:missing value, visible:true, opaque:true, minimum size:{200, 231}, id:1, alpha value:1.0, class:window, needs display:false, zoomed:false, size:{1273, 899}, zoomable:true, titled:true, minimized image:missing value, floating:false, document:missing value, excluded from windows menu:false, auto display:true, index:1, toolbar:toolbar of window id 1 of application “Xcode”, title:”TaskListAppDelegate.applescript ― ASOC Task List”, menu:main menu of application “Xcode”, can hide:true, hides when deactivated:false}
    
    
–ウィンドウでひらいているファイルのフルパス
    
set aPath to associated file name
    
–> “/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/TaskListAppDelegate.applescript”
    
    
–Xcode上では複数のドキュメントをウィンドウ分割で表示することも可能だが、あくまでも「フォーカスが当たっている」方のファイルのパスが返ってくる
    
  end tell
end tell

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

2009/11/07 Xcode 3.2.1上でプロジェクト書類の情報を取得する

Xcode 3.2.1にとって、「document」というのはプロジェクトの書類(拡張子が「.xcodeproj」の、青いアイコンの書類)です。そのプロジェクト書類にアクセスするためのオブジェクトが「project document」で、「document」と等価な扱い(同じ結果が返ってくる)のようですが、さまざまな属性を取得して調べてみるとproject documentが使われているようなので、こちらからアクセスしてみました。

期待したような属性値に加えて、SCM(ソースコード管理)関連の属性も入っていたりするので、このあたりの機能をAppleScriptから呼び出せそうな「予感」を感じるものです。

★何らかのXcodeプロジェクトをオープンした状態で実行してください

スクリプト名:Xcode 3.2.1上でプロジェクト書類の情報を取得する
–Xcode 3.2.1上でプロジェクト書類の情報を取得する
tell application “Xcode”
  tell project document 1
    properties –属性情報の一括取得    
    
(*
    –> {path:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/ASOC Task List.xcodeproj”, project:project “ASOC Task List” of application “Xcode”, class:project document, scm transcript:”< ?xml version=\"1.0\" encoding=\"UTF-8\"?>
“, file name:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/ASOC Task List.xcodeproj”, id:7, file kind:”Xcode Project File”, script:missing value, modified:false, file type:”Xcode Project File”, name:”ASOC Task List.xcodeproj”}
*)

    
    
set aPath to path –Xcodeプロジェクトのパス
    
–> “/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/ASOC Task List.xcodeproj”
    
    
set aSCMtrans to scm transcript
    
(*
–>     –> “< ?xml version=\"1.0\" encoding=\"UTF-8\"?>

    
*)
    set aFileName to file name
    
–> “/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/ASOC Task List.xcodeproj”
    
    
set anID to id
    
–> 7
    
    
set fKind to file kind
    
–> “Xcode Project File”
    
    
set modifyFlag to modified
    
–> false
    
    
set fType to file type
    
–> “Xcode Project File”
    
    
set aName to name
    
–> “ASOC Task List.xcodeproj”
    
  end tell
end tell

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

2009/11/07 Xcode 3.2.1でアプリケーションの情報を取得する

Xcode 3.2.1でアプリケーションのプロパティを取得してみました。selectionがこの階層のオブジェクトに属しているアプリケーションもあったりするため、その確認です。

結論をいえば、この階層のオブジェクトからはとくに有用なプロパティは存在していませんでした。versionを取得してみるとか、frontmost(最前面にいるかどうか)を取得するか、active project documentで現在編集中のプロジェクト書類を取得できるとか(これは重要)いったところが見どころで、それ以外は無視してよい属性ばかりです。

★何らかのXcodeプロジェクトをオープンした状態で実行してください

スクリプト名:Xcode 3.2.1でアプリケーションの情報を取得する
tell application “Xcode”
  properties
  
–> {frontmost:false, event:event 1 of application “Xcode”, name:”Xcode”, key window:missing value, windows menu:sub menu of menu item id 2 of main menu of application “Xcode”, user defaults:user defaults of application “Xcode”, icon image:image id 3 of application “Xcode”, open panel:open panel of application “Xcode”, script:missing value, main bundle:bundle id 4 of application “Xcode”, version:”3.2.1″, main window:missing value, menu:main menu of application “Xcode”, selection:insertion point 43 of text of text document “TaskListAppDelegate.applescript” of application “Xcode”, class:application, active project document:project document “ASOC Task List.xcodeproj” of application “Xcode”, main menu:main menu of application “Xcode”, save panel:save panel of application “Xcode”, active:false, font panel:font panel of application “Xcode”, hidden:false, color panel:color panel of application “Xcode”, id:1, coordinate system:classic coordinate system, drag info:missing value, services menu:sub menu of menu item id 5 of sub menu of menu item id 6 of main menu of application “Xcode”}
end tell

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

2009/11/06 テキスト中の任意の順番の文字取り出し Mac OS X 10.4.11への対応

text 3 of ”ABCD” といった処理はよく使っていたのですが、これがMac OS X 10.4.11上ではエラーになることに気付きました。

Mac OS X 10.4.11は「第2のMac OS 9.2.2」とも言うべき存在であり、まだ相当数の実行環境が残っているばかりか、主要アプリケーションでは10.4.11対応をいまだにうたっているものも少なくありません(Office 2008とかiWork 09とかAdobe CS4とか)。

そんなわけで、本Blogでは10.4.11環境での検証を(最初のころは)しつこく行っていました。しかし、だんだん10.5とか10.6上で書いた方が楽になってきて、10.4.11上での確認を怠っていた今日このごろ……たまたま10.4.11上でこの基本的な記法が通らなかったのを見つけ、すぐさま書きかけのプログラムを書き直した次第です。

こういうものを一覧表にしておくと楽なのかもしれません。海外でも見かけたことはありませんが……。

スクリプト名:テキスト中の任意の順番の文字取り出し Mac OS X 10.4.11への対応
set aStr to “0123456-789″

set a to text 8 of aStr –10.5.8や10.6.1ではこれでOKだが、10.3.9/10.4.11上ではエラーに
set b to text 8 thru 8 of aStr –10.4.11への対策を行った記法。10.3,10.4,10.5,10.6で同じ実行結果

log {a, b}

–> (*-, -*)

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

2009/11/06 InDesign CS3のuser interaction levelを取得、設定する

InDesign CS3で、エラーレベルの取得および設定を行うAppleScriptです。

InDesignでは、エラー時にどのレベルまで警告するか……というよりは、自動処理時にエラーを無視するために、user interaction levelを設定できます。たいていは、すべてのワーニングを無視する「never interact」に設定。すべての処理が終わったあとで、Script実行前に取得しておいた現在のワーニングレベルに戻す、という処理を行います。

スクリプト名:InDesign CS3のuser interaction levelを取得、設定する
set aRes to retUserInteractionLevel() of me
setUserInteractionLevel(0) of me

–InDesign CS3のuser interaction levelを設定する
on setUserInteractionLevel(aNum)
  if (aNum > -1) and (aNum < 3) then
    try
      using terms from application “Adobe InDesign CS3″
        tell application “Adobe InDesign CS3″
          tell script preference 1
            if aNum = 0 then
              set user interaction level to never interact
            else if aNum = 1 then
              set user interaction level to interact with all
            else if aNum = interact with alerts then
              set user interaction level to interact with all
            end if
          end tell
        end tell
      end using terms from
    end try
  else
    
  end if
end setUserInteractionLevel

–InDesign CS3のuser interaction levelを取得する
on retUserInteractionLevel()
  using terms from application “Adobe InDesign CS3″
    tell application “Adobe InDesign CS3″
      tell script preference 1
        set uRes to user interaction level
        
if uRes = never interact then
          –エラーやワーニングがあっても警告しない
          
return 0
        else if uRes = interact with all then
          –すべてのエラーやワーニングを警告する
          
return 1
        else if uRes = interact with alerts then
          –ワーニングについてのみ表示する
          
return 2
        end if
      end tell
    end tell
  end using terms from
end retUserInteractionLevel

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