ラベル Automator の投稿を表示しています。 すべての投稿を表示
ラベル Automator の投稿を表示しています。 すべての投稿を表示

Automator in Snow Leopard - テキスト編

(個人的に)わりと評価が高い Automator。Snow Leopard で何が変わったかといえば、サービスを作成することができるようになったということだけなのですが、これが地味に便利。コンテクストメニュー地味に便利。

そんなわけで勢いに任せて、作ってみました。

インストーラーパッケージが解凍されるので、あとはダブルクリックしてインストールしてください。いつものことですが、ご利用はご自身の責任でお願いします。

収録されている内容は以下の通りです。

  • Finder • Insert Selections Name

Finder で選択されている項目の名前を挿入します。

  • Finder • Insert Selections POSIX path

Finder で選択されている項目の POSIX パスを挿入します。

  • iTunes • Insert Current Track

iTunes で現在再生されている曲名を挿入します。

  • iTunes • Now Playing

Twitter でよく見かけるようなフォーマット(Now Playing: [Artist] - [Track name])で iTunes で現在再生されている曲名を挿入します。

  • iTunes • Search Artist in ITS

選択されているテキストをアーティスト名としてい iTunes Store で検索を行います。

  • Safari • Insert Current URL

Safari で現在閲覧している Web ページの URL を挿入します。

  • Text • Add Line Number

行頭に 3 桁の行番号を追加します。

  • Text • Add Prefix

行頭に引用符(>)を追加します。

  • Text • Appley Markdown

選択されているテキストに Markdown を適用します。Markdown.pl が /usr/local/bin にインストールされている必要があります。

  • Text • Evaluate Date Format

UNIX の date コマンドで利用できる日時フォーマットを評価します。例えば、%Y-%m-%d なら、2010-05-22 になります。フォーマットについては Terminal で strftime のマニュアルを参照してみてください。

  • Text • Force Line Break

選択されているテキストを 80 文字で強制改行します。

  • Text • Insert Current Date

今日の日付を挿入します。実行するとダイアログでデータのフォーマットを尋ねます。UNIX の date コマンドで利用できるフォーマットを指定してください。デフォルトでは %FT%T%z (2010-05-22T00:10:59+0900)が指定されています。フォーマットについては Terminal で strftime のマニュアルを参照してみてください。

  • Text • Insert MIT License

MIT License を挿入します。現在の年とログインしているユーザーの名前が利用されます。

  • Text • Postal Code to Address

郵便番号を XML-RPC(全国郵便番号一覧 | 郵便専門ネットのWEBサービスAPI)を利用して住所に置き換えます。

  • Text • Replace Numbers to X

選択テキスト内にある半角数字を「X」に置き換えます。

  • Text • Search and Replace by Regex

選択テキストの検索と置換を正規表現を利用して行います。

  • Text • Search and Replace

選択テキストの検索と置換を AppleScript の text item delimiter を利用して行います。

  • Text • Separate by Space

テキスト内の半角英字の前後に半角スペースを挿入します。英単語を半角スペースで区切る(CotEditor) -avoidnote- を参考にさせていただきました。

  • Text • Shift Left

選択テキストの行頭にあるタブを一つ削除します。

  • Text • Shift Right

選択テキストの行頭にタブを一つ追加します。

  • Text • Sort

UNIX の sort コマンドを利用して選択テキストをソートします。

  • Text • Trim Empty Lines

空行を削除します。

  • Text • Trim White Space

行頭と行末にある空白(半角スペースとタブ)を削除します。

  • Text • URL Encode

選択テキストを URL エンコードします。

  • Text • View Postal Code in Google Maps

郵便番号から XML-RPC(全国郵便番号一覧 | 郵便専門ネットのWEBサービスAPI)を利用して住所の緯度と経度を取得し、Google Maps で表示します。

  • Text • View Selection Info

選択されているテキストの情報(文字数、行数、単語数)を表示します。

  • TextEdit • View Header File in TextEdit

