Archive for 7月, 2009

2009/07/30 指定年の各月の開始日と終了日を算出する

指定年の各月の開始日と終了日を算出するAppleScriptです。

この手のカレンダー演算によく登場するgetMLenがまたもや登場。開始日は1日なので決め打ちで、終了日はgetMLenを用いて計算で算出。

指定期間内の祝日を取得するとか、指定期間内のiCalのイベントを取り出すといった場合、このように範囲をdateオブジェクトで用意しておく必要が出てきたりします。実につまらない機能のプログラムですが、こういうものを地道に揃えていくと、割とおっかない内容の処理ができるようになったりします。

スクリプト名:指定年の各月の開始日と終了日を算出する
set dList to {}
set aYear to 2010

repeat with i from 1 to 12
  set sDateStr to ((aYear as string) & / & i as string) & / & 1
  
set eDateStr to ((aYear as string) & / & i as string) & / & getMlen(aYear, i) of me as string
  
set the end of dList to {sDateStr, eDateStr}
end repeat

dList
> {{”2010/1/1″, “2010/1/31″}, {”2010/2/1″, “2010/2/28″}, {”2010/3/1″, “2010/3/31″}, {”2010/4/1″, “2010/4/30″}, {”2010/5/1″, “2010/5/31″}, {”2010/6/1″, “2010/6/30″}, {”2010/7/1″, “2010/7/31″}, {”2010/8/1″, “2010/8/31″}, {”2010/9/1″, “2010/9/30″}, {”2010/10/1″, “2010/10/31″}, {”2010/11/1″, “2010/11/30″}, {”2010/12/1″, “2010/12/31″}}

指定月の日数を返す
on getMlen(aYear, aMonth)
  set aYear to aYear as number
  
set aMonth to aMonth as number
  
  
set aDat to (aYear as text) & / & (aMonth as text) & /1
  
if aMonth is 12 then
    set eDat to ((aYear + 1) as text) & / & (1 as text) & /1
  else
    set eDat to ((aYear as text) & / & (aMonth + 1) as text) & /1
  end if
  
  
set eDat to date eDat
  
set eDat to eDat - 1
  
  
set mLen to day of eDat
  
return mLen
end getMlen

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

2009/07/28 月曜日はじまりのカレンダーで指定月が何週分あるか行数を数える

月曜日はじまりのカレンダーで、指定月が何週分あるか計算するAppleScriptです。

カレンダーは月によって何週あるかが変わってくるため、一定の週数よりも多い場合にはレイアウト時に例外処理を行わなくてはならない場合もあります。そういうケースに備えて作成したものです。

月曜日はじまりのカレンダーに対応できるように、曜日(weekday)のテーブルを介して変換を行っています。この調子でいけば、どの曜日ではじまるようにでも対応できるような変換テーブルを作っておいてもよさそうです。

スクリプト名:月曜日はじまりのカレンダーで指定月が何週分あるか行数を数える
set thisYear to 2010
set wList to {}

repeat with i from 1 to 12
  set wRes to detectWeekNumMondayStart(thisYear, i) of me
  
set the end of wList to wRes
end repeat

wList
> {5, 4, 5, 5, 6, 5, 5, 6, 5, 5, 5, 5}

月曜日はじまりのカレンダーで指定月が何週分あるか行数を数える
on detectWeekNumMondayStart(thisYear, thisMonth)
  set wConList to {7, 1, 2, 3, 4, 5, 6}
  
  
set mLen to getMlen(thisYear, thisMonth) of me
  
set sDate to ((thisYear as string) & / & thisMonth as string) & /1
  
set eDate to ((thisYear as string) & / & thisMonth as string) & / & mLen as string
  
set sDate to date sDate
  
set eDate to date eDate
  
set sWeekDay to contents of item (weekday of sDate as number) of wConList
  
set eWeekDay to contents of item (weekday of eDate as number) of wConList
  
  
set mPos to sWeekDay + mLen - 1
  
  
set mP1 to mPos div 7
  
set mp2 to mPos mod 7
  
  
if mp2 = 0 then
    set mpRes to mP1
  else
    set mpRes to mP1 + 1
  end if
  
  
return mpRes
  
end detectWeekNumMondayStart

指定月の日数を返す
on getMlen(aYear, aMonth)
  set aYear to aYear as number
  
set aMonth to aMonth as number
  
  
set aDat to (aYear as text) & / & (aMonth as text) & /1
  
if aMonth is 12 then
    set eDat to ((aYear + 1) as text) & / & (1 as text) & /1
  else
    set eDat to ((aYear as text) & / & (aMonth + 1) as text) & /1
  end if
  
  
