AppleScript 2.0 (1)

いつの間にやら Mac OS X 10.5 Leopard が発売され、Mac は Intel ベースになり、iPod touch などもでていて...隔世の感があります。一年前と状況が様変わり。どう、対処したらいいものか。いったいどれくらいの人が Mac OS X 10.5 に移行したのでしょうか?

Mac OS X 10.5 Leopard になってようやく AppleScript もバージョンが 2.0 になりました。ちらほらと不具合や仕様の変更に対する対処の話題なども見かけるようになりました。

AppleScript 2.0 の最大の話題は、ユニコードをほぼサポートしたことでしょうか。文字には id 属性なるものがつくようになりました。

id of "a"
--> 97

結果は、ASCII number 命令と同じですね。もちろん、この id から文字を得ることもできます。

string id 97
--> "a"

文字列でも可能。

set strIDs to id of "Love"
--> {76, 111, 118, 101}
string id strIDs
--> "Love"

ユニコードをサポートしてしまったので、日本語でも可能。

set strIDs to id of "強敵=友"
--> {24375, 25973, 65309, 21451}
string id strIDs
--> "強敵=友"

結果、以下のようなエラーが出現。

ASCII character 130
--> いくつかのデータを期待されるタイプに変換できません。

単にバグかもしれないですが。ASCII character や ASCII number といった命令は、今後 id 属性の利用に置き換わっていくのでしょう。StandardAdditions.osax には両命令に deprecated の記載がありますし(ちなみに deprecated な命令は他にもあって、info for、list disks、list folder が該当します)。

そして、text、string、Unicode text とあったクラスが全て text クラスになってしまいました。string と Unicode text は予約語として残っていますが、これらは全て text クラスで統一されています。

set theText to "abc"
set uni to theText as Unicode text
set str to theText as string

class of uni
--> text
class of str
--> text
uni is str
--> true

クラスも text ですし、比較も真になります。クラスが統一されたので、クラスによる比較には気をつける必要があります。

set str to "a"
if (class of str) is string then
    --
else if (class of str) is Unicode text then
    --
else
    --
end if

このような書き方は可能ですが、AppleScript 2.0 では string = text = Unicode text なので上記の分岐には意味がありません。

ユニコードのサポートはファイル入出力にも関係してきます。ファイルへの文字列の書き出しは、as で文字列の型を指定することになりますが、as で指定できるのは text か Unicode text、もしくは指定しない(as をつけない)になります。

as Unicode text とすれば、UTF-16 での書き出し。as text とすれば、ユーザーのプライマリエンコーディングを使用します。Mac を日本語環境で使っているとプライマリエンコーディングは「日本語(Mac OS)」になります。as の指定がなしだとプライマリエンコーディングで書き出すようです。

もちろん、読み込み(read 命令)も、as で正しい型を指定しないと文字化けします。

こういったユニコードサポートに伴い Script Editor も対応がなされています。いままでは文字列で日本語を記述するときは「環境設定」のフォーマットでフォントを変えないといけませんでしたが、その必要はなくなりました。また、演算子などの特殊記号もきちんと入力できるようになっています。また、AppleScript 2.0 上ではスクリプトの中身はユニコードで保持されるようになっています。

Finder の日本語が交じったファイル名やフォルダ名も一応扱えるようになっています。濁点、半濁点混じりの日本語では文字の欠落が見られたのですが、大丈夫なようです。しかし、以下のスクリプトが動いてしまうのは解せません。

tell application "Finder" to open folder "パナマ" of desktop

一見、何の変哲もないスクリプトですが、デスクトップ上にあるのは「ぱなま」というひらがなのフォルダなのです。ひらがな、カタカナ関係なしでユニコードサポートかよ...。これは、10.4 から続いていますが、比較もひらがな、カタカナ関係なしです

"だ" is "ダ"
--> true

これに対処する方法は...分かりませんでした。

Finder 上の濁点、半濁点の文字列は扱えるようになっていますが、AppleScript's text item delimiters の方はどうも駄目なようです。

Mac OS X をインストールすると /Library/Scripts 以下にいくつかの AppleScript ファイルも同時にインストールされます。この中の Finder 関連のスクリプトのファイル名やフォルダ名を処理するスクリプトはそのままでは動きませんでした。これは、AppleScript's text item delimiters が文字列の型を見ているからで、Unicode text と string が混在しているために正しく動作しないのでした。正しく動作させるため、as string として文字列の型を統一しておけば、一応日本語環境で動いていたのでした。

Script Editor で開く

on replaceText(findChar, replaceChar, theText)
    set findChar to findChar as string
    set replaceChar to replaceChar as string
    set theText to theText as string

    set old to the AppleScript's text item delimiters
    set the AppleScript's text item delimiters to findChar
    set theList to text items of theText
    set the AppleScript's text item delimiters to replaceChar
    set theText to theList as text
    set the AppleScript's text item delimiters to old

    return theText
end replaceText

このような感じです。が、先にも書いたように AppleScript 2.0 になって string も Unicode text も同じ text クラスとして扱うため文字列の型変換が行えなくなり、上記のスクリプトのように型を統一するという方法が通じなくなったのです。ですから、以下の付属 AppleScript ファイルは日本語混じりのファイルやフォルダに対して期待した動作を行いません。

  • /Library/Scripts/Finder Scripts/Replace Text in Item Names.scpt
  • /Library/Scripts/Finder Scripts/Trim File Names.scpt
  • /Library/Scripts/Finder Scripts/Trim Folder Names.scpt

フザケンナヨ、オイ。ユニコードサポートっていったいどういう意味なんだろう。今日は夕日がやけに目に染みるゼ...。

一応代替として iconv を使った方法をあげておきます。

Script Editor で開く

(*
デスクトップに「Appleフォルダ」、「りんごフォルダ」、「アップルフォルダ」と
いった名前のフォルダがあるとして。
*)


set the desktopFolder to path to desktop folder

tell application "System Events"
    set the folderList to folders of desktopFolder
    set theList to {}
    repeat with thisItem in folderList
        set end of theList to my replaceText("フォルダ", "", name of thisItem)
    end repeat
end tell

theList
--> {"Apple", "りんご", "アップル"}

on replaceText(findChar, replaceChar, theText)
    try
        set findChar to iconv(findChar)
        set replaceChar to iconv(replaceChar)
        set theText to iconv(theText)

        set old to the AppleScript's text item delimiters
        set the AppleScript's text item delimiters to findChar
        set theList to text items of theText
        set the AppleScript's text item delimiters to replaceChar
        set theText to theList as text
        set the AppleScript's text item delimiters to old
    on error eMessage number eNumber
        set the AppleScript's text item delimiters to {""}
        display dialog (eNumber & " : " & eMessage) as text
    end try

    return theText
end replaceText

on iconv(theText)
    do shell script "echo " & quoted form of theText & " | iconv -f UTF-8-MAC -t SJIS"
end iconv

iconv では、UTF-8-MAC から SJIS に変換していますが、これは Finder や System Events が返す値を想定しているので、他の場合には適宜修正する必要があります。一応、Mac OS X 10.4 以降の日本語環境で動きます。

余談ですが、AppleScript の文字列処理で何が一番苦痛かというと、他の言語環境のことを考慮したとき。例えば、英語環境にしたらそれだけで上記のコードは動かなくなったりします。多言語、国際化という話題は AppleScript では苦痛以外のなにものでもなく、ましてや AppleScript Studio が絡むとなれば...。本来ならしなくていい苦労が多いから AppleScript Studio は流行らないのかもしれませんね。

0 件のコメント :

コメントを投稿