open コマンドの -h オプションを利用し、Objective-C ヘッダファイル(NSView.h)を TextEdit で表示します。

  • Xcode • View Header File in Xcode

open コマンドの -h オプションを利用し、Objective-C ヘッダファイル(NSView.h)を Xcode で表示します。

以上、全 28 項目。使いやすいように変更、もしくはそのままでご利用ください。

Automator と AppleScript

Automator で作業をしていると、同じような作業を繰り返していることに気がつきます。定型作業を自動化させるのが Automator の目的なのに、その Automator で同じ作業を繰り返しているなんて。どうも、腑に落ちません。

Automator は登場した当初から AppleScript に対応していました。登場した当初はどうにも重たくて、以来使っていませんでした。Leopard の Automator で「変数」が使えるようになり、「ほう」と思ったものですが、やはりほとんど使いませんでした。

Snow Leopard インストールを期に使ってみたのですが、Automator 自身を Automator で操作できるわけでもなく、Automator の自動化は AppleScript からという環境に変わりはないようです。

唯一、変わったことといえば AppleScript からは「変数」が操作できるようになっていることぐらいでしょうか。反面、新規ワークフローの作成はスムーズにできなくなっています(必ずテンプレートを選択するシートが表示されるので)。

最初にも書いたように Automator は定型作業の繰り返しです。どのワークフローもおおむね同じようなアクションと変数を使います。特に「サービス」関連のワークフローにその傾向があります。

また、デバッグ時に同じようなアクションを何度も追加したり、削除したり...という作業が少なからず発生します。これが、結構手間だったりします。そのためでしょうか、Automator には add と remove という命令が備わっています。

Script Editor で開く

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

    add Automator action "選択された Finder 項目を取得" to front workflow at index 1
end tell

名前参照で書いていますが、互換性を考えるなら Automator action の bundle id 属性などを使う方がいいと思います。

Script Editor で開く

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

    set bundle_identifier to "com.apple.Automator.Get_Selected_Finder_Items_2"
    add Automator action id bundle_identifier to front workflow at index 1
end tell

ファイルやフォルダを処理するサービスなどは「選択された Finder 項目を取得」アクションを最初においてワークフローのデバッグを行うのですが、デバッグが終われば必要なくなります。remove 命令を使えば不必要なアクションや変数を取り除くことができます。

Script Editor で開く

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

    set bundle_identifier to "com.apple.Automator.Get_Selected_Finder_Items_2"

    tell front workflow
        set remove_actions to Automator actions whose bundle id is bundle_identifier
        repeat with this_action in remove_actions
            remove this_action
        end repeat
    end tell
end tell

デバッグ時には特定のアクションの使用、不使用の切り替えを行いたいときがあります。Automator action の enabled 属性で切り替えることができます。次のスクリプトでは使用されているアクションの中から選択されたものを使用停止にします。

Script Editor で開く

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

    tell front workflow
        set action_list to a reference to (Automator actions whose enabled is true)
        if (count of action_list) is 0 then return

        set action_names to name of action_list
        set use_actions to choose from list action_names default items (item 1 of action_names) with multiple selections allowed
        if use_actions is false then return
        repeat with this_action in use_actions
            set enabled of Automator action this_action to false
        end repeat
    end tell
end tell

変数なども同じように add, remove 命令で追加や削除が行えます。次のスクリプトは変数の一覧の中から選択されたものをワークフローに追加します。

Script Editor で開く

tell application "Automator"
    if not (front workflow exists) then return
    set variable_list to name of variables
    my combSort(variable_list)
    set used_variables to choose from list variable_list default items (item 1 of variable_list) with multiple selections allowed
    if used_variables is false then return

    repeat with this_value in used_variables
        add variable this_value to front workflow
    end repeat
end tell

