iPod ノートと AppleScript

ユニコードの話なんだけど、もちろん AppleScript の Unicode text について。ユニコード全般についての話ではないのでその辺りご注意を。

ちょっと、間が空いてしまいましたが...以前に Automator のワークフローのことなどについて書きましたが、そのときにちょっと引っかかったことがあったので調べていました。なにに引っかかったかというと、iPod のメモを作成する Automator のアクション。

Automator についていろいろと調べている中で、このアクションは日本語だと文字化けするというような記述をいくつか拝見しました。そうなのだろうか?と試してみたところ、なんとも言えない結果になる。化けるときもあるし、そうでもないときもある。iPod で閲覧できるときもあるし、できないこともある。

おそらく、このアクションがユニコードを扱っているところに問題があるのでしょう。できないなら解決してみようと思ったのが問題の始まり。

まず、文字化けになる主要な原因は 2 つあります。

  1. アクションの文字列の取り扱い(AppleScript の文字列の扱い)
  2. iPod の言語設定によるエンコーディングの指定

AppleScript の文字列の扱いから見てみましょう。AppleScript の文字列型は主要なところで以下の 3 種類があります。

  1. Unicode text
  2. string
  3. «class utf8»

Unicode text は、UTF-16 のエンコーディングになります。string は、MacEncoding として扱われ、日本語では TextEdit でのファイルの保存時に指定できる「日本語(Mac OS)」にあたります。概ね Shift_JIS です。

«class utf8» は、AppleScript で定数が与えられていないものです。UTF-8 エンコーディングにあたるのですが、定数が与えられていないので AppleScript Studio では使用できません。

Mac OS X 以前の環境との互換性を考慮するなら string を利用します。

スクリプトファイルに直接埋め込まれた文字列は、string になります。

Script Editor で開く

set str to "文字列"
class of str
--> string

string は、as 演算子を使って Unicode text に変換することが可能です。«class utf8» は、Unicode text として表現されます。

Script Editor で開く

set str to "文字列"
class of str
--> string
set utxt to str as Unicode text
class of utxt
--> Unicode text
set utf8 to str as «class utf8»
class of utf8
--> Unicode text

これらは比較を行うとすべて真になります。Unicode text と string、«class utf8» は、比較で違いを調べることができません。

これらはの文字列はファイルに書き出すとそれぞれ異なったエンコーディングのファイルになります。

Script Editor で開く

set str to "文字列"

set theFile to (path to desktop as Unicode text) & "Test.txt"

set fh to open for access file theFile with write permission
set eof fh to 0
-- write str to fh as string -- MacEncoding
-- write str to fh as Unicode text -- UTF-16
write str to fh as «class utf8» -- UTF-8
close access fh

Unicode text で書き出したファイルは UTF-16 になるのですが、BOM は付加されません。string はこのように Unicode text や «class utf8» as で型を変換しても正しく書き出すことができますが、Unicode text や «class utf8» を string に変換するときは文字化けする可能性があります。

読み込むときは、as オプションで型を指定しない限り string としてファイルの内容を読み込みます。

Script Editor で開く

read (choose file) -- MacEncoding
read (choose file) as Unicode text -- UTF-16
read (choose file) as «class utf8» -- UTF-8

これらは、 UTF-8 で保存されているファイルの内容を MacEncoding に変換して読み込むということではありません。as 演算子でエンコーディングを変更できるわけではありません。結果的に UTF-16 のファイルを as string として読み込むことで文字化けがおこるか、エラーになるか、スクリプトがその部分で停止し、終了しなくなります。型の変換は、概ね以下のようになります。

  • string
    • Unicode text に変換可能
    • «class utf8» に変換可能
  • Unicode text
    • string に変換不可
    • «class utf8» に変換可能
  • «class utf8»
    • string に変換不可
    • Unicode text に変換可能

as 演算子はエンコーディングの自動変換などという機能を持っていないので、正しい型を指定しない場合、文字が化けるのは当たり前とも言えます。これは、日本語だからというものではなく、日本語だろうが英語だろうが as で型の変換を行うときは必ず発生するものです。アプリケーションが返す文字列型を把握しておき、正しい型を指定して書き出す、読み込むという基本的な注意事項が重要になります。

例えば、以下のようなスクリプト。

