Archive for 4月, 2013

2013/04/29 意外と知られていない掲載ScriptのScriptリンク

たまたまWeb上で見つけた記事で、このBlog内容を参照しているものがあって……

web12.png

web21.png

……思いっきり脱力しました。

こういう無駄な作業をしなくていいように、本Blogのすべての掲載プログラムリストには、開設当初からリストの最下部に、

web3.png

のような「URLリンク」を埋め込んであり、これをクリックするとAppleScriptエディタに内容を直接転送するようになっています(Mac OS X上では)。

  ▼新規書類に:AppleScriptエディタを起動して、新規書類に内容を転送
  ▼カーソル位置に:AppleScriptエディタで編集中のAppleScriptのうち、カーソルがある位置に内容を転送
  ▼ドキュメント末尾に:AppleScriptエディタで編集中のAppleScriptの末尾に内容を転送

となっており、

  >「 “」を「”」に置き換えないといけないけど。

とかいう不毛で無駄で非創造的な作業は一切必要ありません。

ためしに、以下の簡単なAppleScriptのリストの一番下にある「▼新規書類に」のリンクを(Mac OS X上で)クリックしてください。SafariだとOS X 10.8より前は警告なしでオープン。OS X 10.8以降では、システム環境設定の「セキュリティとプライバシー」の設定(いわゆるGateKeeper)に応じて警告されたり、されなかったりします。

web4.png
▲システム環境設定「セキュリティとプライバシー」のデフォルト状態「Mac App Storeからのアプリケーションのみを許可」にしているときに、本Blogなどに設定されているAppleScriptのリンクをクリックしたときに表示される警告ダイアログ

ChromeなどサードパーティのWebブラウザでは「オープンしてよいか?」といった警告ダイアログが出るので、OKすればそれ以降は警告なしでAppleScriptエディタに転送されます。

chrome.jpeg
▲Mac OS X用Google ChromeではじめてScriptリンクをクリックしたときに表示されるダイアログ

スクリプト名:ダイアログ表示テスト
display dialog “テストだよ〜ん” buttons {“OK”} default button 1 with title “ただのテスト!” with icon 1

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

自作のAppleScript→HTML書き出し用AppleScriptをバージョンアップし、デフォルトのファイル名を指定できるようにしました。これ以降、ファイル名を(オリジナルから)反映させるようにしました。

……ほかにも、本Blogに検索機能がついていることを知らない人が大量にいるようで、かなり脱力します、、、

2013/04/29 文字列で指定したラベルの値をレコードから取得する v2

レコード型データ(例:{myAge:25, myData:”ABCDEFG”})から属性ラベルを変数で指定して属性値を取得するAppleScriptです。

レコード型のデータから任意の属性値を取り出すことは可能ですが、属性ラベルをプログラム内に直接記述する必要があります。

  set aRec to {myAge:25, myData:”ABCDEFG”}
  set a to myAge of aRec
  –> 25

このように、もともとのAppleScriptの言語仕様では属性ラベルを間接的に指定する方法が用意されておらず、そのままでは使い勝手がいまひとつです。

しかし、たいていの言語処理系には、言語仕様を超える処理を行うための仕組みが用意されています(用意されていないケースもあります)。AppleScriptの場合だと、それは「run script」コマンドです。文字列で組み立てたAppleScriptのプログラムをそのまま実行して結果を返します。

そんなrun scriptコマンドを用いて、けっこー昔に少々トリッキーな手を使って、間接的に(変数で属性ラベルを)指定して属性値を取り出せるようにしてみました

最初に作ったときにはレコード内容をファイルに書き出すなど、かなり大掛かりな方法を使っていたのですが、その後いろいろ「手口」が洗練され、ファイルに書き出す必要がないことも分りました。海外のユーザーと情報交換を行って、どんどん洗練されていったわけです。

さらに、エラートラップを用いてレコードを文字列化する場合に、言語環境(日本語)に限定されない処理に書き換えたものが本バージョンです。

最初は、Mac OS X上のすべての言語環境に対応するため、(指定可能なすべての)言語ロケール情報を地道に調べて条件分けしていたのですが、

  if aLoc is in {”af”, “sq”, “am”, “ar”, “as”, “az”, “eu”, “be”, “bn”, “bs”, “br”, “bg”, “my”, “ca”, “chr”, “zh”, “hy”, “en”, “fr”, “de”, “it”} then
    –たいていの言語のエラーメッセージは英語なので、同様の対処でOK
    set b to trimStrFromTo(a, “{”, “}”)
    set b to “{” & b & “}”
  else if aLoc = “ja” then
    –Japanese(日本語の場合の対応)
    set b to repChar(a, “のタイプを string に変換できません。”, “”)
  end if

よくよく考えたら(日本語を含む)すべての言語環境で同じ処理でよいことが分り、このようなプログラムに落ち着きました。

sandbox化したAppleScriptObjCのプログラム中で、自由度が高すぎる「run script」文の使用が禁止されたりしたら……高度な処理が行えず、かなり困ることになりますが……Appleとしても様子を見ているところなんでしょう(あるいは、そこまで担当者が気付いていないかのどちらか)。

スクリプト名:文字列で指定したラベルの値をレコードから取得する v2
set aRec to {myAge:36, myHight:166, myWeight:70}
set aLabel to “myHight”

set a to getSpecifiedAttrOfRec(aRec, aLabel) of me
–> 166

–与えられたレコードから指定の属性値ラベルの値を取り出して返す
on getSpecifiedAttrOfRec(aRec, aLabel)
  
  
–パラメータのエラーチェック。エラー時にはmissing valueを返す
  
set aClass to class of aRec
  
if aClass is not record then return missing value
  
if aLabel = “” then return missing value
  
if class of aLabel is not string then return missing value
  
  
–レコードを無理矢理stringにcastして、エラーメッセージを取得する
  
try
    set a to aRec as string
  on error aMes
    set a to aMes
  end try
  
  
–エラーメッセージ文字列から、元のレコードの情報を組み立てる
  
set b to trimStrFromTo(a, “{”, “}”)
  
set b to “{” & b & “}”
  
  
–動的にAppleScriptを生成して、無理矢理レコードから目的の属性値を取り出す
  
set s to “return “ & aLabel & ” of “ & b
  
try
    set recData to run script s
  on error
    return missing value –指定の属性値が存在しなかった場合にはエラー
  end try
  
  
return recData
  
end getSpecifiedAttrOfRec

on trimStrFromTo(aStr, fromStr, toStr)
  –fromStrは前から探す
  
if fromStr is not equal to “” then
    set sPos to (offset of fromStr in aStr) + 1
  else
    set sPos to 1
  end if
  
  
–toStrは後ろから探す
  
if toStr is not equal to “” then
    set b to (reverse of characters of aStr) as string
    
set ePos to (offset of toStr in b)
    
set ePos to ((length of aStr) - ePos)
  else
    set ePos to length of aStr
  end if
  
set aRes to text sPos thru ePos of aStr
  
return aRes
end trimStrFromTo

–文字置換ルーチン
on repChar(origText, targStr, repStr)
  set {txdl, AppleScript’s text item delimiters} to {AppleScript’s text item delimiters, targStr}
  
set temp to text items of origText
  
set AppleScript’s text item delimiters to repStr
  
set res to temp as text
  
set AppleScript’s text item delimiters to txdl
  
return res
end repChar

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

2013/04/27 Keynoteのスライドショー再生中に再生中のスライド番号を取得して音声でレポートする

Keynoteのスライドショー再生中に、再生中のスライド番号(ページ番号)を取得して音声で報告するAppleScriptです。OS X 10.8+Keynoteバージョン5.3で動作確認を行いました。