on combSort(theList)
    set gap to count theList

    repeat
        set gap to (gap * 10) div 13
        if gap is 0 then set gap to 1

        set flag to false
        repeat with i from 1 to (count theList) - gap
            if (item i of theList) is greater than (item (i + gap) of theList) then
                set flag to true
                set tmp to item i of theList
                set item i of theList to item (i + gap) of theList
                set item (i + gap) of theList to tmp
            end if
        end repeat
        if not ((gap is greater than 1) or flag) then exit repeat
    end repeat
end combSort

変数などは複数のワークフローで使い回したいときがあります。テンポラリなファイルの保存先などはそういったものの一つです。あるワークフローにある変数を他のワークフローにコピーする...こういうことも add 命令で可能です。次のスクリプトはワークフローの変数を他のワークフローにコピーするスクリプトです。

Script Editor で開く

tell application "Automator"
    activate
    if (count workflows) < 2 then return

    set name_list to name of workflows

    set source_document to choose from list name_list default items (item 1 of name_list) with prompt "Select source workflow:"
    if source_document is false then return
    set source_document to source_document as text

    set name_list to my remove_item(name_list, source_document)

    set destination_document to choose from list name_list default items (item 1 of name_list) with prompt "Select destination workflow:"
    if destination_document is false then return
    set destination_document to destination_document as text

    set original_variables to name of variables of workflow source_document
    set used_variables to choose from list original_variables default items (item 1 of original_variables) with multiple selections allowed
    if used_variables is false then return
    repeat with this_value in used_variables
        set contents of this_value to variable this_value of workflow source_document
    end repeat

    repeat with this_value in used_variables
        add this_value to workflow destination_document
    end repeat
end tell

on remove_item(the_list, removed_item)
    set new_list to {}

    repeat with this_item in the_list
        set this_item to contents of this_item
        if this_item is not removed_item then
            set end of new_list to this_item
        end if
    end repeat

    return new_list
end remove_item

保存されたワークフローの実態はパッケージなんですが、パッケージの中身は至ってシンプルで document.wflow というファイルがあるだけです(サービスなんかだと Info.plist も追加されるけど)。このファイルはすべての情報が書かれているプロパティリストファイルです。ファイルの中をのぞくだけで、そのワークフローがどんなアクションを利用しているかが分かります。

ダウンロードしてきたワークフローの中身を確認するのに Automator を起動する必要はなく、このファイルを見るとすべてが分かります。このことを利用して、Finder で選択されているワークフローで使われているアクションの一覧を表示するスクリプト。

Script Editor で開く

set workflow_plist to ":Contents:document.wflow"

tell application "Finder"
    set current_selection to selection
    if selection is {} then return

    set info_list to {}
    repeat with this_item in current_selection
        set this_item to this_item as text
        set plist_file to this_item & workflow_plist
        if exists (alias plist_file) then
            set workflow_info to my get_action_info(POSIX path of plist_file)

            if workflow_info is not {} then
                set action_text to my join(workflow_info, return & tab)
                set end of info_list to displayed name of alias this_item & return & tab & action_text & return
            end if
        end if
    end repeat
end tell

if info_list is not {} then
    tell application "TextEdit"
        activate
        set the_document to make new document
        set text of the_document to my join(info_list, return)
    end tell
end if

on join(the_list, delimiter)
    tell (a reference to text item delimiters)
        set {tid, contents} to {contents, delimiter}
        set {the_text, contents} to {the_list as text, tid}
    end tell

    return the_text
end join

on get_action_info(workflow_file)
    tell application "System Events"
        set plist_file to property list file (workflow_file)
        tell plist_file
            set action_info_list to {}
            repeat with this_item in property list items of property list item "actions"
                set end of action_info_list to value of property list item "ActionName" of property list item "action" of this_item
            end repeat
        end tell
        return action_info_list
    end tell
end get_action_info

サービスをいくつか作っていると、メニューに表示される名前を変更したいときがあります。これはワークフローの名前を Finder で変更しても変わるわけではなく、変更するには Automator でワークフローを開き別名で再保存するか、ワークフローのパッケージ内にある Info.plist の値を変更する必要があります。いちいちそういうことをするのも面倒なので、作ったのが次のスクリプト。