Script Editor で開く

tell application "Safari"
    text of front document
    set theText to result as string
end tell

set theFile to (path to desktop as Unicode text) & "Test.txt"

set fh to open for access file theFile with write permission
set eof fh to 0
write theText to fh as string
close access fh

これは、確実に文字が化けますし、開けないファイルになります(運がよい場合は、開けます。例えば、アルファベットだけの文字列で構成されているとか)。多くのスクリプタブル Cocoa アプリケーションは、結果として Unicode text を返すものがほとんどです。Safari も同様で、返された Unicode text を as string として型の変換を行うと、その時点で文字が化けてしまいます。それをファイルに書き出しても正常なデータではないので開けないファイルが出来上がってしまいます。

上記のように Unicode text から string への変換は正しい結果を期待できません。Unicode text が返されるなら、Unicode text として扱う方が無難です。

アプリケーションが返す Unicode text...例えば、以下のようなスクリプトをいろいろなサイトで試していると、必ずしも正しい結果になっていないことがあります(文字が化けているように見える)。

Script Editor で開く

tell application "Safari"
    text of front document
end tell

このスクリプトの結果が文字化けするのは、Script Editor に問題があります。Script Editor ではちゃんと表示できないのです。結果が文字化けしていてもそのまま Unicode text でファイルに書き出せば、UTF-16 のファイルとしてテキストエディタできちんと表示できます。

Script Editor で開く

tell application "Safari"
    set theText to text of front document
end tell

set theFile to (path to desktop as Unicode text) & "Test.txt"

set fh to open for access file theFile with write permission
set eof fh to 0
write theText to fh as Unicode text
close access fh

AppleScript の Unicode text の書き出しは、BOM を付加しません。BOM を付加しておくと特にエンコーディングを指定していなくてもアプリケーションがきちんと UTF-16 のファイルとして開いてくれます(もちろん、アプリケーションの仕様によりますが)。TextEdit の環境設定で開くときのエンコーディングを指定していても、BOM がついているとわざわざエンコーディングを指定しなくても自動的に開いてくれます。BOM(Hex の FE と FF。ASCII character 254 と ASCII character 255)は、以下のようにして付加します。

Script Editor で開く

tell application "Safari"
    set theText to text of front document
end tell

set theFile to (path to desktop as Unicode text) & "Test.txt"

set fh to open for access file theFile with write permission
set eof fh to 0
write (ASCII character 254) to fh
write (ASCII character 255) to fh
write theText to fh as Unicode text
close access fh

上記は PowerPC での話なので Intel Mac だと逆になるのかな(よく分からないけど)。Unicode text(UTF-16)で書き出すときは、つけておく方がいいでしょう。

AppleScript で扱っている文字列からプレインテキストを取り出す方法として «class ktxt» を使う方法が紹介されていたりします。

Script Editor で開く

set str to "文字列" as Unicode text

«class ktxt» of ((str as string) as record)

もちろんこの方法は、対象となる文字列が他の文字列情報を持っていないことには利用できません。string クラスに利用してもエラーになるだけですし、Unicode text であっても文字列情報を持っていない場合はエラーになるので、実際の利用には注意が必要です(この方法を使ったからといって Unicode text を string に文字化けせずに取り出せるというわけではないので。念のため)。

Unicode text と string の & 演算子による結合は Unicode text 型の文字列が結果として返ってきます。これは、AppleScript 1.10 からだったと思います。

Cocoa アプリケーションの多くでは結果として Unicode text を返す...ということは先に触れました。

Script Editor で開く

tell application "TextEdit"
    set theText to text of front document
    class of theText
    --> Unicode text
end tell

このような感じですね。しかし、ここに一つ落とし穴があります。例えば、TextEdit の書類になんらかの添付ファイルが埋め込まれているとき。上記のスクリプトでは添付ファイルの部分は「?」が代替として表示されます。この「?」が曲者で、以下のようにすると「?」以下の文章が消えてしまいます。

Script Editor で開く