Keynoteのスライドショー(書類)のうち、どのページを再生中かを取得して音声で報告します。とくに、音声で読み上げる必要性はないのですが、動作内容を理解しやすくするためのテストプログラムなのでこのような実装になっています。

また、アプリケーション(Keynote)の状態を取得して、スライドショーの再生中にのみページ数の読み上げ動作を行います。

本AppleScriptは、アプリケーション形式で、かつ「ハンドラの実行後に終了しない」にチェックを入れた、いわゆる常駐型のアプレットの形式で保存して、保存したアプレットを起動するようにしてください。

スクリプト名:keynoteSlideShowNumberTalker
on run
  
  
end run

on idle
  –Slide Showの再生中かどうかを判定
  
tell application “Keynote”
    set pF to playing
  end tell
  
  
–Slide Show再生中のみスライド番号を読み上げる
  
if pF = true then
    tell application “Keynote”
      tell slideshow 1
        set aSlideNum to slide number of current slide
      end tell
    end tell
    
    
say (aSlideNum as string)
    
  end if
  
  
return 5
  
end idle

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

2013/04/25 並び順をインデックスリストで指定してソート

並び順をインデックスリストで指定して2Dのリストを任意の並び順でソートするAppleScriptです。

日本の47都道府県に関するデータを集め……たとえば、都道府県の人口であれば、人数の多い順からソートするとか、都道府県に付けられたJISコード(全国地方公共団体コード)でソートするなど、いくつか指標となるものはあります。

ただ……都道府県を北から南へ順に並べるような処理をしたい場合には、もうその「並び順自体をデータ化」して、そのとおりにソート対象データを並べ替えるほかありません。

かくして、そのようなサブルーチンを作ってみました。

AppleScript名:並び順をインデックスリストで指定してソート
–並び順を指定するインデックスリスト(この順番にソート対象データを並べ替える)
set indexList to {"北海道", "青森県", "岩手県", "秋田県", "宮城県", "山形県", "福島県", "新潟県", "富山県", "石川県", "福井県", "茨城県", "栃木県", "群馬県", "埼玉県", "千葉県", "東京都", "神奈川県", "長野県", "山梨県", "岐阜県", "静岡県", "愛知県", "三重県", "滋賀県", "京都府", "兵庫県", "大阪府", "奈良県", "和歌山県", "島根県", "岡山県", "鳥取県", "広島県", "山口県", "香川県", "徳島県", "愛媛県", "高知県", "福岡県", "大分県", "佐賀県", "長崎県", "宮崎県", "熊本県", "鹿児島県", "沖縄県"}

–ソート対象データ
set aList to {{"東京都", 301}, {"神奈川県", 98}, {"大阪府", 90}, {"千葉県", 60}, {"埼玉県", 55}, {"北海道", 40}, {"愛知県", 40}, {"京都府", 40}, {"兵庫県", 40}, {"福岡県", 30}, {"静岡県", 20}, {"広島県", 20}, {"茨城県", 20}, {"宮城県", 16}, {"長野県", 15}, {"福島県", 12}, {"新潟県", 11}, {"滋賀県", 10}, {"岐阜県", 10}, {"群馬県", 10}, {"石川県", 10}, {"熊本県", 9}, {"岡山県", 9}, {"福井県", 7}, {"青森県", 7}, {"秋田県", 6}, {"愛媛県", 6}, {"和歌山県", 6}, {"奈良県", 5}, {"三重県", 5}, {"沖縄県", 5}, {"岩手県", 5}, {"大分県", 4}, {"鹿児島県", 4}, {"宮崎県", 4}, {"栃木県", 3}, {"香川県", 3}, {"山形県", 3}, {"富山県", 2}, {"山梨県", 2}, {"長崎県", 2}, {"徳島県", 2}, {"島根県", 2}, {"鳥取県", 1}, {"高知県", 1}, {"山口県", 1}}

set bList to sortItemByIndexList(aList, indexList, 1, 2) of me
–> {{"北海道", 40}, {"青森県", 7}, {"岩手県", 5}, {"秋田県", 6}, {"宮城県", 16}, {"山形県", 3}, {"福島県", 12}, {"新潟県", 11}, {"富山県", 2}, {"石川県", 10}, {"福井県", 7}, {"茨城県", 20}, {"栃木県", 3}, {"群馬県", 10}, {"埼玉県", 55}, {"千葉県", 60}, {"東京都", 301}, {"神奈川県", 98}, {"長野県", 15}, {"山梨県", 2}, {"岐阜県", 10}, {"静岡県", 20}, {"愛知県", 40}, {"三重県", 5}, {"滋賀県", 10}, {"京都府", 40}, {"兵庫県", 40}, {"大阪府", 90}, {"奈良県", 5}, {"和歌山県", 6}, {"島根県", 2}, {"岡山県", 9}, {"鳥取県", 1}, {"広島県", 20}, {"山口県", 1}, {"香川県", 3}, {"徳島県", 2}, {"愛媛県", 6}, {"高知県", 1}, {"福岡県", 30}, {"大分県", 4}, {"佐賀県", 0}, {"長崎県", 2}, {"宮崎県", 4}, {"熊本県", 9}, {"鹿児島県", 4}, {"沖縄県", 5}}

–並び順をインデックスリストで指定してソート
–パラメータ: (1) aList=ソート元リスト ({{"name1", number1}, {"name2", number2}……} )、
–      (2) indexList=ソート順指定用インデックスリスト、
–      (3) itemNo=並べ替え対象アイテム番号(ソート元リスト内の各リスト要素内のソートキーになるアイテムの番号)
–      (4) nohitItem=インデックス項目がソート元リストに対してヒットしなかった場合の、件数0を入れるアイテム番号
–エラー:    エラー時にはfalseを返す
on sortItemByIndexList(aList, indexList, itemNo, nohitItem)
  –処理高速化のためにハンドラ内部にScript Objectを宣言してデータアクセス
  
script sortItemByIndexListObj
    property indexListSpd : indexList
    
property aListSpd : aList
  end script
  
  
–パラメータのエラーチェック
  
set tmpItem to contents of first item of aList
  
set tmpLen to length of tmpItem
  
  
–itemNoのエラーチェック
  
if (itemNo < 1) or (itemNo > tmpLen) then return false
  
–nohitItemのエラーチェック
  
if (nohitItem < 1) or (nohitItem > tmpLen) then return false
  
–itemNoとnohitItemが衝突していないかチェック
  
if itemNo = nohitItem then return false
  
  
  
–処理本体
  
set outList to {}
  
repeat with i in indexListSpd of sortItemByIndexListObj
    set j to contents of i
    
    
set hitF to false
    
    
repeat with ii in aListSpd of sortItemByIndexListObj
      set targItem to contents of item itemNo of ii
      
if targItem = j then
        set the end of outList to contents of ii
        
set hitF to true
        
exit repeat
      end if
    end repeat
    
    
–合致するデータがなかった場合の対応
    
if hitF = false then
      set tmpList to {}
      
repeat nohitItem times
        set the end of tmpList to ""
      end repeat
      
set item itemNo of tmpList to j
      
set item nohitItem of tmpList to 0
      
set the end of outList to tmpList
    end if
    
  end repeat
  
  
outList
  
end sortItemByIndexList

★Click Here to Open This Script 

2013/04/25 年代のデータから、{開始年, 終了年} のリストを作成 v2

生まれた年を10年刻みの「年代」別にとらえてデータ集計を行いたいときに、どの年代別の集計を行いたいかをリストで与えておくと、その実際の「開始年」「終了年」のリストを作成してくれるAppleScriptです。