Script Editor で開く

property file_extensions : {".workflow"}

tell application "Finder"
    set current_selection to selection
    if current_selection is {} then return

    set workflow_files to {}
    repeat with this_item in current_selection
        set file_name to displayed name of this_item
        set this_item to POSIX path of (this_item as text)
        set {file_name, ext} to my splitext(file_name)
        if ext is in file_extensions then
            set plist_file to this_item & "/Contents/Info.plist"
            my set_defaut_menu_item_name(plist_file, file_name)
        end if
    end repeat
end tell

on set_defaut_menu_item_name(plist_file, document_name)
    tell application "System Events"
        if not (disk item plist_file exists) then return missing value

        tell property list file plist_file
            if not (property list item "NSServices" exists) then return missing value
            tell property list item "NSServices"
                if not (property list item "NSMenuItem" of property list item 1 exists) then return missing value
                tell property list item "NSMenuItem" of property list item 1
                    set menu_text to value of property list item "default"
                    if menu_text is not document_name then
                        set value of property list item "default" to document_name
                    end if
                    return value of property list item "default"
                end tell
            end tell
        end tell
    end tell
end set_defaut_menu_item_name

on splitext(file_name)
    set reversed_name to (reverse of (characters of file_name)) as text
    set num to offset of "." in reversed_name
    if num is 0 then
        set ext to ""
    else
        set reversed_ext to text 1 thru num of reversed_name
        set ext to (reverse of (characters of reversed_ext)) as text
        set ext_num to count ext
        set name_length to count file_name
        set file_name to text 1 thru (name_length - ext_num) of file_name
    end if
    return {file_name, ext}
end splitext

Finder で選択されているワークフローのメニュー名をファイルの名称に変更します。

以上のスクリプト以外にもいくつかまとめて。

いつものことですが、ご利用はご自身の責任でお願いします。

ところで、Automator には AppleScript という変数があります。この変数は変わった変数で、AppleScript の実行結果を変数として利用することができます(「シェルスクリプト」という変数もそうだけど)。変数のレベルで AppleScript やシェルスクリプトが利用でき、かつ、アクションにも同じようなアクションがある...。ここまでくるとやりたい放題ですね。

Automator でサービスを作成する前に...

ようやくのことで Snow Leopard を入れてみました。環境を整備し、ソフトウェアを入れ、じっくりと触ってみました。なんだか、描画が変になることがありますし、微妙な違和感(バグかどうかよくわからない現象が時々起こる)があります。Leopard の方が使いやすかったなぁ...。Leopard は手に馴染んでいた。まぁ、使い勝手は慣れてくるのでしょうが。

さて。

今更の感もありますが、Snow Leopard の目玉の一つ、Automator。以前にも Automator の記事を書きましたが、Snow Leopard になっていろいろと便利になったようなので、Snow Leopard に対応したものを。

Automator は、基本的にはなんらかの「入力」を受け取り、それらを「加工」し、加工したものを「出力」します。この処理プロセスはプログラムの基本なのですが、Automator はプログラムらしさを排除し、わかりやすいインターフェースで処理プロセスを作成することができるアプリケーションです。

Automator が入力として受け取れるデータはいろいろとありますが、基本は「ファイル/フォルダ」か「テキスト」です。出力も同様です。

Automator は入力されたデータを「加工」するのですが、データを加工するのが「アクション」です。アクションは単体で動作するものもありますし、それだけでは動作しないものもあります。アクションを一つ、または複数つなげることで目的のデータに加工し、出力します。アクションは直前のアクションが加工したデータを入力として受け取り、次のアクションに加工したデータを渡します。最後のアクションが出力するデータが最終的な結果となります。

アクションを一つ、または複数並べたものを「ワークフロー」といいます。ワークフローを保存しておくことで様々な場面で繰り返し利用することができます。