set eDat to date eDat
  
set eDat to eDat - 1
  
  
set mLen to day of eDat
  
return mLen
end getMlen

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

2009/07/28 日曜日はじまりのカレンダーで指定月が何週分あるか行数を数える

日曜日はじまりのカレンダーで、指定月が何週分あるか計算するAppleScriptです。

カレンダーは月によって何週あるかが変わってくるため、一定の週数よりも多い場合にはレイアウト時に例外処理を行わなくてはならない場合もあります。そういうケースに備えて作成したものです。

スクリプト名:日曜日はじまりのカレンダーで指定月が何週分あるか行数を数える
set thisYear to 2010
set wList to {}

repeat with i from 1 to 12
  set wRes to detectWeekNum(thisYear, i) of me
  
set the end of wList to wRes
end repeat

wList
> {6, 5, 5, 5, 6, 5, 5, 5, 5, 6, 5, 5}

日曜日はじまりのカレンダーで指定月が何週分あるか行数を数える
on detectWeekNum(thisYear, thisMonth)
  set mLen to getMlen(thisYear, thisMonth) of me
  
set sDate to ((thisYear as string) & / & thisMonth as string) & /1
  
set eDate to ((thisYear as string) & / & thisMonth as string) & / & mLen as string
  
set sDate to date sDate
  
set eDate to date eDate
  
set sWeekDay to weekday of sDate as number
  
set eWeekDay to weekday of eDate as number
  
  
set mPos to sWeekDay + mLen - 1
  
  
set mP1 to mPos div 7
  
set mp2 to mPos mod 7
  
  
if mp2 = 0 then
    set mpRes to mP1
  else
    set mpRes to mP1 + 1
  end if
  
  
return mpRes
  
end detectWeekNum

指定月の日数を返す
on getMlen(aYear, aMonth)
  set aYear to aYear as number
  
set aMonth to aMonth as number
  
  
set aDat to (aYear as text) & / & (aMonth as text) & /1
  
if aMonth is 12 then
    set eDat to ((aYear + 1) as text) & / & (1 as text) & /1
  else
    set eDat to ((aYear as text) & / & (aMonth + 1) as text) & /1
  end if
  
  
set eDat to date eDat
  
set eDat to eDat - 1
  
  
set mLen to day of eDat
  
return mLen
end getMlen

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

2009/07/26 10進数数値をExcel 2004_2008的カラム表現にエンコード

Excel 2004/2008でセルの位置を指定する際、Excel v.Xまでの「R1C1形式」ではなく「A1形式」が採用されました。数値をこのA1形式に変換するためのAppleScriptサブルーチンです。

R1C1形式は非常に扱いが簡単で、これがそのまま使えればよかったのですが……(汗)

Excelで、縦軸を表すcellオブジェクトと、横軸を表すcolumnオブジェクトを使って、

  set a to formula of cell 3 of column 2 –セル「B3」にアクセス

といったR1C1形式に近い表記は可能ですが、範囲指定をする際にはA1形式が必要になってしまいます。

A1形式は、最初のアルファベット部分がカラム(列)を、数値部分がロー(行)を示しています。

このA1形式のカラム部分の計算を行うのが本サブルーチンです。ただし、1〜1,351までの範囲を対象としています。このA1形式のカラム部分は単なる26進数ではなく、少々トリッキーな計算(というか補正)が必要になってしまい、その計算で保証できる範囲が1,351ということです。

ex1.jpg

本気で作り込めば、もうちょっと大きな数値まで対象にできそうですが、実用上1,351まで変換することはなさそうです。Excel 2008ではカラムが16,384まで持てるようになってはいるものの、そんなに大きな表を扱うのであれば、いっそFileMaker Proなどのデータベースを用いたほうが楽に処理できることでしょう。

本ルーチンについても、最善の内容ではなく表現範囲を限定した上でのいわば「次善」の内容であり、他にもっとよいものがあれば使っていきたいところ。海外でいろいろ探しまわったものの、この処理については適切なものが見つからなかったので、仕方なく作成した次第です。

そもそも、Windows版ExcelでVisualBasicから呼び出すメソッドには10進数とA1形式の相互変換を行うものがあるので、それがMac OS X版に実装されていないことが問題の根源のような気もします。

スクリプト名:10進数数値をExcel 2004_2008的カラム表現にエンコード
set aRes to aNumToExcelColumn(502) of me
> “SH”

10進数数値をExcel 2004/2008的カラム表現にエンコードするサブルーチン
1〜1351までの間であれば正しいエンコーディング結果を返す
on aNumToExcelColumn(origNum)
  if origNum > 1351 then
    display dialog エラー:Excel 2004/2008的カラム表現(A1形式)への変換ルーチンにおいて、想定範囲外(1351以上)のパラメータが指定されました buttons {”OK“} default button 1
    