元データは、1950年代、1960年代、1970年代……というリストのデータにしておいて、

  set condList to {1950, 1960, 1970, 1980, 1990, 2000, 2010}

そこから厳密な開始年,終了年を求めます。

  –> {{0, 1959}, {1960, 1969}, {1970, 1979}, {1980, 1989}, {1990, 1999}, {2000, 2009}, {2010, 2019}}

最初のアイテムだけはそれ以前(1940年代とか1930年代とか)のデータの受け皿とするために、開始年を0年に設定しています。

10年刻みだとか、そういう暗黙の「お約束」をそのままコーディングしていますが、条件として与えられた最初のリストから、分析するようにすべきでしょう。

昔は、データ集計といえば(Classic Mac OSの頃はOSの安定性もイマイチだったので)安全のためにFileMaker Proを外部からAppleScriptでコントロールして集計を行うことが(個人的に)多かったのですが、Mac OS XになってOSの安定性とかソートライブラリの量が昔とは比較にならないほど向上したため、ほとんどAppleScriptだけで行うようになりました。

あるいは、FileMaker Proからデータを取り出して、あとはひたすらAppleScriptだけでデータの集計や抽出を行うとか。そういうデータ処理のために、こういう(他人から見ると謎な存在の)プログラムをコツコツ作っています。

スクリプト名:年代のデータから、{開始年, 終了年} のリストを作成 v2
set condList to {1950, 1960, 1970, 1980, 1990, 2000, 2010}
set conList to retStartEndCondition(condList) of me
–> {{0, 1959}, {1960, 1969}, {1970, 1979}, {1980, 1989}, {1990, 1999}, {2000, 2009}, {2010, 2019}}

–年代のデータから、{開始年, 終了年} のリストを作成
on retStartEndCondition(condList)
  
  
set newConList to {}
  
  
set firstF to true
  
repeat with i in condList
    
    
if firstF = true then
      set startNum to 0
      
set endNum to (contents of i) + 9
      
set firstF to false
    else
      set startNum to contents of i
      
set endNum to i + 9
    end if
    
    
set the end of newConList to {startNum, endNum}
    
  end repeat
  
  
newConList
  
end retStartEndCondition

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

2013/04/23 ネットワークごしにクリップボードの内容を転送

ネットワーク(LAN)ごしにクリップボードの内容を転送するAppleScriptです。

ソフトウェアのマニュアルを作っているようなときに、ネットワーク上の別のマシン(異なるバージョンのOSで稼働しているとか)上で画面キャプチャを撮り、ネットワーク経由でクリップボード内の画面キャプチャの内容を転送してドキュメントに貼り込む……といった利用スタイルを前提としています。

clip3.png

AppleScript同士でリモートアップルイベントを介して通信するので、OSバージョンが極端に異なっていても大丈夫です。実際に、OS X 10.8.3のマシンとMac OS X 10.5.8のマシン間でクリップボードの内容を転送しています。

受信側(MBPretina)では、システム環境設定の「共有」で「リモートアップルイベント」を受け付けるように設定しておきます。

clip1.png

さらに、クリップボード内容の受信用アプレット「clipRelay」を起動したままにしておきます。この「clipRelay」アプレットは常駐型にで保存しておきます。

clip2.png

リモート側マシンで画面キャプチャ内容をクリップボードに入れた状態で、「クリップボード転送」Scriptを実行すると、指定マシン(ここではMBPretina)にクリップボードの内容を転送します。初回のみ、受信側のユーザー名とパスワードを入力する必要があります。

clip4.png

「クリップボード転送」Scriptを実行すると、即座にリモート側から受信側に内容が転送されます。

適宜、お使いの環境に合わせて「クリップボード転送」内のマシン名称を書き換えて実行してください。

スクリプト名:clipRelay
on run
  tell me to activate
end run

on idle
  
  
return 1
  
end idle

on setClip(aData)
  
  
set the clipboard to aData
  
beep
  
end setClip

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

スクリプト名:クリップボード転送
–do shell script “defaults write com.apple.screencapture disable-shadow -bool true && killall SystemUIServer”

try
  set aData to the clipboard
on error
  display dialog “クリップボードが空です” buttons {“OK”} default button 1 with icon 1
  
return
end try

tell application “clipRelay” of machine “eppc://MBPRetina.local”
  
  
setClip(aData)
  
end tell

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

2013/04/21 Skim 1.4.3で追加されたfavorite colorsにアクセス

オープンソースのPDFビューワー「Skim」の最新バージョン1.4.3で追加された属性「favorite colors」にアクセスするAppleScriptです。

applicationの属性値としてfavorite colorsが追加されました。

skim0.png

スクリプト名:Skim 1.4.3で最近使った色を取得
tell application “Skim”
  set aList to favorite colors
end tell

–> {{65535, 0, 0, 65535}, {65535, 32768, 0, 65535}, {65535, 65535, 0, 65535}, {0, 65535, 0, 65535}, {0, 0, 65535, 65535}, {65535, 0, 65535, 65535}}

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

結果は、{R(赤),G(緑),B(青),A(アルファ値)}のセットのリストで返ってきます。各値は16ビットの数値です。

skim1.png

skim2.png

色の値は16ビットなのでchoose colorでプレビューするときには簡単(アルファチャネルは無視)ですが、一般的なアプリケーションの多くでは8ビットの値で扱っているので、16ビット→8ビット変換のためにちょっとだけ計算を追加で行う必要があります。

スクリプト名:Skim 1.4.3の最近使った色をプレビュー
tell application “Skim”
  set aList to favorite colors
end tell

repeat with i in aList
  set {r, g, b, a} to i
  
set aCol to {r, g, b}
  
  
choose color default color aCol
  
end repeat

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

2013/04/18 24時間以上の時間を指定されることを前提として時刻および日付を解釈してdateオブジェクトを返す

日付文字列(YYYY/MM/DD)と時刻の文字列(hh:mm:ss)からdateオブジェクトを作成するAppleScriptです。dateオブジェクトに変換するさい、28時などの24時を超える表記を考慮して日付計算に反映しています。

OS X 10.8のdateオブジェクトのバグ(日本語環境で発生)の影響は受けていません(OS X 10.8.3上にて検証)。

スクリプト名:24時間以上の時間を指定されることを前提として時刻および日付を解釈してdateオブジェクトを返す
set aTime to "28:00:00"
set aDate to "2013/04/19"

set aDateObj to retDateObj(aDate, aTime) of me
–> date "2013年4月20日土曜日 4:00:00"

–24時間以上の時間を指定されることを前提として時刻および日付を解釈してdateオブジェクトを返す
on retDateObj(aDate, aTime)
  
  
set hList to parseByDelim(aTime, ":") of me
  
set hNum to (contents of first item of hList) as number
  
set dPlus to hNum div 24 –日付の繰り上がり分
  
set hNew to (hNum mod 24) as string
  
  
set first item of hList to hNew
  
set newTime to retConcatText(hList, ":") of me
  
  
set newDateStr to aDate & " " & newTime
  
set newDateObj to (date newDateStr) + dPlus * days
  
  
return newDateObj
  
end retDateObj

–与えられた文字列を、指定デリミタ文字でparseしてリストにして返す
on parseByDelim(aData, aDelim)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set dList to text items of aData
  
set AppleScript’s text item delimiters to curDelim
  
return dList
end parseByDelim