Automator を起動すると、最初に「ワークフロー」のテンプレートを選択することになります。利用目的によってこれらのテンプレートから一つを選び、ワークフローの作成を開始します。

テンプレート「ワークフロー」は汎用的なワークフローです。目的に応じてワークフローを作成し、保存しておきます。保存したワークフローの利用方法は多岐に渡ります。

保存されたワークフローを ~/Library/Scripts に入れておくことで、スクリプトメニューから利用することができます。また Terminal からワークフローを指定して automator コマンドで処理をさせることができます。

テンプレート「ワークフロー」で作成したワークフローは「プリントプラグイン」、「イメージキャプチャ・プラグイン」としても利用できます。これらは特別に Automator のテンプレートを利用しなくても特定のフォルダの中に入れておくだけで利用できます。

また、ワークフローを「アプリケーション」として保存しておくとドラッグ & ドロップでデータを受け取ることができるようになります。アプリケーション形式だと「iCal アラーム」としても利用できます。

基本的にはテンプレート「ワークフロー」でワークフローを作成、保存しておくことで上記のような利用が可能になります。しかし、このテンプレートでは「サービス」と「フォルダアクション」として利用できるワークフローにはなりません。「サービス」と「フォルダアクション」だけは少し特殊で、これらはテンプレートを利用しないと作成することはできません。

「フォルダアクション」は最初に対象となるフォルダを設定しておく必要があります。フォルダを設定し、保存(~/Library/Workflows/Applications/Folder Actions に保存される)した時点でフォルダアクションは実行されるようになります。停止は ~/Library/Workflows/Applications/Folder Actions から対象のワークフローを取り除くことによって行います。

「サービス」は ~/Library/Services にワークフローとして保存されるのですが、普通のワークフローではなく、サービス経由でデータを受け取れるように設定されて保存されます。この設定があるため、通常のワークフローは「サービス」として利用することができません。

と、まぁ基本的なところは以上でしょうか。

なんといっても目玉は「サービス」なんでしょうね。ところで、Snow Leopard になってから /Library/Scripts にインストールされるスクリプトが減りましたね。Finder 関連のものは全てなくなってしまいました。また、ColorSync のスクリプトは ColorSyncScripting を利用していたのが sips で代用するようになっていますね。Finder 関連のものがなくなったのは Automator の「サービス」があるからいいでしょ、ということでしょうか。

なくなった Finder 関連のスクリプトの代替サービスは Mac OS X Automation: Services Downloads で入手することができます。ここからダウンロードできるサービスとアクションは全て入れておくといいと思います。便利なものが揃っています。中でも面白いのが「Website Popup」というアクション。URL を渡すと半透明の HUD ウィンドウにウェブサイトを表示してくれます。

今回、久しぶりに Automator を本格的に触ってみました(Mac OS X 10.5 の時は全く使っていませんでした)が...、なかなか楽しませて頂きました。Finder 関連のスクリプトがなくなるのもむべなるかな。

しかし、分かりにくいところもありますが。とてつもなく分かりにくいのが、変数。その次に分かりにくいのが「サービス」の「選択項目」と「検索対象」。両方とも理解できるとどうってことないのですが。

まず、「サービス」の「選択項目」。基本的には「選択されているテキスト」か「選択されているファイルまたはフォルダ」のいずれかになります。さらに「選択されているテキスト」は「URL」、「アドレス」、「電話番号」、「日付」、「メールアドレス」のいずれかから選択することができます。例えば、URL を選んでおくと URL 以外の文字列を選択してもサービスのメニューには表示されません。

サービスはこのように賢く振る舞ってくれるのですが、正確には URL を含んでいる文字列を認識し、それをワークフローの入力として渡します。ですから、入力された文字列は、必ずしも正確な URL だとは限りません。正確な URL を抜き出す作業はユーザーに一任です。この作業を行ってくれるアクションは Mac OS X Automation: Services Downloads からダウンロードできます。Get URLs from Text がそれですが、Get Dates from Text というアクションも一緒にぜひとも入れておきましょう。