return “”
  end if
  
  
set upperDigitEncTable 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“, A“}
  
set lowerDigitEncTable 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“, A“}
  
  
set oNum to origNum
  
set nTh to 26
  
set stringLength to 4
  
  
数字が1桁の場合の対応
  
if origNum < 27 then
    set aRes to (item origNum of upperDigitEncTable) as string
    
return aRes
  end if
  
  
  
if origNum > 702 then
    3桁になる場合
    
set upupNum to oNum div 676 整数除算–上の上の桁
    
set oNum to oNum - (upupNum * 676)
    
set upNum to oNum div 26 整数除算–上の桁
    
set lowNum to oNum mod 26 - 1 余剰計算–下の桁
    
    
log {origNum, upupNum, upNum, lowNum}
    
    
超つじつま合わせルーチン【強引】
    
if lowNum = -1 then
      set upNum to upNum - 1
      
set lowNum to 25
    end if
    
    
set upupChar to (item upupNum of upperDigitEncTable) as string
    
set upChar to (item upNum of upperDigitEncTable) as string
    
set lowChar to (item (lowNum + 1) of lowerDigitEncTable) as string
    
set resText to upupChar & upChar & lowChar
    
  else
    2桁の場合
    
set upNum to oNum div 26 整数除算–上の桁
    
set lowNum to oNum mod 26 - 1 余剰計算–下の桁
    
    
    
超つじつま合わせルーチン【強引】
    
if lowNum = -1 then
      set upNum to upNum - 1
      
set lowNum to 25
    end if
    
    
set upChar to (item upNum of upperDigitEncTable) as string
    
set lowChar to (item (lowNum + 1) of lowerDigitEncTable) as string
    
set resText to upChar & lowChar
    
  end if
  
  
return resText
  
end aNumToExcelColumn

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

2009/07/22 ファイル名文字列から拡張子のみ取得する

ファイル名文字列から拡張子のみ取得するAppleScriptです。

URLからファイル名部分を求めたのちに、ファイル名の文字列から拡張子部分だけを取り出すために作成しました。

もっと具体的にいえば、URL Access Scriptingで指定URLのファイルをダウンロードする時に、URLからファイル名を求め……32文字を超えるようであれば、ファイル名を縮めるために、あらかじめ拡張子を求めておいて、ファイル名を短くしたあとに拡張子を付加する……という処理のために作成しました。

割と、どうということはない処理内容ですが、同じ処理を2度書くのはかったるいのでサブルーチンにしておいた次第です。

スクリプト名:ファイル名文字列から拡張子のみ取得する
set fileNameStr to aslakjlasdjlasaaaaaaaaaaaaaaa.jlasldas_das_001.jpg
set aRes to retExtNameFromFilenameStr(fileNameStr) of me

ファイル名文字列から拡張子のみ取得する
on retExtNameFromFilenameStr(fileNameStr)
  set fLen to length of fileNameStr
  
set revText to (reverse of (characters of fileNameStr)) as string 逆順テキストを作成
  
set anOffset to offset of . in revText
  
set fRes to text (fLen - anOffset + 1) thru -1 of fileNameStr
  
return fRes
end retExtNameFromFilenameStr

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

2009/07/22 Numbersで選択中の範囲を連続する数値で埋める

Numbers上で選択した範囲を連続する数値で埋めるAppleScriptです。

Excelでものすごくよく使う「編集」>「フィル」>「連続データの作成…」をNumbers上に手っ取り早く実装してみました。Script Menuに入れて使ってみてください。

excel_seqno.jpg

Numbersのシート上で範囲を指定して……
num1.jpg

このAppleScriptを実行すると、開始値を入力するダイアログが表示されるので、好きな値を入力して[Return]キーを押すと……
num2.jpg

連続する数値が入力されます。
num3.jpg

ステップ値を変更したり、複数列を選択された場合への対処を行ったり、直前のセルの値を取得して初期値のデフォルト値にあてたりするなど、いろいろカスタマイズしてみると面白いと思われます。

スクリプト名:Numbersで選択中の範囲を連続する数値で埋める
set sNum to text returned of (display dialog Input start Num default answer “”)
tell application Numbers
  tell document 1
    tell sheet 1
      tell table 1
        set mySelectedRanges to value of every cell of selection range
        
set cellList to cell of selection range
        
set iCount to 0
        
set newList to {}
        
repeat with i in mySelectedRanges
          set the end of newList to sNum + iCount
          
