01/14 ドロップされたASをTextWranglerでdiff表示
ドロップされたAppleScriptをTextWrangler(version 3.5.3)でdiff表示するAppleScriptです。他のAppleScriptのファイルを処理してdiff表示(差分表示)を行うユーティリティ的なものです。
以前に、「ドロップされたASをdiff表示 Mac OS X 10.4対応版」というものを作ったことがありました。AppleScriptをdiff表示するのに、普通はApple純正のFileMergeを使っているのですが、そのためには文字コードなどの書き換えをする必要があり、TextWranglerを併用して……TextWrangler自体がdiff表示機能を持っていることを思い出し、TextWranglerでdiff表示させるというものでした。
すでに決着が付いたかのように思われていた、AppleScript業界の「diff問題」が再燃したのは、読者がいるんだかいないんだかさっぱり不明なこのBlogの、読者の方からの1通のメールからでした。
『いつもお世話になります。(サイトに)
希望といいますか要望だけで申し訳ないのですが、「ドロップされたASをdiff表示 Mac OS X 10.4対応版」の10.6対応版などを作ってはいただけないでしょうか?
というのも、10.6ならdiff表示v4で十分なはずなんですが、業務PCにてXcodeのインストールが許可されていないという事情がありまして、もしよろしければ、ご検討いただけますようお願いいたします。』
……「スクリプトエディタ」を操作していたところを「AppleScriptエディタ」に書き換えれば瞬殺ではないか、と思って手をつけてみたら……意外とたいへんでした(汗)
Mac OS X 10.6上でTextWranglerを使ってcompare fileコマンドでdiffを取ろうとすると……謎のエラーが出ます。
set oldPath to choose file
set newPath to choose file
set oldPath to oldPath as string
set newPath to newPath as string
tell application “TextWrangler”
compare file oldPath against file newPath
end tell
こんな、最低限の基礎的な記述に戻してあげて(トラブル時にものすごく大事なやりかた)、テキストに書き出したAppleScriptを2つ指定してみると……あいかわらずエラーになります。
「もう、TextWranglerじゃなくて別のツールでも使おうか……」
日も暮れて、そう考えかけたころ、「fileで指定しているのがいけないのでは?」と気付き、aliasで渡してみたら何事もなかったように表示されました。

そもそも、TextWranglerのAppleScript用語辞書(アプリケーションのアイコンをAppleScriptエディタにドラッグ&ドロップすると表示)を見てみると、

などと書いてあるので、「そうかーaliasじゃダメなんだー」と受け取ったからです。これは、TextWranglerのAppleScript用語辞書が間違っています。

▲こんな風に書かなくては(AppleScriptエディタの用語辞書より「open」命令の記述)
このScriptをアプリケーション形式で保存し、出来上がったドロップレットに2つのAppleScript書類をドロップすると、TextWranglerでdiff表示を行います。
| スクリプト名:asdiff |
| on run –環境確認を行うべき(書いてない) –FileMergeの起動を最初にやっておく tell application “System Events” set fmExists to (exists of process “TextWrangler”) end tell if fmExists = false then tell application “TextWrangler” launch end tell end if end run on open fileList tell application “Finder” set sortedList to sort fileList by creation date end tell set sortedList to reverse of sortedList set oldPath to writeASSourceToTempFolder((item 1 of sortedList) as alias) set newPath to writeASSourceToTempFolder((item 2 of sortedList) as alias) –do shell script “/usr/bin/opendiff ” & oldPath’s POSIX path’s quoted form & ” ” & newPath’s POSIX path’s quoted form & ” > /dev/null 2>&1 &” tell application “TextWrangler” compare oldPath against newPath –Mac OS X 10.6用にaliasで渡すように書き換えた end tell end open –AppleScriptのソースを取得してファイルに書き出し on writeASSourceToTempFolder(aScript) –ASのソースを取得 set scriptSource to getContentsOfScript(aScript) of me if scriptSource = false then display dialog “指定のASのオープン時にエラーが発生” return false –エラー end if tell application “Finder” set origName to name of file aScript end tell set origName to makestr_alphabetNumeric_only(origName) of me –tmpにASのソースを一時ファイルとして保存 set tmpPath to (path to temporary items from system domain) as string set aFN to do shell script “/bin/date +%Y%m%d_%H%M%S” set tmpPathFull to tmpPath & origName & “_” & aFN & “.txt” set fRes to write_to_file_UTF8(scriptSource, tmpPathFull, false) of me if fRes = true then return tmpPathFull as alias –書き出したテキストのフルパスを返す(10.6用に変更) else return false –エラー end if end writeASSourceToTempFolder –指定したAppleScriptのソースを取得する(Mac OS X 10.4用) on getContentsOfScript(aScript) tell application “AppleScript Editor” try with timeout of 600 seconds –アプリケーションの起動に時間がかかるケースもあるので180秒から延長 set aScript to open aScript end timeout on error return false end try tell window 1 set aName to name end tell tell document aName set aCon to contents close without saving end tell end tell return aCon end getContentsOfScript –ファイルへのUTF8での書き込み on write_to_file_UTF8(this_data, target_file, append_data) 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 if append_data is false then ? set eof of the open_target_file to 0 write this_data to the open_target_file as «class utf8» starting at eof close access the open_target_file return true on error try close access file target_file end try return false end try end write_to_file_UTF8 –アルファベットと数字のみの文字列にして返す on makestr_alphabetNumeric_only(aKeyword) set aKeyword to aKeyword as string set aKeyword to aKeyword as Unicode text set cList to characters of aKeyword set newName to “” repeat with i in cList set aRes to checkAN(i) of me if aRes = true then set newName to newName & (i as string) end if end repeat return newName end makestr_alphabetNumeric_only on checkAN(aKeyword) set anList to {“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”, “l”, “m”, “n”, “o”, “p”, “q”, “r”, “s”, “t”, “u”, “v”, “w”, “x”, “y”, “z”, “-”, “+”, “.”, “_”, “=”, “(”, “)”, “#”, “$”, “%”, “&”, “~”, “^”, “0″, “1″, “2″, “3″, “4″, “5″, “6″, “7″, “8″, “9″} set aKeyword to aKeyword as Unicode text set aKeyword to aKeyword as string set kList to characters of aKeyword repeat with i in kList ignoring case if i is not in anList then return false end if end ignoring end repeat return true end checkAN |