「ファイルまたはフォルダ」も同様で、例えば「イメージファイル」を選択しておくと「イメージファイル」以外が選択されているときはメニューに表示されません。

「検索対象」は作成した「サービス」がどのアプリケーションで表示されるかを設定するためのものですが、「すべてのアプリケーション」を選択することでどのアプリケーションであってもメニューに表示されるようになります。問題は「選択項目」でこれを「入力なし」にするとアプリケーションのサービスメニューにしか表示されないようになります。コンテキストメニューの方では表示されません。

つまり「選択項目」を「入力なし」、「検索対象」を「すべてのアプリケーション」にすると、すべてのアプリケーションで利用できるけど、アプリケーションメニューのサービスメニューにしか表示されないサービスになるのです。このようなサービスはいつでもどのような状況からでも利用できるメニューになるのでキーボードショートカットを与えておくと便利に利用できます。

「選択項目」と「検索対象」でどこのメニューに表示されるか、どのようなときに表示されるかが決定されます。

Automator は Mac OS X 10.5 の時から「変数」が使えたのですが...正直、目的の変数をどのように作るのか理解するのには骨が折れました。

「変数」は便利なように最初からデフォルトの値を持ったものがあります。歯車のアイコンがついているものがそれです。他方、値をカスタマイズできるように設定を行える変数があります。V というアイコンがついているものがそれです。

これらの用意さている変数を組み合わせて目的の変数を作成します。では、例えば、ファイルを保存するのに一意の名前を付けたい、といったとき。スクリーンキャプチャしてファイルを保存するとき、「Capture-ユーザー名年月日時間」といった書式のファイル名を作りたいとします。

必要なのは「ユーザー名」と「年月日」と「時間」、それに保存する「場所」です。これらは用意されている変数から作成します。

まず、Automato の「変数」を表示し「ユーザー」を選択、その中にある「ユーザー名(ショートネーム)」をダブルクリックします。

Automator で変数を配置する

すると、ウィンドウの下部にある「変数」に「ユーザー名(ショートネーム)」が追加されます。

変数一覧に追加された変数

同様の手順で「場所」から「ピクチャ」を。そして、「日付と時刻」から「今日の日付」と「現在の時刻」を追加します。これらは値をカスタマイズできる変数です。現在、変数一覧は次のようになっています。

追加された変数一覧

「時刻」と「日付」の書式をカスタマイズします。変数一覧にある「今日の日付」をダブルクリックすると小さなウィンドウが表示されます。「名前」は変数名になります。the_date としておきます。「フォーマット」から「カスタムフォーマット...」を選択し、下図のようにします。

日付のフォーマットを変更

年月日の間にあるハイフンは自分で入力します。また、月日はそれぞれ 2 桁になるように変更しておきます。

月日を 2 桁表示に

同様の手順で「現在の時刻」も下図のように変更しておきます。

時刻のフォーマットを変更

以上で必要な変数は揃いました。後はこれらを組み合わせてファイル名を作成します。変数一覧の部分でコンテキストメニューを表示すると「新規変数...」というメニューが現れます。これが、欲しかった変数で見つけるのに時間がかかった変数です。

コンテキストメニューの「新規変数...」メニュー

この変数は「テキストとデータ」にある「テキスト」という変数なのですが、まさか、これを使って複数の変数を組み合わせるなんて思いもよりませんでした。ともかく、「新規変数...」を選択するとこの変数が追加されます。追加された変数をダブルクリックし、下図のようにします。

変数の変更

分かりにくいのですが「値」は変数一覧にある変数をドラッグ & ドロップして追加します。『ピクチャ』「Capture-」『ユーザー名(ショートネーム)』「_」『the_date』「T」『the_time』という並びになっています(『』で囲んでいるものが変数一覧からドラッグ & ドロップしたもの。「」で囲んでいるものは記述したもの)。