set iCount to iCount + 1
        end repeat
        
        
repeat with i from 1 to (length of cellList)
          tell item i of cellList
            set value to item i of newList
          end tell
        end repeat
      end tell
    end tell
  end tell
end tell

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

2009/07/22 1年間の各週の開始日と終了日を求める(月曜日はじまりカレンダー)

1年間の各週の開始日と終了日を求めるAppleScriptです。ただし、通常の日曜日はじまりのカレンダーではなく月曜日はじまりのカレンダーを対象としています。

スクリプト名:1年間の各週の開始日と終了日を求める(月曜日はじまりカレンダー)
set wList to “”
set sDate to 2010/1/1
set sDate to date sDate
set sDateW to weekday of sDate as number
> 6

起点となる月曜日の原点日を決める(元日からのオフセット値)
set wOffset to 0
if sDateW < 2 then
  月曜日より小さい場合
  
set wOffset to 2 - sDateW
else if sDateW = 2 then
  月曜日の場合
  
set wOffset to 0
else
  それ以外
  
set wOffset to 7 - sDateW + 2
end if

最初の月曜日を求める
set sDateM to sDate + (wOffset * days)

メインループ
repeat with i from 0 to 52
  set fMonday to sDateM + (i * 7 * days)
  
set fSunday to sDateM + ((6 + (i * 7)) * days)
  
  
set wList to wList & date string of fMonday & tab & date string of fSunday & return
end repeat
wList

>

(*
“2010年1月4日月曜日  2010年1月10日日曜日
2010年1月11日月曜日  2010年1月17日日曜日
2010年1月18日月曜日  2010年1月24日日曜日
2010年1月25日月曜日  2010年1月31日日曜日
2010年2月1日月曜日  2010年2月7日日曜日
2010年2月8日月曜日  2010年2月14日日曜日
2010年2月15日月曜日  2010年2月21日日曜日
2010年2月22日月曜日  2010年2月28日日曜日
2010年3月1日月曜日  2010年3月7日日曜日
2010年3月8日月曜日  2010年3月14日日曜日
2010年3月15日月曜日  2010年3月21日日曜日
2010年3月22日月曜日  2010年3月28日日曜日
2010年3月29日月曜日  2010年4月4日日曜日
2010年4月5日月曜日  2010年4月11日日曜日
2010年4月12日月曜日  2010年4月18日日曜日
2010年4月19日月曜日  2010年4月25日日曜日
2010年4月26日月曜日  2010年5月2日日曜日
2010年5月3日月曜日  2010年5月9日日曜日
2010年5月10日月曜日  2010年5月16日日曜日
2010年5月17日月曜日  2010年5月23日日曜日
2010年5月24日月曜日  2010年5月30日日曜日
2010年5月31日月曜日  2010年6月6日日曜日
2010年6月7日月曜日  2010年6月13日日曜日
2010年6月14日月曜日  2010年6月20日日曜日
2010年6月21日月曜日  2010年6月27日日曜日
2010年6月28日月曜日  2010年7月4日日曜日
2010年7月5日月曜日  2010年7月11日日曜日
2010年7月12日月曜日  2010年7月18日日曜日
2010年7月19日月曜日  2010年7月25日日曜日
2010年7月26日月曜日  2010年8月1日日曜日
2010年8月2日月曜日  2010年8月8日日曜日
2010年8月9日月曜日  2010年8月15日日曜日
2010年8月16日月曜日  2010年8月22日日曜日
2010年8月23日月曜日  2010年8月29日日曜日
2010年8月30日月曜日  2010年9月5日日曜日
2010年9月6日月曜日  2010年9月12日日曜日
2010年9月13日月曜日  2010年9月19日日曜日
2010年9月20日月曜日  2010年9月26日日曜日
2010年9月27日月曜日  2010年10月3日日曜日
2010年10月4日月曜日  2010年10月10日日曜日
2010年10月11日月曜日  2010年10月17日日曜日
2010年10月18日月曜日  2010年10月24日日曜日
2010年10月25日月曜日  2010年10月31日日曜日
2010年11月1日月曜日  2010年11月7日日曜日
2010年11月8日月曜日  2010年11月14日日曜日
2010年11月15日月曜日  2010年11月21日日曜日
2010年11月22日月曜日  2010年11月28日日曜日
2010年11月29日月曜日  2010年12月5日日曜日
2010年12月6日月曜日  2010年12月12日日曜日
2010年12月13日月曜日  2010年12月19日日曜日
2010年12月20日月曜日  2010年12月26日日曜日
2010年12月27日月曜日  2011年1月2日日曜日
2011年1月3日月曜日  2011年1月9日日曜日

*)

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