–リストを任意のデリミタ付きでテキストに
on retConcatText(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 retConcatText

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

2013/04/17 WebViewでローディング完了通知

WebViewで任意のURLのWebを表示し、Webコンテンツのローディングが完了したら通知するAppleScriptObjCのサンプルです。

web11.png

web2.png

自前のWebブラウザを作って、ローディング完了通知をもらうのは簡単ですが……Safari内部のローディング完了通知なんかを取れないものかと考えてしまうところ。

→ Xcodeプロジェクトのダウンロード

AppleScriptObjCファイル名:wbTestAppDelegate.applescript

– wbTestAppDelegate.applescript
– wbTest

– Created by 長野谷 隆昌 on 13/04/17.
– Copyright 2012 Piyomaru Software. All rights reserved.


script wbTestAppDelegate
  property parent : class “NSObject”
  
  property webview : missing value
  
property internetlocation : missing value
  
  
  on applicationWillFinishLaunching_(aNotification)
    
    –Web Viewのローディング完了通知をNotification Centerに登録
    
set noter1 to current application’s NSNotificationCenter’s defaultCenter()
    
noter1’s addObserver_selector_name_object_(me, “webLoaded:”, current application’s WebViewProgressFinishedNotification, webview)
    
  end applicationWillFinishLaunching_
  
  
  on applicationShouldTerminate_(sender)
    return current application’s NSTerminateNow
  end applicationShouldTerminate_
  
  
  on clicked_(aSender)
    
    set aurlobj to internetlocation’s stringValue()
    
set aurlobj to aurlobj as string
    
    –URLのプロトコルヘッダーが欠けている場合には補完
    
if (aurlobj does not start with “http://”) and (aurlobj does not start with “https://”) then
      set aurlobj to “http://” & aurlobj
    end if
    
    –指定URLをオープンする
    
webview’s setMainFrameURL_(aurlobj)
    
  end clicked_
  
  
  –Web Viewのローディング完了時に実行
  
on webLoaded_(aNotification)
    display dialog “Loaded”
  end webLoaded_
  
end script

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

2013/04/16 AppleScriptObjCでPDFViewを使ってPDFをプレビュー(4)

AppleScriptObjCでPDFをプレビューするテストプログラムをその後進展させたものです。

ようやく、現在表示中のPDFの選択中のページのインデックス番号(0からはじまる通し番号)を取得できるようになりました。

→ Xcodeプロジェクトのダウンロード

PDF Kit Programming Guideの「PDF Kit Tasks」を参照し、そのとおりにAppleScriptObjCで書いても動かず、延々とデバッグを行い…………………………「document」を「|document|」と修正したところ、何の問題もなく動作しました。

このあたりは、Xcode上でチェックしたり対策してくれないと、なかなか気付きません。

AppleScriptObjC Explorer2を外部からAppleScriptでコントロールして、自動でチェックするようにしたほうがよいかもしれません(XcodeのAppleScript用語辞書の実装はあいかわらずタコなままなので、Xcodeをこづき回しても得るものが少ない。また、AppleScriptの構文色分けを反映しなくなったのは納得できません)。

本サンプルは、選択したPDFをPhotoshopでレンダリングして画像にするための「プレビュー」を目的としており、対象ファイル、対象ページ、レンダリング解像度などを取得してPhotoshopでレンダリングするフローの中で使用する部品として想定しています。実際にはこの部品は(間に合わなかったので)使用せず、もっと簡易な仕様の部品を使いましたが……次回はこの部品の改良版を投入したいところです。

pdf1.png

pdf2.png

AppleScriptObjCファイル名:AppDelegate.applescript

– AppDelegate.applescript
– pdftest2

– Created by Takaaki Naganoya on 2013/04/16.
– Copyright (c) 2012年 Takaaki Naganoya. All rights reserved.


script AppDelegate
  property parent : class “NSObject”
  
property nsurl : class “NSURL”
  
property PDFDocument : class “PDFDocument”
  
  
  property pdfPreviewWin : missing value
  
property pdfView : missing value
  
property pdfThumb : missing value
  
  property pdfPageText : missing value
  
  
  
  on applicationWillFinishLaunching_(aNotification)
    
    pdfView’s setAllowsDragging_(false)
    
pdfView’s setDelegate_(me)
    
    
    pdfThumb’s setMaximumNumberOfColumns_(2)
    
pdfThumb’s setAllowsMultipleSelection_(false)
    
    –書類が変更になった(オープンされた場合)Notificationの処理先ハンドラを登録
    
set noter1 to current application’s NSNotificationCenter’s defaultCenter()
    
noter1’s addObserver_selector_name_object_(me, “pdfChange:”, current application’s PDFViewDocumentChangedNotification, pdfView)
    
    –ページが変更になったNotificationの処理先ハンドラを登録
    
noter1’s addObserver_selector_name_object_(me, “pdfPageChange:”, current application’s PDFViewPageChangedNotification, pdfView)
    
    
    
    –ファイルを選択
    
set aFile to choose file of type “com.adobe.pdf”
    
set aFileString to aFile as Unicode text
    
dispPDFWithHFSpath_(aFileString)
    
    
  end applicationWillFinishLaunching_
  
  
  
  –プレビューウィンドウをセンタリング(見た目以外にとくに意味なし)
  
on applicationDidFinishLaunching_(aNotification)
    
    pdfPreviewWin’s |center|()
    
  end applicationDidFinishLaunching_
  
  
  
  –HFSパスの文字列を渡すとPDFViewに表示する
  
on dispPDFWithHFSpath_(aFileString)
    
    set aFileString to aFileString as Unicode text
    
    tell application “Finder”
      set aFileURL to (URL of file aFileString)
    end tell
    
    set aFileURL to aFileURL as Unicode text
    
set theURL to nsurl’s URLWithString_(aFileURL)
    
    set aPDFdoc to PDFDocument’s alloc()’s initWithURL_(theURL) –allocわすれてた、、、
    
pdfView’s setDocument_(aPDFdoc)
    
  end dispPDFWithHFSpath_
  
  
  on applicationShouldTerminate_(sender)
    return current application’s NSTerminateNow
  end applicationShouldTerminate_
  
  
  –表示ページが変更になった場合にnotificationでこちらを呼び出している
  
on pdfPageChange_(notification)
    
    dispPDFPageNumber()
    
  end pdfPageChange_
  
  
  –ファイルの新規オープン、および表示ページが変更になった場合にnotificationでこちらを呼び出している
  
on pdfChange_(notification)
    
    dispPDFPageNumber()
    
  end pdfChange_
  
  
  –PDFページ数を表示する
  
on dispPDFPageNumber()
    
    set curDoc to pdfView’s |document| –ここが問題の箇所!!!
    
set curPage to pdfView’s currentPage
    
set curPageNumber to curDoc’s indexForPage_(curPage)
    
    pdfPageText’s setStringValue_((curPageNumber + 1) as string)
    
  end dispPDFPageNumber
  
  
end script

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

2013/04/15 Photoshop上で選択範囲を指定色(RGB)で塗りつぶす

Photoshopでオープン中の画像の選択範囲に対して、指定のRGB色で塗りつぶすAppleScriptです。

あらかじめPhotoshopで何がしかの画像をオープンしておき、選択範囲を作成しておく必要があります。

スクリプト名:Photoshop上で選択範囲を指定色(RGB)で塗りつぶす

fillPhotoshopSelectedRegion(0, 0, 255) of me

–Photoshop上で選択範囲を指定色(RGB)で塗りつぶす
on fillPhotoshopSelectedRegion(rNum, gNum, bNum)
  tell application id "com.adobe.photoshop"
    tell current document
      set aCol to {class:RGB color, red:rNum, green:gNum, blue:bNum}
      
      
fill selection with contents aCol
    end tell
  end tell
end fillPhotoshopSelectedRegion

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

2013/04/15 Photoshopでオープン中の画像をグレースケール→白黒2値の画像にモードを変換する

Photoshopでオープン中の画像をグレースケール→白黒2値の画像にモード変換するAppleScriptです。

白黒2値に変換するさいには、階調をディザ拡散で表現するよう指定しています。

col10.png

スクリプト名:Photoshopでオープン中の画像をグレースケール→白黒2値の画像にモードを変換する
tell application id "com.adobe.photoshop"
  tell current document
    try
      –RGB 8ビットカラー→グレースケール
      
change mode to grayscale
      
      
–グレースケール→白黒2値
      
set aOPT to {class:Bitmap mode options, resolution:72, conversion method:diffusion dither} –ディザ拡散
      
–set aOPT to {class:Bitmap mode options, resolution:72, conversion method:pattern dither}–パターンディザ
      
change mode to bitmap with options aOPT
    end try
  end tell
end tell

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

2013/04/13 Photoshop CS6で指定RGB色の指定明度差の2色を計算する

Photoshop CS6で、指定色に対して(L*a*b*のL*の値で)指定分だけ明るい色と暗い色を計算してRGB値で返して色プレビューを行うAppleScriptです。

col11.png
▲指定した色

col21.png
▲指定色からL値で+10だけ明るい色のプレビュー

col3.png
▲指定色からL値で-10だけ暗い色のプレビュー

スクリプト名:Photoshop CS6で指定RGB色の指定明度差の2色を計算する
set aDiffL to 10 –明度差

–色選択
set {rCol, gCol, bCol} to choose color

–16ビット値→8ビット値 変換
set rCol to rCol div 256
set gCol to gCol div 256
set bCol to bCol div 256

set aLAB to retLABfromRGBnumList(rCol, gCol, bCol) of me

copy aLAB to {elNum, aNum, bNum}

set bRGB to retRGBfromLABnumList(elNum + aDiffL, aNum, bNum) of me –明るい色
set cRGB to retRGBfromLABnumList(elNum - aDiffL, aNum, bNum) of me –暗い色

–色プレビューしてみる
set aRes to col8bitRGBPreview(bRGB) of me
set aRes to col8bitRGBPreview(cRGB) of me

–与えられたリスト数値のRGBデータをLAB値に変換して返す
–R:0〜255, G:0〜255, B:0〜255 
–L*:0.0〜100.0, a*:-128.0〜127.0, b*: -128.0〜127.0
on retLABfromRGBnumList(rNum, gNum, bNum)
  
  
tell application “Adobe Photoshop CS6″
    set myLABColor to convert color {class:RGB color, red:rNum, green:gNum, blue:bNum} to Lab
    
    
set L_Num to value_L of myLABColor
    
set A_Num to value_a of myLABColor
    
set B_Num to value_b of myLABColor
    
  end tell
  
  
return {L_Num, A_Num, B_Num}
  
end retLABfromRGBnumList

–与えられたリスト数値のLABデータをRGB値に変換して返す
–R:0〜255, G:0〜255, B:0〜255 
–L*:0.0〜100.0, a*:-128.0〜127.0, b*: -128.0〜127.0
on retRGBfromLABnumList(elNum, aNum, bNum)
  
  
tell application “Adobe Photoshop CS6″
    set myRGBColor to convert color {class:Lab color, value_L:elNum, value_a:aNum, value_b:bNum} to RGB
    
    
set redNum to red of myRGBColor
    
set greenNum to green of myRGBColor
    
set blueNum to blue of myRGBColor
  end tell
  
  
set redNum to round redNum rounding as taught in school –四捨五入
  
set greenNum to round greenNum rounding as taught in school –四捨五入
  
set blueNum to round blueNum rounding as taught in school –四捨五入
  
  
  
return {redNum, greenNum, blueNum}
  
end retRGBfromLABnumList

–0〜255の8ビットの値から構成されるRGB値のリスト {r,g,b} の色をchoose colorでプレビューする
on col8bitRGBPreview(rgbColList)
  set aLen to length of rgbColList
  
  
if aLen is not equal to 3 then return false
  
  
set {r, g, b} to rgbColList
  
  
set asR to r * 256
  
set asG to g * 256
  
set asB to b * 256
  
  
set prevCol to {asR, asG, asB}
  
  
choose color default color prevCol
  
  
return true
  
end col8bitRGBPreview

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

2013/04/13 PowerPointで、オブジェクトの外側の線の色を、水色から青に変更

Office 2011のPowerPointで、各スライド上に存在するオブジェクト(shape)のうち、水色の枠線を適用しているものを抽出して、青の枠線に変更するAppleScriptです。

PowerPoint書類上で、本来は青(↓)

col2.png

の枠線を引く必要があったものに、誤って水色(↓)

col1.png

の枠線を引いた箇所がいくつかあるのを見つけました。

そんな微妙な間違いを目視で確認して修正するのは事実上不可能なので、AppleScriptを書いて自動で修正しました。

ppt_before.png
▲AppleScript実行前

pptafter.png
▲AppleScript実行後(うわ、違いがびみょ〜)

技術的なみどころは、オブジェクト階層の奥まった場所にある属性値をa reference toで直接参照して書き換えしているところです。

スクリプト名:PowerPointで、オブジェクトの外側の線の色を、水色から青に変更
–水色の線を青に変更
tell application “Microsoft PowerPoint”
  tell active presentation
    set sCount to count every slide
    
    
repeat with i from 1 to sCount
      tell slide i
        set ssCount to count every shape
        
        
repeat with ii from 1 to ssCount
          
          
tell shape ii
            set aProp to properties
            
set aLineF to line format of aProp
            
set fcData to fore color of aLineF
          end tell
          
          
if fcData = {51, 102, 255} then
            set aRef to (a reference to fore color of line format of shape ii)
            
set fore color of aRef to {0, 0, 255} –線の塗り色を青 {0,0,255} に変更
          end if
          
        end repeat
        
      end tell
    end repeat
    
  end tell
end tell

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

2013/04/13 Photoshop CS6でRGB→RGB Hex、RGB Hex→RGB変換

Photoshop CS6で、RGB値とWebで利用するRGB16進数の文字列の相互変換を行うAppleScriptです。

Photoshop CS6の色空間の相互変換命令「convert color」のオプションにRGB Hexの記述があったので、本当に使えるのかどうか試すために書いてみたものです。

実際には、その程度ならAppleScript単体で処理できるので、「こんな機能もあるのか、へー」と感心する以上の実用性はありません。

ほかにも、Photoshop CS6の「convert color」命令はgrayscaleの色空間も扱えるようですが、さすがにそれは使わなさそうな……

スクリプト名:Photoshop CS6でRGB→RGB Hex、RGB Hex→RGB変換
–色選択
set {rCol, gCol, bCol} to choose color

–16ビット値→8ビット値 変換
set rCol to rCol div 256
set gCol to gCol div 256
set bCol to bCol div 256

set aRGBhexStr to retRGBhexfromRGBnumList(rCol, gCol, bCol) of me

set bRGB to retRGBfromRGBhexStr(aRGBhexStr) of me

return {{rCol, gCol, bCol}, aRGBhexStr, bRGB}
–> {{0, 128, 255}, "0080FF", {0, 128, 255}}

–与えられたリスト数値のRGBデータをRGB Hex文字列に変換して返す
–R:0〜255, G:0〜255, B:0〜255 
on retRGBhexfromRGBnumList(rNum, gNum, bNum)
  
  
tell application "Adobe Photoshop CS6"
    set myRGBColor to convert color {class:RGB color, red:rNum, green:gNum, blue:bNum} to RGB Hex
    
    
set aHex to hex value of myRGBColor
    
  end tell
  
  
return aHex
  
end retRGBhexfromRGBnumList

–与えられたRGB hex文字列データをRGB値に変換して返す
–R:0〜255, G:0〜255, B:0〜255 
on retRGBfromRGBhexStr(aRGBhexStr)
  
  
tell application "Adobe Photoshop CS6"
    set myRGBColor to convert color {class:RGB hex color, hex value:aRGBhexStr} to RGB
    
    
set redNum to red of myRGBColor
    
set greenNum to green of myRGBColor
    
set blueNum to blue of myRGBColor
  end tell
  
  
set redNum to round redNum rounding as taught in school –四捨五入
  
set greenNum to round greenNum rounding as taught in school –四捨五入
  
set blueNum to round blueNum rounding as taught in school –四捨五入
  
  
  
return {redNum, greenNum, blueNum}
  
end retRGBfromRGBhexStr

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

2013/04/13 Photoshop CS6でRGB→HSB、HSB→RGB変換

Photoshop CS6でRGB値とHSB値の相互変換を行うAppleScriptです。

海外でPhillipsのHueをコントロールするScriptを調べていたときに、カラーの値をHSBで与える(RGBでも指定できる?)ようで、RGBとHSBの変換を行うshell scriptのプログラムを見て、どうしよう(shellの内容をそのまま使うか、AppleScriptにすべて書き換えるか)と思っていたら……こんなお手軽な方法が、、、、

ただ、RGBとHSBの変換のためだけにPhotoshop CS6を使うというのも、それはそれでものすごく何かの無駄遣いのような……

スクリプト名:Photoshop CS6でRGB→HSB、HSB→RGB変換
–色選択
set {rCol, gCol, bCol} to choose color

–16ビット値→8ビット値 変換
set rCol to rCol div 256
set gCol to gCol div 256
set bCol to bCol div 256

set aHSB to retHSBfromRGBnumList(rCol, gCol, bCol) of me

copy aHSB to {hue_Num, saturation_Num, brightness_Num}

set bRGB to retRGBfromHSBnumList(hue_Num, saturation_Num, brightness_Num) of me

return {{rCol, gCol, bCol}, aHSB, bRGB}
–> {{102, 102, 255}, {239.996337890625, 60.000610351562, 100.0}, {102, 102, 255}}

–与えられたリスト数値のRGBデータをHSB値に変換して返す
–R:0〜255, G:0〜255, B:0〜255 
–H:0.0〜360.0, S:0.0〜100.0, B: 0.0〜100.0
on retHSBfromRGBnumList(rNum, gNum, bNum)
  
  
tell application "Adobe Photoshop CS6"
    set myLABColor to convert color {class:RGB color, red:rNum, green:gNum, blue:bNum} to HSB
    
    
set hue_Num to hue of myLABColor
    
set saturation_Num to saturation of myLABColor
    
set brightness_Num to brightness of myLABColor
    
  end tell
  
  
return {hue_Num, saturation_Num, brightness_Num}
  
end retHSBfromRGBnumList

–与えられたリスト数値のHSBデータをRGB値に変換して返す
–R:0〜255, G:0〜255, B:0〜255 
–H:0.0〜360.0, S:0.0〜100.0, B: 0.0〜100.0
on retRGBfromHSBnumList(hNum, sNum, bNum)
  
  
tell application "Adobe Photoshop CS6"
    set myRGBColor to convert color {class:HSB color, hue:hNum, saturation:sNum, brightness:bNum} to RGB
    
    
set redNum to red of myRGBColor
    
set greenNum to green of myRGBColor
    
set blueNum to blue of myRGBColor
  end tell
  
  
set redNum to round redNum rounding as taught in school –四捨五入
  
set greenNum to round greenNum rounding as taught in school –四捨五入
  
set blueNum to round blueNum rounding as taught in school –四捨五入
  
  
  
return {redNum, greenNum, blueNum}
  
end retRGBfromHSBnumList

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

2013/04/13 Photoshop CS6でRGB→LAB、LAB→RGB変換

Adobe Photoshop CS6を使って、RGBカラーの値とL*a*b*の値(CIELAB D50)を相互変換するAppleScriptです。

Photoshop CS3のときにはAppleScriptからL*a*b*の値の処理はできなかったのですが、CS6に移行してできるようになっていたので感心しました。

RGB値からHSBなりL*a*b*の値に変換してしまえば、明度を変更した色の値を求めて、RGBに再変換して返すといった処理が気軽にできるので助かります。

スクリプト名:Photoshop CS6でRGB→LAB、LAB→RGB変換
–色選択
set {rCol, gCol, bCol} to choose color

–16ビット値→8ビット値 変換
set rCol to rCol div 256
set gCol to gCol div 256
set bCol to bCol div 256

set aLAB to retLABfromRGBnumList(rCol, gCol, bCol) of me

copy aLAB to {elNum, aNum, bNum}

set bRGB to retRGBfromLABnumList(elNum, aNum, bNum) of me

return {{rCol, gCol, bCol}, aLAB, bRGB}

–与えられたリスト数値のRGBデータをLAB値に変換して返す
–R:0〜255, G:0〜255, B:0〜255 
–L*:0.0〜100.0, a*:-128.0〜127.0, b*: -128.0〜127.0
on retLABfromRGBnumList(rNum, gNum, bNum)
  
  
tell application “Adobe Photoshop CS6″
    set myLABColor to convert color {class:RGB color, red:rNum, green:gNum, blue:bNum} to Lab
    
    
set L_Num to value_L of myLABColor
    
set A_Num to value_a of myLABColor
    
set B_Num to value_b of myLABColor
    
  end tell
  
  
return {L_Num, A_Num, B_Num}
  
end retLABfromRGBnumList

–与えられたリスト数値のLABデータをRGB値に変換して返す
–R:0〜255, G:0〜255, B:0〜255 
–L*:0.0〜100.0, a*:-128.0〜127.0, b*: -128.0〜127.0
on retRGBfromLABnumList(elNum, aNum, bNum)
  
  
tell application “Adobe Photoshop CS6″
    set myRGBColor to convert color {class:Lab color, value_L:elNum, value_a:aNum, value_b:bNum} to RGB
    
    
set redNum to red of myRGBColor
    
set greenNum to green of myRGBColor
    
set blueNum to blue of myRGBColor
  end tell
  
  
set redNum to round redNum rounding as taught in school –四捨五入
  
set greenNum to round greenNum rounding as taught in school –四捨五入
  
set blueNum to round blueNum rounding as taught in school –四捨五入
  
  
  
return {redNum, greenNum, blueNum}
  
end retRGBfromLABnumList

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

2013/04/13 0〜255の8ビットの値から構成されるRGB値のリストの色をプレビューする

{r,g,b}のリストで表現したRGBデータのリストの色をchoose colorでプレビューするAppleScriptです。

色データの内容を視覚的に把握したいときに便利です。本ダイアログ表示中に[ESC]キーを押したり、キャンセルボタンをクリックすると終了してしまうのが難点ですが……

スクリプト名:0〜255の8ビットの値から構成されるRGB値のリストの色をプレビューする

set aRGB to {76, 40, 255}
set aRes to col8bitRGBPreview(aRGB) of me

set bRGB to {0, 0, 225}
set aRes to col8bitRGBPreview(bRGB) of me

–0〜255の8ビットの値から構成されるRGB値のリスト {r,g,b} の色をchoose colorでプレビューする
on col8bitRGBPreview(rgbColList)
  set aLen to length of rgbColList
  
  
if aLen is not equal to 3 then return false
  
  
set {r, g, b} to rgbColList
  
  
set asR to r * 256
  
set asG to g * 256
  
set asB to b * 256
  
  
set prevCol to {asR, asG, asB}
  
  
choose color default color prevCol
  
  
return true
  
end col8bitRGBPreview

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

2013/04/09 MacTech Magazine 03 2013にASOC関連記事掲載

iPadで読める電子版のMacTech Magazineアプリにて、最新刊のMacTech Magazine 03 2013が配信されました。アプリは無料で各号450円。3冊まとめるとお安くなるようですが、(セミナー開催などで)途中で休む月があるので、どーーーもまとめて払うのに不安をおぼえます。

そんなMacTech Magazineの最新号、AppleScriptObjCの記事が2本掲載されています。

img_0098.PNG

・Migrating AppleScript Studio Apps to AppleScriptObjC ( Cocoa-AppleScript )

AppleScript StudioからAppleScriptObjCに移行する方法を説明する記事。よくあるCurrency Converter(通貨レート変換計算プログラム)の作り方を解説。AppleScript Studioユーザー向けということで、より噛み砕いて説明したASOC入門記事にはなっているのですが、想定しているAppleScript Studioのユーザーレベルが低すぎのような気が……(ーー;; ニーズはあると思うんですけれど、一般に求められているものと違うような気がします。

・AppleScriptObjC Prints a Document

ASOCのプログラムで印刷機能を実装するサンプルの解説記事。個人的には、こちらのほうが参考になりました。

2013/04/08 手作りのノンブルが作ってあるPowerPoint書類に対して、座標位置(一番左側に寄せてある)を手がかりにフレームを取得してリナンバリング

真心のこもった「手作りのノンブル」が作ってあるPowerPoint書類に対して、座標位置からノンブルのテキストフレームを判別し、リナンバーを行うAppleScriptです。

久しぶりにPowerPointで作らなくてはならない書類(=Keynote書類では受け取ってもらえない用途)に追加修正を行っていたところ、各ページの下に付いていたページ番号が……

ppt1.png

普通、マスタースライドにページ番号(ノンブル)を配置しておけば、ページが増えようが減ろうが、ノンブル管理についてユーザーが関知する必要はないのですが……途中のバージョンから(なぜか)それが無視されて、各ページの下部に「手作りのノンブル」が配置されていることが判明。

しかも、そのPowerPointの書類はけっこうなページ数があったため、すべての「手作りノンブル」を削除してPowerPoint本来のノンブルを復活させるのもはばかられるところ。

そこで、「そんなたいした処理にはならないだろー」と踏んで、AppleScriptからリナンバーを行うことにしました。

……結論からいえば、けっこう入り組んだPowerPointのオブジェクト階層迷路を引き回されて、「たいした」作業にはなってしまったのですが、目的を果たすことはできました。

PowerPointはDTPソフトではないので、各オブジェクトにScript Labelを割り当てられるとかいうことはなくて、それぞれのオブジェクトの判別については相当な困難が伴うはずですが…………そこは、オブジェクトの座標を見て、X座標が0(プログラム上では念のため5以下)になっているものを「真心のこもった手作りノンブル用テキストフレーム」とみなして、処理しています。

PowerPointのScriptingは久しぶりだったので、「クラス名を取得して、あとで条件判断用に使おうとしたら、プログラム中にクラス名を直接記述できなかった」などの怪奇現象に直面して焦ってしまいました。

この手の(出来の悪い)アプリケーションのScriptingにおける挙動については、割と技術的なバッドノウハウ的な蓄積があり、クラス名を取得したら即座にas stringで文字列にして、文字列で判定を行うことで問題を回避しました。

あとで気付きましたが、このプログラムをちょこっと直せば、各ページに付いている「真心のこもった手作りのノンブル」を自動削除して、PowerPoint本来のマスタースライド上のノンブルを活かせそうです。

スクリプト名:手作りのノンブルが作ってあるPowerPoint書類に対して、座標位置(一番左側に寄せてある)を手がかりにフレームを取得してリナンバリング
–手作りのノンブルが作ってあるPowerPoint書類に対して、座標位置(一番左側に寄せてある)を手がかりにフレームを取得してリナンバリング

tell application “Microsoft PowerPoint”
  
  
tell active presentation –Document
    –スライドの枚数を数える
    
set sCount to count every slide
    
    
–スライド先頭から順次ループ
    
repeat with i from 1 to sCount
      
      
tell slide i –Page
        
        
set tList to {}
        
set s1List to every shape
        
repeat with ii in s1List
          set leftPos to left position of ii
          
if leftPos < 5 then
            set aClass to (class of ii) as string –テキストにして取得しないとclass名はまともに扱えない
            
if aClass = “shape textbox” then
              set the end of tList to ii
            end if
          end if
        end repeat
        
        
if tList is not equal to {} then
          set ttCount to count every item of tList
          
log ttCount
          
set aTF to text frame of contents of first item of tList
          
          
tell aTF
            set hsF to has text
            
            
–Text Frameにテキストが入っている場合のみ処理
            
if hsF = true then
              set aProp to properties
              
set aTRange to text range of aProp
              
              
set aCon to content of aTRange
              
if aCon begins with “−” and aCon ends with “−” then
                set aText to “− “ & (i as string) & ” −”
                
set content of aTRange to aText
              end if
            end if
            
          end tell
        end if
        
      end tell
    end repeat
    
  end tell
end tell

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

2013/04/06 開始日と終了日の間を、指定日数単位で切った{開始日,終了日}のリストの日付文字列リストを返す

開始日と終了日(サンプルでは当日の日付)の間を、指定日数単位(サンプルでは7日)で区切った、{開始日,終了日}のリストの日付文字列リストを返すAppleScriptです。

本ScriptはOS X 10.8特有のdateバグの影響は受けていません。

スクリプト名:開始日と終了日の間を、指定日数単位で切った{開始日,終了日}のリストの日付文字列リストを返す
set aDate to “2013/2/5″
set aDateObj to date aDate

set curDate to current date

set bList to makeFromToDateStrList(aDateObj, curDate, 7, “/”) of me

–> {{”2013/02/05″, “2013/02/11″}, {”2013/02/12″, “2013/02/18″}, {”2013/02/19″, “2013/02/25″}, {”2013/02/26″, “2013/03/04″}, {”2013/03/05″, “2013/03/11″}, {”2013/03/12″, “2013/03/18″}, {”2013/03/19″, “2013/03/25″}, {”2013/03/26″, “2013/04/01″}, {”2013/04/02″, “2013/04/08″}}

–開始日と終了日の間を、指定日数単位で切った{開始日,終了日}のリストの日付文字列リストを返す
on makeFromToDateStrList(fromDate, toDate, stepDateNum, aParseStr)
  
  
set aList to {}
  
  
repeat while fromDate < toDate
    set date1 to retDateStr(fromDate, aParseStr) of me
    
set date2 to retDateStr(fromDate + ((stepDateNum - 1) * days), aParseStr) of me
    
    
set the end of aList to {date1, date2}
    
set fromDate to fromDate + stepDateNum * days
  end repeat
  
  
return aList
  
end makeFromToDateStrList

–”YYYY-MM-DD” を返す
on retDateStr(aDate, aSep)
  
  
set aYear to year of aDate
  
set aMonth to month of aDate as number
  
set aDay to day of aDate
  
  
set yStr to retZeroPaddingText(aYear, 4) of me
  
set mStr to retZeroPaddingText(aMonth, 2) of me
  
set dStr to retZeroPaddingText(aDay, 2) of me
  
  
set resStr to yStr & aSep & mStr & aSep & dStr
  
  
return resStr
  
end retDateStr

–数値にゼロパディングしたテキストを返す
on retZeroPaddingText(aNum, aLen)
  
  
set tText to (“0000000000″ & aNum as text)
  
set tCount to length of tText
  
set resText to text (tCount - aLen + 1) thru tCount of tText
  
  
return resText
  
end retZeroPaddingText

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

2013/04/05 SafariでRadiko選局を行う 10.6.8+5.1.8版

SafariでRadikoの選局を行うAppleScriptのMac OS X 10.6.8+Safari 5.1.8向けに改修を行ったものです。

OS X 10.8上でSafari 6.0.3を相手にラジオ局選択をできるようにはなったのですが、肝心の自宅ラジオ録音用マシン(Mac mini)はMac OS X 10.6.8で動いているので、ターゲット機に合わせて書き換える必要が出てきました。

仕方なく、UI Browser(のお試し版)を10.6.8のマシンにインストールして、Safari上のWebコンテンツのUIを調べつつ、オブジェクト階層の書き換えを行いました。また、非力なCoreDuo 1.6GHzのマシンに合わせて待ち時間を修正しました。

ちなみに、OS X 10.7.5上ではSafari 6.0.3が動いておりOS X 10.8用のAppleScriptがそのまま動きます。

スクリプト名:SafariでRadiko選局を行う 10.6.8+5.1.8版
–Mac OS X 10.6.8+Safari 5.1.8

property waitSec : 10 –Safariのページローディングを待つ時間(秒)

–GUI Scriptingの確認
repeat 3 times
  tell application “System Events”
    set aRes to UI elements enabled
  end tell
  
  
if aRes = false then
    display dialog “GUI Scriptingをオンにしてください。” buttons {“OK”} default button 1
    
tell application “System Events”
      activate
      
set UI elements enabled to true
    end tell
  end if
end repeat
if aRes = false then return

set aList to getRadioStationList_1068() of me
–> {”TBSラジオ”, “文化放送”, “ニッポン放送”, “ラジオNIKKEI第1″, “ラジオNIKKEI第2″, “InterFM”, “TOKYO FM”, “J-WAVE”, “ラジオ日本”, “bayfm78″, “NACK5″, “FMヨコハマ”, “放送大学”}

tell current application
  activate
  
set aRes to choose from list aList
end tell

set aaRes to first item of aRes

selectRadioStation_1068(aaRes) of me –選局

–SafariでRadikoの選局を行う
on selectRadioStation_1068(aStation)
  activate application “Safari”
  
  
tell application “Safari”
    close every document
    
    
tell document 1
      tell current tab
        open location “http://radiko.jp”
      end tell
    end tell
  end tell
  
  
delay waitSec
  
  
tell application “System Events”
    tell process “Safari”
      tell list 1 of UI element 1 of scroll area 1 of group 1 of group 1 of group 3 of window 1
        set gList to every group
        
        
set uList to {}
        
        
repeat with i in gList
          set j to contents of i
          
tell j
            set a to first item of (every UI element)
            
set statName to title of a
            
            
if statName = aStation then
              tell UI element aStation
                click
                
exit repeat
              end tell
            end if
          end tell
        end repeat
        
      end tell
    end tell
  end tell
  
end selectRadioStation_1068

–SafariでRadikoのラジオ局一覧を取得する
on getRadioStationList_1068()
  activate application “Safari”
  
  
tell application “Safari”
    close every document
    
    
tell document 1
      tell current tab
        open location “http://radiko.jp”
      end tell
    end tell
  end tell
  
  
delay waitSec
  
  
tell application “System Events”
    tell process “Safari”
      tell list 1 of UI element 1 of scroll area 1 of group 1 of group 1 of group 3 of window 1
        set gList to every group
        
        
set uList to {}
        
        
repeat with i in gList
          tell i
            set a to first item of (every UI element)
            
set statName to title of a
            
set the end of uList to statName
          end tell
        end repeat
        
      end tell
    end tell
  end tell
  
  
return uList
  
end getRadioStationList_1068

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

2013/04/01 SafariでRadikoの選局を行う v2

SafariでRadiko.jpをオープンして現在の地域で選局可能なラジオ局の一覧を取得し、一覧から選択したあとに、指定したラジオ局をオープンするAppleScriptです。

radi1.png

GUI Scripting経由でSafariにアクセスしているので、システム環境設定からあらかじめ「アクセシビリティ」から「補助装置にアクセスできるようにする」にチェックを入れておくか、Script実行時にパスワードを入力すると設定を変更します。

自作のAppleScriptObjCのアプリケーション「radiRec」に組み込んで動作を確認しました。AppleScriptObjCのプロジェクトに入れても問題ありません。

radirec.png

OS X 10.8.3+Safari 6.0.3、場所は東京都内で動作確認してあります(他のエリアではチェックしていません)。

スクリプト名:SafariでRadikoの選局を行う v2
property waitSec : 5 –Safariのページローディングを待つ時間(秒)

–GUI Scriptingの確認
repeat 3 times
  tell application “System Events”
    set aRes to UI elements enabled
  end tell
  
  
if aRes = false then
    display dialog “GUI Scriptingをオンにしてください。” buttons {“OK”} default button 1
    
tell application “System Events”
      activate
      
set UI elements enabled to true
    end tell
  end if
end repeat
if aRes = false then return

set aList to getRadioStationList() of me
–> {”TBSラジオ”, “文化放送”, “ニッポン放送”, “ラジオNIKKEI第1″, “ラジオNIKKEI第2″, “InterFM”, “TOKYO FM”, “J-WAVE”, “ラジオ日本”, “bayfm78″, “NACK5″, “FMヨコハマ”, “放送大学”}

tell current application
  activate
  
set aRes to choose from list aList
end tell

set aaRes to first item of aRes

selectRadioStation(aaRes) of me –選曲

–SafariでRadikoの選局を行う
on selectRadioStation(aStation)
  activate application “Safari”
  
  
tell application “Safari”
    close every document
    
    
tell document 1
      tell current tab
        open location “http://radiko.jp”
      end tell
    end tell
  end tell
  
  
delay waitSec
  
  
tell application “System Events”
    tell process “Safari”
      tell list 1 of UI element 1 of scroll area 1 of group 1 of group 1 of group 2 of window 1
        set gList to every group
        
        
set uList to {}
        
        
repeat with i in gList
          tell i
            set a to first item of (every UI element)
            
set statName to title of a
            
set the end of uList to statName
            
if statName = aStation then
              
              
click a
              
            end if
          end tell
        end repeat
        
      end tell
    end tell
  end tell
  
end selectRadioStation

–SafariでRadikoのラジオ局一覧を取得する
on getRadioStationList()
  activate application “Safari”
  
  
tell application “Safari”
    close every document
    
    
tell document 1
      tell current tab
        open location “http://radiko.jp”
      end tell
    end tell
  end tell
  
  
delay waitSec
  
  
tell application “System Events”
    tell process “Safari”
      tell list 1 of UI element 1 of scroll area 1 of group 1 of group 1 of group 2 of window 1
        set gList to every group
        
        
set uList to {}
        
        
repeat with i in gList
          tell i
            set a to first item of (every UI element)
            
set statName to title of a
            
set the end of uList to statName
          end tell
        end repeat
        
      end tell
    end tell
  end tell
  
  
return uList
  
end getRadioStationList

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