この file_name という変数をワークフローのところにドラッグ & ドロップし、「結果を表示」アクションを使うと変数がどのような結果を返すかが確認できます。

変数の結果を確認

こうやって作った変数はスクリーンキャプチャの保存先や、新規テキストファイルの保存先などとして利用することができます。拡張子は必要ありません。適宜、補ってくれます。

変数を保存先に適用

変数はこうやって使うのですね...。全く知りませんでした。

実際にいくつかサービスを作ってみようと思ったのですが...そこにたどり着くまでが長かった。ということで、次の機会にでも。

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. 結果を表示

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

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

Automator を使って楽をする?

いまいち盛り上がりに欠ける気がしますね、Automator。実際、Automator 関連の記事を書いたにもかかわらず、あまり使うことがありません。その目的、コンセプトを見ていると「なるほど、使えると便利なんだな」と思うのですが...。

「Automator を使ったら自動化ができて便利だよ」
「へー、そうなんだ」
「...」
「で、Automator って何ができるの?」

そう、Automator って何ができるか分からない。自動化って何?

「たとえば、『ブログに掲載する画像をリサイズする』ということをどうやっている?」
「Photoshop Elements で画像を開いて大きさを変更して、Web 用に保存してそれをブログにアップロードして...」
「結構、面倒だね」
「うん、面倒」
「そういう面倒な処理を自動でやってくれるのが Automator なんだ」
「へー。やってみて」
「画像リサイズのアクションを置いて、ファイルをアップロード...あれ?アクションがない?」
「できねーじゃん!」

できないことも多いのです。

「ここにたくさんのファイルがあるんだけど...このファイルの名前を変えたいの。でも、数が多いから手でやるのは面倒で...なんかいい方法ない?」
「ああ、こういうときこそ Automator」
「Automator でできるの?」
「もちろん」
「じゃ、お願い」
「『クリスマスパーティーaxcsw051224.jpg』『ハイキングxsdJKf061023.jpg』『ハイキングxsQecdL061023.jpg』『ハイキングweFvbSg061023.jpg』(以下続く)...何この奇妙奇天烈なファイルの名前?」
「うん、そのファイルの名前からアルファベット小文字だけを取り除きたいの」
「...」
「正規表現も使えないのかよ!」

(「シェルスクリプトを実行」、「AppleScript を実行」アクションを使えばできますが)使えません。

「Automator でできるっていつもいうけど、ほとんどできないじゃない!」 「いや、もっと普遍的で一般的な処理なら...」 「なによ!その一般的な処理って!私がしたいのは、私の携帯のカレンダーとアドレスを Mac の iCal とアドレスブックと同じものにしたいってことだけじゃない!」

そう。自動化したい処理って同じ処理でも微妙に要求が違います。使う人の数だけあるといってもいいでしょう。いまのところ Automator では(もしかしたら最も望まれていることかもしれない)微妙な要求に応えてくれることはありません。

「アクションの数が多くてどれがどれだか...」
「そういうときは、ほら、ウィンドウの上のところにあるテキストフィールドに検索したい言葉を入力すれば、アクションを探すことができるよ」
「そうなの?えーと、『画像』と」
「...」
「アクションがないわね」
「『画像』じゃなく『イメージ』で検索するんだよ...」
「なんで?一緒じゃない?私は、日本人よ!馬鹿にするな!」

Automator の検索は賢くありません。

「『Finder 項目に Spotlight コメントを追加』って便利ね。Spotlight と組み合わせれば、簡単にファイルが見つかっちゃう」
「(よかったと思いつつ)Automator も捨てたもんじゃないでしょ?」
「でも、コメントに何を書いたか忘れちゃうのよね。書いたコメントを一覧表示してくれるアクションってないの?」
「...」
「あまり、期待していなかったわ。じゃ、コメントを追加するのを勝手にやってくれるアクションってないの?コメントいちいち追加するのが面倒で...」
「...」
...頬を撫でる一陣の風。今日も冷え込みは厳しい。

ワークフローのご利用は計画的に。