2009/07/22 指定月のうち、日曜日に該当するものを日付だけ返す

指定月のうち、日曜日に該当する日付だけを数値のリストで返すAppleScriptです。

最初はどう書いたものかと途方に暮れていましたが、書き出したらそれほどたいした長さにはなりませんでした。

1か月の長さを求めて、ループで1か月分のdateオブジェクトを生成し、曜日を確認して日曜日に該当したら出力用リストに追加……という処理を行うだけです。

スクリプト名:指定月のうち、日曜日に該当するものを日付だけ返す
set aList to retSundayDateNum(2009, 7) of me
> {5, 12, 19, 26}

指定月のうち、日曜日に該当するものを日付だけ返す
on retSundayDateNum(aYear, aMonth)
  set myMonthLen to getMlen(aYear, aMonth) of me
  
set sundayList to {}
  
repeat with i from 1 to myMonthLen
    set aDateStr to (((aYear as string) & / & aMonth as string) & / & i as string)
    
set aDate to date aDateStr
    
if (weekday of aDate as number) = 1 then 日曜日
      set the end of sundayList to i
    end if
  end repeat
  
  
return sundayList
end retSundayDateNum

指定年の指定月の日数を求める
on getMlen(aYear, aMonth)
  set aYear to aYear as number
  
set aMonth to aMonth as number
  
  
set aDat to (aYear as text) & / & (aMonth as text) & /1
  
if aMonth is 12 then
    set eDat to ((aYear + 1) as text) & / & (1 as text) & /1
  else
    set eDat to ((aYear as text) & / & (aMonth + 1) as text) & /1
  end if
  
  
set eDat to date eDat
  
set eDat to eDat - 1
  
  
set mLen to day of eDat
  
return mLen
end getMlen

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

2009/07/22 もんのすごいざっくりな元号計算ルーチン

西暦から元号名および年を算出するAppleScriptです。

ほぼ、西暦から平成に変換することだけを目的として作ったので、もう……目を覆わんばかりの雑なサブルーチンです。西暦→和暦の変換ルーチンが見つからなかったので、ひらすらやっつけで書いたものですが……納得できません。

本来、元号は1年の途中で切り替わるものなので……日付まで考慮して計算すべきものであり、そのあたりに不満が残ります。

スクリプト名:もんのすごいざっくりな元号計算ルーチン
set gRes to retGngoAndYear(2010) of me
log gRes
>   (*aGengo:平成, aYear:22*)

set gengoText to aGengo of gRes
set jYearNum to aYear of gRes

もんのすごいざっくりな元号計算ルーチン
作るのがダルすぎる、、、、
on retGngoAndYear(aYear)
  set gengoText to “”
  
if aYear > 1989 then
    set jYear to aYear - 1989 + 1
    
set gengoText to 平成
    
  else if aYear > 1926 then
    set jYear to aYear - 1926 + 1
    
set gengoText to 昭和
    
  else if aYear > 1912 then
    set jYear to aYear - 1912 + 1
    
set gengoText to 大正
    
  else if aYear > 1868 then
    set jYear to aYear - 1868 + 1
    
set gengoText to 明治
  end if
  
  
return {aGengo:gengoText, aYear:jYear}
end retGngoAndYear

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

2009/07/22 国民の祝日を求め__指定期間に該当するものを返す

指定期間内の国民の祝日および振替休日をリストで返すAppleScriptです。

あまりに巨大化したのと、どこにでも登場するようなサブルーチンの塊だったりするので、他のサブルーチンと衝突しないようにscript文で論理分割してみました。script文で囲まれた範囲は「別のScript」として扱われるため、サブルーチン名などで他と重複するものがあっても、「別のScript上にある別のサブルーチン」として扱われるため、名前の衝突を回避することができます。

呼び出すには、

set hList to retHolidaysWithinDates(sDate, eDate) of calendarKit

のようにof meではなくof Script名となります。さらに、この呼び出し部分がいずれかのサブルーチン内にある場合には、

set hList to retHolidaysWithinDates(sDate, eDate) of calendarKit of me

のようになります。
(more…)

2009/07/21 Microsoft Office 2008 for Mac Service Pack 2 (12.2.0)が公開

Microsoft Office 2008 for Mac Service Pack 2 (12.2.0)が公開されました。AppleScript用語辞書の変更点はとくにありません。

また、新たに追加されたMicrosoft Document ConnectionはAppleScript非対応アプリケーションです。

2009/07/20 Google Chrome BetaがAppleScriptに非対応

GoogleのWebkitベースのWebブラウザ「Google Chrome」のMac OS X版をダウンロードして評価してみました。