tell application "TextEdit"
    set theText to text of front document
    -->
    (*"文字

    画像? <-- ここに添付ファイルが存在している

    文字"*)

    set pList to paragraphs of theText
    set theText to pList as Unicode text
    -->"文字"
    (*添付ファイルがある行以下が消えている...*)
end tell

不思議な現象です。寡聞にして今まで知りませんでした...。取得した文字列を行ごとに分解して iPod ノートに書き出す...ということをしていたのですが、いくらやっても結果は正しいのに空のファイルが出来上がってしまい、非常に悩みました。この問題はすべてのスクリプタブル Cocoa アプリケーションに共通します。Mail、Safari、TextEdit、Xcode、OmniOutliner...等々。

この「?」は、まさに代替で「?」のように見えるけど、文字の「?」ではないのです。ASCII number を調べると 63 が返ってくるのですが、「?」ではない。is "?" としても false が返ってくる。文字の「?」ではないので text item delimiters を使って削除することもできず、offset によるチェックも効果がない。

Script Editor で開く

tell application "TextEdit"
    font of attribute runs of text of front document
    --> {"HiraMaruPro-W4", missing value, "HiraMaruPro-W4"}
end tell

このようにして font 属性を調べてみると missing value となる。なら、フィルタ参照で font 属性が missing value 以外のものを取得するといいのだけど、うまくいかない。

Script Editor で開く

tell application "TextEdit"
    attribute runs of text of front document whose font of it is not missing value
    (*  
    {"文字

    画像", "?", "

    文字"}
    *)
end tell

フィルタリングされないのですね。missing value が返ってくるものは、実際に調べないとそれが missing value かどうかが分からないからです。ちゃんと missing value という定数を返すアプリケーションもありますが、TextEdit のように直接指定しないと missing value を返さないアプリケーションもあります。また、missing value を返す属性は、missing value という言葉が示すようになにも返さない場合もあります。だから、以下のように missing value が返ってくることを期待してスクリプトを組んでいるとエラーになる場合があります。

set val to font of attribute run 3 of text of document 1
if val is missing value then
    set val to dafaultValue
end if
--> 変数 val が定義されていません

属性が設定されていないときはなにも返されないというときは try 構文で対処するしかないです。

set val to font of attribute run 3 of text of document 1
try
    val
on error
    set val to defaultValue
end try

少し話が逸れましたが、こういうこともあるということで。添付ファイルを表す「?」は、以下のようにして取り除くことができます。

Script Editor で開く

tell application "TextEdit"
    set attrs to font of attribute runs of text of front document
    set tmp to {}
    repeat with i from 1 to count attrs
        set attr to item i of attrs
        if attr is not missing value then
            set end of tmp to attribute run i of text of front document
        end if
    end repeat
    tmp
end tell

これで添付ファイルを表す「?」を取り除くことができますが、問題は長い文章だった場合。非常に時間がかかる。正直、こういうことで悩むなどと思っていませんでした。なにかさくっと「?」だけを取り除く簡単な方法はないのでしょうか。

以上が AppleScript における文字列の取り扱いの基本的なところでしょうか。さて、iPod 上でファイルを閲覧するには iPod 側の問題も知っておく必要があります。

iPod の言語が「日本語」のとき、ファイルのエンコーディングは「MacJapanese」が使用されます(iPod 内部で)。「日本語」以外に「韓国語」、「簡易体中国語」、「繁体字中国語」は、それぞれに対応したエンコーディングが利用されます。これら以外の時は、すべて Latin1 のエンコーディングが使用されます。UTF-8 と UTF-16 は、BOM によってエンコーディングを判定させることができます。

iPod の仕様がこのようになっているので、日本語で iPod にノートを表示させるならファイルの方は「日本語(Mac OS)」(MacJapanese)で保存するのがいいでしょう。Unicode text として保存しているなら、

  1. BOM を付加する
  2. ファイルの最初にエンコーディングタグを付加する

いずれかの方法で文字化けを回避できるかもしれません。エンコーディングタグは、ファイルの先頭に以下のようなタグを付加することでファイルのエンコーディングを直接指定するものです。

<?xml encoding="MacJapanese"?>

この場合、Unicode text を書き出しているのだから というタグをファイルの先頭に付け加えるといいと思われます。

Automator のアクションを使って iPod にノートを書き出したときになんらかの問題がある場合、

  1. Automator 側に問題がある(AppleScript の文字列の扱い)
  2. iPod の設定に問題がある

のいずれかになります。一概に日本語だから AppleScript でうまく処理できないのが原因とも言えません。Script Editor 上で書き出す限り、きちんと書き出せているのですから。問題は途中で as string としてみたり as Unicode text としてみたり、書き出すときの as オプションがおかしかったり...そういったところにあって、これは対象が日本語でも英語でも同じように文字化けします。この辺りは Automator のアクションの組み合わせによっておこる可能性があります(前のアクションが文字列を加工してし、string 型の文字列を渡した等)。

以上が iPod でノートが表示されないときの主要な原因になります。

Automator の「新規 iPod メモ」アクションは、UTF-16 のファイルを書き出します。これは、TextEdit などで開いてみることができます。しかし、BOM は付加されていません。ですので、iPod の「言語」設定が「日本語」の場合、iPod は「日本語(Mac OS)」でファイルを表示しようとします。ここでファイルのエンコーディングと iPod のエンコーディングの違いが生じるため、

  1. 内容が表示されない
  2. 文字化けが起きる

のいずれかの結果になります。「新規 iPod メモ」アクションが書き出したファイルの先頭にエンコーディングタグか BOM をつければいいのですが、Automator のアクションの中にはそういうものがありません。書き出しされたファイルを TextEdit で開き UTF-16 で別名で保存するのが手っ取り早いでしょうか(TextEdit で UTF-16 エンコーディングを指定して保存すると BOM が付加される)。

結局のところ「新規 iPod メモ」アクションは、常にうまく表示できるファイルを作成できるわけではない、という問題を孕んでいるのですね。

Automator を使って楽をする - その他編

Finder 編、iPhoto 編と続けてきましたが、今回はその他のワークフロー。Mail 編、Safari 編...と続けていけばいいのでしょうが、どうにも数がでてこないし...。なので、便利かなと思えるワークフローなどまとめて紹介。

  • VIDEO_TS を指定して再生
    1. DVD を再生
  • ムービーブラウザ
    1. 選択された Finder 項目を取得
    2. ムービーをブラウズ
  • ダウンローダー
    1. Safari の現在の Web ページを取得
    2. Web ページからリンク URL を取得
    3. URL にフィルタを適用
    4. URL をダウンロード

「DVD を再生」アクションは、再生時の動作を指定することが出来ます。その中に VIDEO_TS を指定するオプションがあります。これを指定してアプリケーションで保存しておけば、VIDEO_TS をアプリケーションにドラッグ & ドロップして即座に DVD Player.app で再生を開始することが出来ます。

Safari の「ムービーをブラウズ」アクションは、QuickTime Player が再生できるファイルを渡すと Safari などのブラウザで閲覧できる HTML を作成してくれます。ここでは「選択された Finder 項目を取得」を最初に持ってきていますが、「ムービーをブラウズ」アクションが渡されたファイルをフィルタリングしてくれるので、なくても構いません。

Automator にはサンプルワークフローとして Safari から画像をダウンロードするワークフローがついていますが、こちらはリンクにフィルタをかけてからダウンロードするダウンローダー。リンクの最後が zip で終わっているなどと指定することで柔軟な一括ダウンロードを実現します。

次は、PDF 関連。

  • ウォーターマーク
    1. PDF にウォーターマークを描画
  • 結合
    1. 選択された Finder 項目を取得
    2. Finder 項目を並べ替える
    3. PDF ページを結合
    4. PDF 書類を名称変更
    5. Finder 項目を移動
  • ファイルサイズを圧縮
    1. 選択された Finder 項目を取得
    2. Finder 項目をコピー
    3. Quartz フィルタを PDF 書類に適用

PDF 関連のアクションは、不可視のテンポラリーフォルダに PDF を作成するので結合などした後には移動させておきます。もちろん、そのままプレビューなどで開いてアプリケーションで別名で保存しても構いません。

「Quartz フィルタを PDF 書類に適用」アクションは、入力が PDF ファイルになっていますが、画像ファイルでも大丈夫。JPEG 画像はそのまま処理できました。

  • 新規 iCal イベント
    1. 新規 iCal イベント
  • イベントの要約
    1. iCal の カレンダー を検索
    2. イベントの要約
    3. 新規テキストファイル

iCal です。イベントを要約してプリントまで持っていきたいところですが、Finder の「Finder 項目をプリント」は日本語環境で使えないのでした。文字化けが起きます。きっと、シェルの lpr を使っているのでしょう。ですので、ファイルに保存するだけです。次は、Mail。

  • ファイルをアーカイブして送信
    1. 選択された Finder 項目を取得
    2. アーカイブを作成
    3. 新規メールメッセージ
    4. 送信メッセージを送信
  • スクリーンキャプチャを送信
    1. スクリーンショットを撮る
    2. 新規メールメッセージ
    3. 送信メッセージを送信
  • グリーティングカード
    1. 誕生日の人を検索
    2. 誕生日のグリーティングを送信
    3. 送信メッセージを送信

「新規メールメッセージ」アクションを実行時に表示させておく方がなにかと使い勝手はいいと思います。「スクリーンショットを撮る」アクションでは保存先を指定しておいてください。クリップボードだと添付されません。個人的にはグリーティングカードをこまめに送るような人は、仕事もできる人だと思う(偏見)。グリーティングカードを送るぐらいの手間は、得することはあっても損することはないですよね。

次は Safari。

  • テキストを読み上げる
    1. Safari の現在の Web ページを取得
    2. Web ページからテキストを取得
    3. テキストを読み上げる
  • テキストをオーディオファイル化
    1. Safari の現在の Web ページを取得
    2. Web ページからテキストを取得
    3. テキストをオーディオファイルにレンダリング
    4. オーディオファイルを読み込む
    5. プレイリストに曲を追加
    6. iPod をアップデート
  • テキストを iPod ノートとして保存
    1. Safari の現在の Web ページを取得
    2. Web ページからテキストを取得
    3. iPod のすべてのメモを削除
    4. 新規 iPod メモ

「Web ページからテキストを取得」アクションは、選択範囲などを指定できないので少し使いにくいのですが。

最後に Finder に戻って。

  • フォルダの内容をカタログ化
    1. Finder 項目の選択を求める
    2. フォルダの内容を取得
    3. 新規テキストエディット書類
  • 表示オプションを指定して新規フォルダを作成
    1. 新規フォルダ
    2. フォルダ表示を設定

Automator のアクションは、様々な項目を出力します。Finder のアクションの多くはファイルやフォルダのパスを出力します。この出力はスラッシュ区切りの UNIX パスの場合もありますし、AppleScript の Finder の参照の場合もあります。が、これらの出力は上記のようにテキストとしても扱うことが可能です。複数項目であってもパスを改行で区切って出力してくれます。

「フォルダの内容を取得」アクションでサブフォルダの内容も取得するようにしておけば、パッケージ内の項目も出力されます。ただし、結果はパスの羅列なので項目数が多いと非常に見にくいです。

「フォルダ表示を設定」アクションは、サブフォルダに変更を適用させることが出来ます。ここでは新規フォルダを指定していますが、例えば、ホームを指定して実行するとホーム以下の全てのフォルダの表示を変更することが出来ます。

さて、様々なワークフローを紹介しきました。紹介してきたワークフローは、こちらからダウンロードできます。Finder 編、iPhoto 編で紹介したものと、今回紹介したもの全てが同梱されています。いつも通りですが、ご利用はご自身の責任で。

Automator を使って楽をする - iPhoto 編

まじめに Autmator をこれだけいじったのは初めてだったり...。いろいろと思うところはあるにせよ、便利は便利(微妙な言い方...)。

前回の Finder 編に続いて、今回は iPhoto 編。iPhoto 編と掲げていますが、主に画像ファイルを扱うワークフローを取り上げます。

まず、デジタルカメラを接続したときに動作するワークフローを。デジタルカメラから画像を取り込むアクション「写真をダウンロード」が用意されているのでこれを利用します。

  • iPhoto に読み込み、別名で保存
    1. 写真をダウンロード
    2. 写真を iPhoto に読み込む
    3. 新規フォルダ
  • 光学メディアに保存し、iPhoto に読み込む
    1. 写真をダウンロード
    2. 写真を iPhoto に読み込む
    3. ディスクを作成

両方とも画像は iPhoto で一元管理し、オリジナルはバックアップしておくことを考えています。「写真をダウンロード」アクションでは画像を取り込んだ後にデジタルカメラから削除するオプションがあるので、それを指定しておきます。「写真を iPhoto に読み込む」アクションでは iPhoto に読み込んだ後にオリジナルのファイルを削除するオプションがあるのでチェックをしておきます。こうしておくと、

  1. デジタルカメラから取り込む
  2. デジタルカメラの画像を消去
  3. iPhoto の読み込む
  4. iPhoto ライブラリの中にファイルが複製される
  5. デジタルカメラから読み込んだファイルを消去
  6. 「写真を iPhoto に読み込む」アクションの出力(iPhoto ライブラリの複製されたファイルの参照)を使って処理を行う

という流れになるので結果的に iPhoto ライブラリの中だけに画像ファイルが残ります。「新規フォルダ」アクションは、ファイルが渡されるとそれらのファイルをコピーしたフォルダを作成します。外付け HDD を指定しておけば、バックアップが行えます(これらのバックアップしたファイルに Spotlight コメントを追加しておくとか、連番処理しておく等の処理に続けることも可能です)。

もちろん、デジタルカメラから取り込んだ画像を消去していくので大事な画像で試す前に実験をしておくことをお進めします。大事な画像がなくなっても責任は取れませんので。

これらのワークフローをワークフローとして保存しておいてスクリプトメニュー等から実行してもいいのですが、アプリケーションとして保存しておき、「イメージキャプチャ.app」の環境設定で「カメラを接続したときに起動する項目」で指定しておくとデジタルカメラを接続したとたんにワークフローが実行されるでさらに便利です。

デジタルカメラから画像を取り込んだら今度は iPhoto での作業になります。iPhoto のアクションには「写真の選択を求める」というアクションがあります。このアクションは iPhoto を起動することなく iPhoto が管理している写真を閲覧することが出来る大変便利なアクションです。

このアクションの出力は iPhoto ライブラリの中にある画像ファイルの参照になります。つまり、加工などの処理を行うときは複製をしてから行います(移動させてしまったりしたら iPhoto のデータベースと齟齬が生じてしまう)。この点にさえ注意しておけば使い勝手のいいアクションです。

  • メールを送る
    1. 写真の選択を求める
    2. Finder 項目をコピー
    3. イメージをサイズ調整
    4. 新規メールメッセージ
    5. 送信メッセージを送信
  • PDF コンタクトシートを印刷
    1. 写真の選択を求める
    2. 新規 PDF コンタクトシート
    3. PDF ページをイメージとしてレンダリング
    4. イメージをプリント
  • ディスクイメージに保存
    1. 写真の選択を求める
    2. 新規ディスクイメージ
  • QuickTime スライドショー(作成日順)
    1. 写真の選択を求める
    2. Finder 項目を並べ替える
    3. Finder 項目をコピー
    4. イメージをサイズ調整
    5. 新規 QuickTime スライドショー
  • アプリケーションを指定して開く
    1. 写真の選択を求める
    2. Finder 項目を開く

ワークフローによっては省略していますが、適宜「Finder 項目をコピー」を利用してください(オリジナルの保護のため)。

PDF コンタクトシートは、選択される画像ファイルとファイル数によってはとてつもなく巨大なサイズのコンタクトシートが作成されます。コンタクトシートをメールなどに添付して送ろうというときは、「PDF」の「Quartz フィルタを PDF に適用」アクションで「Reduce File Size」フィルタを適用してファイルサイズを減らしておくといいと思います。

「ディスクイメージに保存」は、配布用の CD を作成することを想定しています。「アプリケーションを指定して開く」は、Photoshop などで加工する...といった処理を想定しています。目的がなにか分からないとなんのためのワークフローか分からないので...。

しかし...iPhoto 5 しか持っていないので分からないのですが、コメントを追加したりキーワードを追加したり、アルバムに振り分けたりといったアクションがないですね。ほとんど、iPhoto で整理済みの画像を取得するアクションばかりです。iPhoto で行う作業用のアクションがない。困ったものです。

次のワークフローは「写真を確認」アクションを使ったものです。このアクションは、画像をひとつひとつ大きいウィンドウで確認することが出来ます。

  • 承認された画像を iPhoto に読み込む
    1. 選択された Finder 項目を取得
    2. Finder 項目にフィルタを適用
    3. 写真を確認
    4. 写真を iPhoto に読み込む

または、デジタルカメラを接続して取り込んだときに必要な画像を選別するのに利用できます。今回は、こんなところで(今回紹介したワークフローは、こちらからダウンロードできます。もちろんご自身の責任においてご使用してください)。

Automator を使って楽をする - Finder 編

Automator を使って楽をしましょう。今度は真面目に。

まずは、Finder から。Finder のアクションには『選択された Finder 項目を取得』というアクションがあります。複数項目に対してなんらかの処理を行うならこのアクションが使い勝手がいいです。以下のような感じで。

  • Finder の選択項目に Spotlight コメントを追加
    1. 選択された Finder 項目を取得
    2. Finder 項目に Spotlight コメントを追加
  • 選択されているファイルを任意のアプリケーションで開く
    1. 選択された Finder 項目を取得
    2. Finder 項目にフィルタを適用
    3. Finder 項目を開く(任意のアプリケーションを指定)
  • Finder 項目の名前を変更
    1. 選択された Finder 項目を取得
    2. Finder 項目名を連番付きの名前にする
  • Finder の選択項目をプリント
    1. 選択された Finder 項目を取得
    2. Finder 項目にフィルタを適用
    3. Finder 項目をプリント

これらは、Finder のコンテクストメニューとして利用すれば便利です(Automator の「ファイル」メニューの「プラグインを別名で保存...」でプラグインの対象を Finder にして保存)。フォルダ内の全ての項目を選択し、コンテクストメニューから処理という感じ。しかし、これでは不必要なファイルも混じってしまいます。コマンドキーを押しながら一つ一つマウスで項目を選択してもいいのですが、項目が多いとうんざりします。そこで、「Finder 項目にフィルタを適用」というアクションを間に挟んで必要なファイルだけを抜き出すようにすれば、もう一つ使い勝手のいいワークフローになります。

Finder で選択してフィルタを適用してからなんらかの処理をする...こういうワークフローは上記を見ても分かるように、定型です。こういう処理が定型のものはワークフローをひな形にでもしておけばいいのですが、ここは AppleScript のサイト。やっぱり、AppleScript で解決します。以下のスクリプトを実行すると Automator を起動して新しいワークフローを作って「選択された Finder 項目を取得」、「Finder 項目にフィルタを適用」アクションを配置します。

Script Editor で開く

property workflowActions : {{"Finder", "/System/Library/Automator/Get Selected Items.action"}, {"Finder", "/System/Library/Automator/Filter Finder Items.action"}}

on run
    tell application "Automator"
        close every workflow saving no
        set theWorkflow to make new workflow

        repeat with thisAction in workflowActions
            set theAction to my getAction(item 1 of thisAction, item 2 of thisAction)
            if theAction is missing value then error "アクションが見つかりませんでした"
            tell theWorkflow
                add theAction to it
            end tell
        end repeat
        beep
    end tell
end run

on getAction(targetApplication, actionFile)
    tell application "Automator"
        set theAction to Automator actions whose file is actionFile and target application contains targetApplication
        if theAction is {} then return missing value

        return item 1 of theAction
    end tell
end getAction

上記のワークフローは Finder で選択している項目を対象にしていますが、例えば、プロジェクト関連のフォルダの中にあるファイルには同じ Spotlight タグをつけておきたいというとき。いちいち項目を選択してワークフローを実行するのは面倒です。こういうときは、ワークフローをフォルダアクションとして保存しておきます。

  • Spotlight コメントを追加(フォルダアクション用)
    1. Finder 項目に Spotlight コメントを追加

これを「プラグインを別名で保存...」で対象を「フォルダアクション」にして、目的のフォルダに添付すればいいです。フォルダに追加された項目が Automator アクションの入力になります。

必要なファイルだけを探す、ということでいえば Spotlight を使った検索アクションがそれなりに使えます。例えば、今日作成したファイルを検索し、書庫化してファイル名を実行日にする、といったアクションは以下のようになります。

  • 作成日が今日のファイルをアーカイブ
    1. Finder 項目を検索
    2. アーカイブを作成
    3. Finder 項目名に日付または時刻を追加
    4. Finder 項目名に日付または時刻を追加

アクションは、一つのワークフローに対して複数使用できます。最初の「Finder 項目名に日付または時刻を追加」アクションで日付を追加し、次の「Finder 項目名に日付または時刻を追加」で時間を追加します(こうしないと同じファイル名のものが作成されてエラーになるので)。

保存場所と検索する場所を一定にしておけば(ワークフローの作成時に指定しておく)、iCal のアラームを使ってバックアップの自動化が行えます。

ワークフローを作っていると、途中の状態を確認しながら行いたいときがあります。そういうときは「結果を表示」アクションをあいだに挟めばいいのですが、いちいち配置するのが面倒です。で、これもやっぱり AppleScript で行ってしまいます。以下のスクリプトは、最前面のワークフローのアクションの最後に「結果を表示」アクションを配置します。

Script Editor で開く

tell application "Automator"
    if not (exists front workflow) then return

    set theAction to my getAction("Automator", "/System/Library/Automator/View Results.action")
    if theAction is missing value then error "アクションが見つかりませんでした"
    tell front workflow
        add theAction to it
        --execute of it
        beep
    end tell
end tell

on getAction(targetApplication, actionFile)
    tell application "Automator"
        set theAction to Automator actions whose file is actionFile and target application contains targetApplication
        if theAction is {} then return missing value

        return item 1 of theAction
    end tell
end getAction

配置したものは取り除かないといけません。次のスクリプトは全ての「結果を表示」アクションをワークフローから取り除きます。

Script Editor で開く

tell application "Automator"
    if not (exists front workflow) then return

    tell front workflow
        set actionList to Automator actions whose target application contains "Automator" and file is "/System/Library/Automator/View Results.action"

        if actionList is not {} then
            repeat with thisAction in actionList
                remove thisAction
            end repeat
        end if
        beep
    end tell
end tell

Finder のワークフローだけで長く続きますが、Automator を使っていてちょっと不思議に思ったのが上記のワークフローでも使っている「Finder 項目にフィルタを適用」と「Finder 項目の名前を変更」アクション。

フィルタの方はフィルタの条件を複数指定できるのですが、例えば拡張子を「txt」と「text」と二つの条件を指定し「ファイル.txt」と「ファイル.text」を選択して実行しても結果が返ってこない。どちらのファイルも拡張子を指定して取得したいのにできない。いろいろ考えたあげく、これはきっと一つのファイルに対して拡張子が「txt」で「text」のものをフィルタリングしているのだろうなと当たりを付ける。つまり、以下のようなこと。

name extension of thisFile is "txt" and name extension of thisFile is "text"

てっきり、or でフィルタリングしているんだと思っていました。だから、複数の条件を指定すると思った通りの結果にならないことがある。だから、拡張子が「mp3」と「zip」のファイルを一つのワークフローで処理しようとするなら、以下のようにする必要があります。

  • 複数拡張子のファイルの一括処理の例
    1. 選択された Finder 項目を取得
    2. Finder 項目にフィルタを適用
    3. 結果を表示
    4. 選択された Finder 項目を取得
    5. Finder 項目にフィルタを適用
    6. 結果を表示

同じアクションを必要回数配置するのです。スマートじゃない。全く、スマートじゃない。やだ。といっても仕方がないようで。しかし、これは不便じゃない(他のアクションを使えばいいのかもしれませんが)?

そして、「Finder 項目の名前を変更」アクション。このアクションは、Finder ウィンドウで並んでいる順番をみて処理をしてくれるわけではないのですね。Finder ウィンドウをカラム表示していると名前順にファイルが並びますが、実行してこの並び順通りに処理されなくて焦りました。こういう順番が大事なときは「Finder 項目を並び替える」アクションを挟んで、並び替えを指定しておく方がいいようです。

  • 複数項目の並び替えの例
    1. 選択された Finder 項目を取得
    2. Finder 項目にフィルタを適用
    3. Finder 項目を並べ替える
    4. 結果を表示

デジタルカメラの画像の連番処理などは最初に撮影した項目を最初の番号にしたいはず。この並べ替えをしなかったがために撮影日順にならなかった...なんてことにならないように。

上記のワークフローは、こちらからダウンロードできます。適宜、アクションの設定を変更してご利用してください。ただし、なんらかの損害を与えたとしても当方いっさい関知いたしませんので、ご使用はご自身の責任においてお願いします。