http://www.google.com/chrome/intl/en/eula_dev.html?dl=mac

chrome1.jpg

この段階のバージョンではAppleScript用語辞書は実装されていないことが確認されました。GoogleのアプリケーションでGoogle EarthにAS用語辞書が実装されていますが、その内容は実用的とは言えないもので……この方面でChromeに過大な期待はしないほうがよさそうです。

また、Google Chromeの現在のバージョンでは、本Blogに掲載しているスクリプトエディタへのコンテンツ転送リンクが効きません。まだ正式リリースになっていないものですが、この仕様をGoogleが認識しているかどうかという点には疑問が残ります。また、修正依頼を出しても通るとも思えません。

2009/07/20 AppleScriptで開発を行うユーザーアカウントにATOKは禁物

日本語入力インプットメソッド「ATOK」の新版が登場していますが、AppleScriptで開発やシステムの運用を行うユーザーアカウントにATOKを入れないことをおすすめします。

これは、ATOKがキー入力のシステムに干渉を起こし、AppleScriptのGUI Scripting系コマンド……さらに具体的にいえば「keystroke」コマンドの実行を阻害するためです。

keystrokeコマンドを使わずにプログラムを書くのであれば問題はないのですが、このような点に問題が出るため、AppleScriptでプログラムを書いている環境にはATOKをインストールしないことを、重ねて強く推奨します。

2009/07/20 Twitterifficで選択中の発言の時間をGrowlで表示。アイコン付きで v3

Twitterrifficで選択中の発言が行われた時間をGrowlでアイコン付き表示するAppleScriptの改良版です。

URL Access Scriptingに指定するURLのうちファイル名に該当する部分の長さが32文字以上だと、勝手にダウンロード時にファイル名を丸められてしまう、という問題に対処するため、28文字でファイル名チェックを行い、短く付け替えています。

ちょうど、坂本龍一教授をFollowして、たまたま発言を見つけたので時刻を調べてみたらエラーに遭遇。ファイル名を調べてみたら37文字で、テンポラリフォルダに入っていた画像ファイルがすべて途中で丸められていることが判明。URL Access Scriptingの32文字制限に気付いて、対策を施したものです。

ダウンロード後に画像が真っ白になっているケースが見られたので、syncコマンドを実行してキャッシュの内容をHDDにシンクロさせています。

(more…)

2009/07/20 URL Access Scriptingにファイル名の32文字制限が

AppleScriptでインターネットからダウンロードを行う際に用いる「URL Access Scripting」に、ファイル名の32文字制限があることに気付きました。US Appleのメーリングリストの過去ログをあさってみても、「何かがあるらしい」とまでは2001年ごろに話題にはなっていたものの、具体的な症状まで明らかになることはありませんでした(「気のせいではないか?」といった論調)。

URLの長さについては、32文字以上を許容しますし、URLの後に&でパラメータを付けた場合にも文字列長の制限は(AppleScript的には)とくにないのですが(フォームの側のリクエスト長の制限はまた別として)、URLの中に含まれるファイル名の部分が32文字以上だと途中で切られてしまうようです。

32文字といえば、Classic Mac OSのファイル名の長さの制限値であり、その時代にはたしかにそうした制限に意味はあったのでしょうが、Mac OS Xの時代までその制限がある必要はありません。

その制限が、Mac OS X 10.5の時代まで引き継がれてきたこと自体に驚きを禁じ得ません。

2009/07/20 Twitterifficで選択中の発言の時間をGrowlで表示。アイコン付きで v2

Twitterrifficからアイコンを取得して、ダウンロードを行おうとすると弾かれるケースが見られたので、とりあえず「すでにダウンロードしたアイコンがあれば使用する」ように処理を変更したバージョンです。

アイコンのダウンロードが行えない時に、TwitterアカウントのURLを個別にAppleScriptで取得して、そのままSafariで表示すると問題ないようなので、案外User Agent名称のチェックをサーバー側で行っているのかもしれません。

URL Access ScriptingにはUser Agent名称を詐称する機能はないため、そのための対策を行うのであればシェルからcurlコマンドを呼び出す必要が出てくることでしょう。

もう少し、エラーが発生する状況を観察してみることとします。

(more…)

2009/07/20 Twitterrifficで選択中の発言の時間をGrowlで表示。アイコン付きで

Twitterrifficで選択中の発言がいつ行われたかを確認するために、発言の時間をGrowlで表示するAppleScriptです。

twitter2.jpg

Twitterrifficの画面上では発言時刻が表示されないので、正確な時刻が知りたいと考えて作り始めたものですが……その時間があればWebブラウザで確認できたような……(汗)

一度こうしてAppleScriptを作ってしまえば、次回からはScript Menuから呼び出すだけになるので、まあ……無意味ではなかったのでしょう。

本Scriptでは、指定画像でGrowlの表示を行いたかったので、Twitterrificから取得した画像のURLから画像をダウンロードし、それを指定してメッセージを表示させてみました。

Twitterriffic側のselectionから画像のURLを取得しようとした時に、画像を指定していないアカウントの場合にはmissing valueが返ってくるようになっているのですが、selectionからURLを取得すると、missing valueが返ってくるのではなく変数への代入そのものが実行されなかったため、一度selectionのpropertiesをまるごと変数に代入し、そこからURLを取得して判定するようにしてみました。

(more…)

2009/07/17 指定年月日の、元日からの経過日数と年内の残り日数を求める

指定日付の、元日からの経過日数と年内の残り日数を求めるサブルーチンです。

スクリプト名:指定年月日の、元日からの経過日数と年内の残り日数を求める
set aRes to getElapsedAndRestDate(2009, 8, 8) of me
> {elapsed:220, rests:145}

指定年月日の、元日からの経過日数と年内の残り日数を求める
on getElapsedAndRestDate(aYear, aMonth, aDate)
  
  
set firstDate to date ((aYear as string) & /1/1“)
  
set thisDate to date (((aYear as string) & / & aMonth as string) & / & aDate as string)
  
set lastDate to date ((aYear as string) & /12/31“)
  
  
set elapsedDays to ((thisDate - firstDate) / days + 1) as integer
  
set restDays to ((lastDate - thisDate) / days) as integer
  
  
return {elapsed:elapsedDays, rests:restDays}
  
end getElapsedAndRestDate

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

2009/07/17 指定年月の祝日の日を数値のリストで返す

指定の年・月に発生する祝日と振替休日の「日」を数値のリストで返すサブルーチンです。

「国民の祝日を求める v4」などの超ヘビー級のAppleScriptサブルーチンではなく、単に指定月内の祝日&振替休日を求めます。

InDesignの表オブジェクトを用いてカレンダーを作成し、対象月の祝日の色を赤く変更するような処理を書いていて、ざっくりと軽い処理さえできればよいと考えて作成したものです。

ちなみに、本ルーチンでも元日の振替休日を許容するようになっています。

(more…)

2009/07/17 国民の祝日を求める v4

2009/07/17 リストから指定内容に該当する要素を削除

リストから、指定内容に該当する要素を削除するAppleScriptです。

カレンダー関連の処理をAppleScriptで書いていて……振替休日が他の祝日にぶつかり、この振替休日の順次繰り越し処理でうしろに回したあと、もともとあった最初の振替休日のデータを削除すべく作成したものです。

本当はもっと短く書けるはずなのですが、リストからの複数要素一括指定削除ルーチンなどという、本来の用途からすると過剰に高機能なサブルーチンを引っ張り出してきたためにちょっと長くなってしまっています。

(more…)

2009/07/15 指定月の第x指定曜日に該当する日付を求める(曜日数値指定対応)

よく使っているカレンダー計算ルーチンの仕様が気に入らなかったので書き換えてみました。

指定の年/月において、第x曜日に該当する日付を求めるAppleScriptのサブルーチンです。以前は、「日曜日」などの日本語にローカライズされた曜日名称を指定する仕様にしてあったのですが、日本語以外の言語環境で使うことを目的として、これを数値で指定するようにしたものです。

weekday of (current date) as numberとすれば、日曜日は1、月曜日が2……そして土曜日では7が返ってきます。この曜日番号を指定することで、日本語ローカライズされた曜日名を指定しなくて済みます。

本来、祝祭日などの休日情報についてはOS側が提供すべき情報だと思っていますが、そうはいってもOS側が提供してくれない(厳密にいえば、iCalのカレンダーで休日情報が配布されていますが)ので、計算する必要があり……世界各地の休日情報を反映させたカレンダー計算を行う場合には、このようなサブルーチンが必要になります(そういうニーズがあるかどうかは分りませんが)。

スクリプト名:指定月の第x指定曜日に該当する日付を求める(mmdd形式)
set aYear to 2009

曜日の数値指定: weekday of (current date) as number –日曜日=1、月曜日=2、土曜日=7
get_specifiedDay(aYear, 7, 4, 2) of me 2009年7月の第2水曜日の日付を求める
> “7/8″

指定月の第x指定曜日に該当する日付を求める(mm/dd形式)
 曜日の指定を数値(weekday of (current date) as number)で行えるようにした。
 曜日を「日曜日」などの日本語ローカライズド文字列で指定するのをやめた
on get_specifiedDay(aYear, aMonth, Youbi, orderNum)
  set Youbi to Youbi as number
  
set sDat to date ((aYear & / & aMonth & /1“) as text)
  
set eDat to getMlen(aYear, aMonth)
  
  
set countNum to 0
  
  
repeat with i from 1 to eDat
    set aCal to date ((aYear & / & aMonth & / & (i as text)) as text)
    
set aWeekDayNum to weekday of aCal as number
    
if Youbi = aWeekDayNum then
      set countNum to countNum + 1
      
if countNum is orderNum then
        set aCalText to (aMonth & / & i as text)
        
return aCalText
      end if
    end if
  end repeat
end get_specifiedDay

on getMlen(aYear, aMonth)
  set aYear to aYear as number
  
set aMonth to aMonth as number
  
  
set aDat to (aYear as text) & / & (aMonth as text) & /1
  
if aMonth is 12 then
    set eDat to ((aYear + 1) as text) & / & (1 as text) & /1
  else
    set eDat to ((aYear as text) & / & (aMonth + 1) as text) & /1
  end if
  
  
set eDat to date eDat
  
set eDat to eDat - 1
  
  
set mLen to day of eDat
  
return mLen
end getMlen

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

2009/07/12 XcodeでクリーニングしてビルドしてZip圧縮

Xcode 3.1.3で、最前面のXcodeプロジェクトをクリーニングしてビルドし、作成したバイナリを指定ファイル名にZip圧縮します。

このScriptでZip圧縮したあとにメールに添付して送信するなり、FTPサーバーにアップロードするなり、いろいろやってみてもよいでしょう。

ただ、ビルドする対象のプロジェクトは、アプリケーションを生成するものだけではないため、そのあたりプロジェクトの種類(プラグイン、Automator Action、ドライバなど)を取得できるようにXcode側がAppleScriptに情報を渡してくれるようになっているとよいのですが、現状ではそうした配慮はありません。

スクリプト名:XcodeでクリーニングしてビルドしてZip圧縮
tell application "Xcode"
  tell project 1
    set bList to name of every build configuration
    
set rBCon to first item of (every build configuration whose name is "Release")
    
    
set cRes to clean with removing precompiled headers
    
> "クリーニングに成功しました"
    
    
set bRes to build using rBCon
    
> "ビルドは問題なく完了しました (1 個の警告)"
    
    
set binPath to product directory
  end tell
end tell

set binPathAlias to POSIX file binPath

tell application "Finder"
  tell folder binPathAlias
    set appFile to (every file whose name ends with ".app") as alias list
  end tell
end tell

set anApp to contents of first item of appFile
set zipAlias to compressFileByZip(anApp, "appArch.zip") of me
> alias "Cherry:Users:maro:Documents:ぴよまるソフトウェア:高速富士山miniプロジェクト:hsmtfj_mini:v3:build:Release:hsmtfj mini.app.zip"

ファイルをZipで圧縮して指定名称にリネーム
on compressFileByZip(aFile, newName)
  set apPath to POSIX path of aFile
  
set folF to false
  
if apPath ends with "/" then
    set apPath to text 1 thru -2 of apPath
    
set folF to true
  end if
  
  
set source to quoted form of apPath a folder
  
set dest to quoted form of (apPath & ".zip")
  
do shell script "ditto -ck " & source & " " & dest
  
  
set apPathStr to aFile as string
  
if folF = true then
    set apPathStr to text 1 thru -2 of apPathStr
  end if
  
set apPathZip to apPathStr & ".zip" as alias
  
  
tell application "Finder"
    set name of apPathZip to newName
  end tell
  
  
return apPathZip
  
end compressFileByZip

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

2009/07/05 UnicodeCheckerでUTF-8の文字コードを得る

Unicodeの文字情報を調べるアプリケーション、UnicodeCheckerがScriptableになっており、AppleScript内部ネイティブのUTF-16のコードをUTF-8のコードに変換できるようです。

GUI側からちょこっといじくって「それほど使えない」と判断していたのですが、AppleScriptの命令を眺めていると、かなり使える印象を受けます。AppleScriptから呼び出すのが正しい使い方なのではないかと思えてしまうほどです。

uni1.jpg

ことえりの文字パレットを表示。UTF-16、UTF-8など異なる文字コードの情報を調べられる。

uni2.jpg

UnicodeCheckerによる表示。さらに詳細な情報を調べられる。

スクリプト名:UnicodeCheckerでUTF-8の文字コードを得る
tell application UnicodeChecker
  get escaped representation of (deXHTMLized representation of “)
  
> “%E3%81%82″
end tell

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