Created
February 26, 2009 00:11
-
-
Save zarigani/70546 to your computer and use it in GitHub Desktop.
AppleScript's Library & Script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* | |
GUIライブラリ | |
ロード方法の例(このライブラリをユーザースクリプトフォルダに"_gui.scpt"で保存した場合) | |
property GUI : load script file ((path to scripts folder as text) & "_gui.scpt") | |
あるいは動的に... | |
set GUI to load script file ((path to scripts folder as text) & "_gui.scpt") | |
開発&テスト環境 | |
MacBook OSX 10.5.6 | |
AppleScript 2.0.1 | |
Script Editor 2.2.1 (100.1) | |
*) | |
--初期化処理(Quicksilverからの起動なら、ひと呼吸置いて実行する) | |
on init() | |
if is_from_quicksilver() then | |
delay 0.2 | |
end if | |
end init | |
--GUIスクリプティングが無効なら、有効にすることを勧めるメッセージを出力する | |
on check() | |
tell application "System Events" | |
if UI elements enabled is false then | |
tell application "System Preferences" | |
activate | |
set current pane to pane "com.apple.preference.universalaccess" | |
set msg to "GUIスクリプティングが利用可能になっていません。\n\"補助装置にアクセスできるようにする\" にチェックを入れて続けますか?" | |
--display dialog msg buttons {"OK"} default button "OK" with icon note --giving up after 10 | |
display dialog msg buttons {"キャンセル", "チェックを入れて続ける"} with icon note | |
end tell | |
--error "中断しました。" | |
set UI elements enabled to true | |
delay 1 | |
tell application "System Preferences" to quit | |
delay 1 | |
end if | |
end tell | |
end check | |
--click_menu(app_name, menu_path) | |
--メニュー操作をシンプルに実行する | |
--app_nameは、操作対象のアプリケーション名 | |
--app_nameを""にすると、実行時にアクティブなアプリケーションに対する操作となる | |
--menu_pathは、テキストまたはリスト | |
-- click_menu("", "編集/検索/検索...") --OK | |
-- click_menu("Script Editor", {"編集", "検索", "検索..."}) --OK | |
-- click_menu("Script Editor", "編集", "検索", "検索...")--NG(リストでないので、編集をクリックする操作になってしまう) | |
--…または...の種類に注意 | |
-- click_menu("Script Editor", "Apple/システム環境設定…") --全角記号1文字 | |
-- click_menu("Script Editor", "スクリプトエディタ/環境設定...") --半角ドット3文字 | |
--小さいカナ文字に注意(×ウィンドウ ○ウインドウ) | |
--アップルメニューの場合はpath_menuに"Apple"を指定する | |
-- click_menu("", "Apple/この Mac について") | |
--アイテム番号による指定も可能 | |
--アイテム番号では区切り線も1と数える | |
--アイテム番号とアイテム名称の混在可能 | |
-- click_menu("Script Editor", "スクリプトエディタ/サービス/テキストエディット/選択部分を含む新しいウインドウを開く") | |
-- click_menu("Script Editor", "2/5/32/2") --=="スクリプトエディタ/サービス/テキストエディット/選択部分を含む新しいウインドウを開く" | |
-- click_menu("", "2/環境設定...") --"スクリプトエディタ/環境設定..." | |
--アイコンメニューは、メニューバーのアイテム番号の選択とキー操作で行う | |
--アイコンメニューのapp_nameは"SystemUIServer" | |
--"SystemUIServer"以外のアイコンメニューを操作する方法は、現状分からない... | |
--例:ログインウィンドウを表示する(ログインユーザーが1人だけの場合) | |
(* | |
click_menu("SystemUIServer", "16") | |
shortcut("↓") | |
shortcut("↓") | |
shortcut("space") | |
*) | |
on click_menu(app_name, menu_path) | |
if menu_path is "" then | |
error "menu_path が入力されていません。" | |
end if | |
if app_name is "" then | |
set app_name to frontmost_app() | |
end if | |
set mp to split(menu_path, "/") | |
tell application "System Events" | |
tell process app_name | |
if "AppleScript Runner" is in my every_process() or ¬ | |
frontmost is false then | |
set frontmost to true | |
end if | |
if mp's length = 1 then | |
menu bar 1's (menu bar item (my number_from(mp's item 1))) | |
else | |
--menu bar 1's menu bar item (mp's item 1)'s menu (mp's item 1) | |
menu bar 1's (menu bar item (my number_from(mp's item 1)))'s menu 1 | |
repeat with i from 2 to mp's length | |
if i < mp's length then | |
--result's menu item (mp's item i)'s menu (mp's item i) | |
result's (menu item (my number_from(mp's item i)))'s menu 1 | |
else | |
result's (menu item (my number_from(mp's item i))) | |
end if | |
end repeat | |
end if | |
click result --click:クリックする/pick:選択する--ほぼ同等だが、アイコンメニューにはclickが必須 | |
delay 0.1 --連続してメニューを操作する時、ひと呼吸必要 | |
end tell | |
end tell | |
end click_menu | |
--shortcut(app_name, key_text) | |
--キーボードショートカット操作をシンプルに実行する | |
--引数のkey_textには、ハイフンで区切った文字列、もしくはリストで指定する | |
-- shortcut("", "command-option-L") | |
-- shortcut("", {"command", "option", "L"}) | |
--文字列やリストの最後は必ず、一般キーかキーコードにする必要あり | |
--一般キーとは、command, option, control, shift, fn以外のキー | |
--キーコードは3桁の数字で指定する | |
-- shortcut("", "003") --f | |
-- shortcut("", "3") --3 | |
--fnキーはキー操作文字列には利用できない | |
--ファンクションキー等は、キーコードで指定する | |
-- f1:122 f2:120 f3:99 f4:118 f5:96 f6:97 f7:98 f8:100 f9:101 f10:109 f11:103 f12:111 | |
--一般キーとして以下のキーワードを利用可能 | |
-- delete esc ← → ↓ ↑ space tab return | |
--利用例: | |
-- shortcut("", "command-option-control-shift-A") --==keystroke "a" using {command down, option down, control down, shift down} | |
-- shortcut("", "command-126") --==key code 126 using {command down} | |
-- shortcut("", "command-1") --==keystroke "1" using {command down} | |
-- shortcut("Finder", "control-space") | |
on shortcut(app_name, key_text) | |
if key_text is "" or key_text is {} then | |
error "key_text が入力されていません。" | |
end if | |
if (count of key_text) = 1 then | |
set key_list to split(key_text's first item, "-") | |
else | |
set key_list to split(key_text, "-") | |
end if | |
set last_key to downcase(key_list's last item) | |
set modifier_key to {} | |
if "command" is in key_list then set modifier_key to modifier_key & command down | |
if "option" is in key_list then set modifier_key to modifier_key & option down | |
if "control" is in key_list then set modifier_key to modifier_key & control down | |
if "shift" is in key_list then set modifier_key to modifier_key & shift down | |
if last_key is "delete" then | |
set last_key to 51 --delete | |
else if last_key is "esc" then | |
set last_key to 53 --esc | |
else if last_key is "←" then | |
set last_key to 123 --← | |
else if last_key is "→" then | |
set last_key to 124 --→ | |
else if last_key is "↓" then | |
set last_key to 125 --↓ | |
else if last_key is "↑" then | |
set last_key to 126 --↑ | |
else if last_key is "space" then | |
set last_key to space | |
else if last_key is "tab" then | |
set last_key to tab | |
else if last_key is "return" then | |
set last_key to return | |
else if last_key's length is 3 then | |
try | |
set last_key to last_key as number | |
end try | |
end if | |
press_key(app_name, last_key, modifier_key) | |
end shortcut | |
--キー操作を実行する | |
--利用例: | |
-- press_key("1", command down) | |
-- press_key(126, command down) | |
on press_key(app_name, normal_key, modifier_key) | |
--delay 0.2 --環境によって、必要なひと呼吸が変わってくる可能性がある | |
if app_name is "" then | |
set app_name to frontmost_app() | |
end if | |
tell application "System Events" | |
tell process app_name | |
if "AppleScript Runner" is in my every_process() or ¬ | |
frontmost is false then | |
set frontmost to true | |
end if | |
if my is_number(normal_key) then | |
key code normal_key using modifier_key | |
else | |
keystroke normal_key using modifier_key | |
end if | |
--delay 0.1 | |
end tell | |
end tell | |
end press_key | |
--Quicksilverから起動しているかどうか | |
on is_from_quicksilver() | |
try | |
my name as text | |
false | |
on error | |
true | |
end try | |
end is_from_quicksilver | |
--起動中のアプリケーション名をリストで取得する | |
on every_process() | |
tell application "System Events" | |
--name of every process | |
--every process's name | |
processes's name | |
end tell | |
end every_process | |
--最前面のアプリケーション名(拡張子なし)を取得する | |
on frontmost_app() | |
--short name of (info for (path to frontmost application)) -- short name属性がない場合、missing valueが返ってくる | |
--name of (path to frontmost application) --拡張子が付属してしまう。"Script Editor.app" | |
tell application "System Events" | |
set name_list to processes's name whose frontmost is true | |
name_list's first item | |
end tell | |
end frontmost_app | |
--1番上の書類ウィンドウを取得する(1番上の書類ウィンドウが存在しない場合、書類ウィンドウに限らず一番上のウィンドウを取得する) | |
on front_window() | |
tell application "System Events" | |
tell process (my frontmost_app()) | |
try | |
set topWindow to item 1 of (every window whose subrole is "AXStandardWindow") --1番上の書類ウィンドウ | |
topWindow --1番上の書類ウィンドウが存在しない場合、以下のエラー処理になる。 | |
on error | |
front window --set topWindow to front window --window 1 | |
end try | |
end tell | |
end tell | |
end front_window | |
--このライブラリが依存する_lib.scptのコピー | |
on do_ruby_script(ruby_code) | |
set shell_code to "ruby -e \"puts(" & ruby_code & ")\"" | |
do shell script shell_code | |
end do_ruby_script | |
on downcase(str) | |
do_ruby_script("'" & str & "'.downcase") | |
end downcase | |
on split(sourceText, separator) | |
if sourceText = "" then return {} | |
set oldDelimiters to AppleScript's text item delimiters | |
set AppleScript's text item delimiters to {separator} | |
set theList to text items of sourceText | |
set AppleScript's text item delimiters to oldDelimiters | |
return theList | |
end split | |
on is_number(num) | |
num's class is integer or num's class is real | |
end is_number | |
on is_number_text(str) | |
try | |
str as number | |
true | |
on error | |
false | |
end try | |
end is_number_text | |
on number_from(str) | |
try | |
str as number | |
on error | |
str | |
end try | |
end number_from | |
(* | |
on click_menu(app_name, menu_path) | |
set mp to split(menu_path, "/") | |
tell application "System Events" | |
tell process app_name | |
set frontmost to true --必ず、アクティブにしておく | |
tell menu bar 1 | |
tell menu bar item (mp's item 1) | |
tell menu (mp's item 1) | |
if mp's length is 2 then | |
pick ¬ | |
menu item (mp's item 2) | |
else if mp's length is 3 then | |
pick ¬ | |
menu item (mp's item 2)'s ¬ | |
menu (mp's item 2)'s ¬ | |
menu item (mp's item 3) | |
(* | |
tell menu item (mp's item 2) | |
tell menu (mp's item 2) | |
pick menu item (mp's item 3) | |
end tell | |
end tell | |
*) | |
else if mp's length is 4 then | |
pick ¬ | |
menu item (mp's item 2)'s ¬ | |
menu (mp's item 2)'s ¬ | |
menu item (mp's item 3)'s ¬ | |
menu (mp's item 3)'s ¬ | |
menu item (mp's item 4) | |
(* | |
tell menu item (mp's item 2) | |
tell menu (mp's item 2) | |
tell menu item (mp's item 3) | |
tell menu (mp's item 3) | |
pick menu item (mp's item 4) | |
end tell | |
end tell | |
end tell | |
end tell | |
*) | |
else | |
error "メニューパス \"" & menu_path & "\" を認識できません。" | |
end if | |
end tell | |
end tell | |
end tell | |
delay 0.1 --連続してメニューを操作する時、ひと呼吸必要 | |
end tell | |
end tell | |
end click_menu | |
*) | |
(* | |
on click_menu2(app_name, menu_name1, menu_name2) | |
tell application "System Events" | |
tell process app_name | |
set frontmost to true --必ず、アクティブにしておく | |
tell menu bar 1 | |
tell menu bar item menu_name1 | |
tell menu menu_name1 | |
pick menu item menu_name2 | |
end tell | |
end tell | |
end tell | |
delay 0.1 --連続してメニューを操作する時、ひと呼吸必要 | |
end tell | |
end tell | |
end click_menu2 | |
on click_menu3(app_name, menu_name1, menu_name2, menu_name3) | |
tell application "System Events" | |
tell process app_name | |
set frontmost to true --必ず、アクティブにしておく | |
tell menu bar 1 | |
tell menu bar item menu_name1 | |
tell menu menu_name1 | |
tell menu item menu_name2 | |
tell menu menu_name2 | |
pick menu item menu_name3 | |
end tell | |
end tell | |
end tell | |
end tell | |
end tell | |
delay 0.1 --連続してメニューを操作する時、ひと呼吸必要 | |
end tell | |
end tell | |
end click_menu3 | |
*) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* | |
LIBライブラリ | |
ロード方法の例(このライブラリをユーザースクリプトフォルダに"_lib.scpt"で保存した場合) | |
property LIB : load script file ((path to scripts folder as text) & "_lib.scpt") | |
あるいは動的に... | |
set LIB to load script file ((path to scripts folder as text) & "_lib.scpt") | |
開発&テスト環境 | |
MacBook OSX 10.5.6 | |
AppleScript 2.0.1 | |
Script Editor 2.2.1 (100.1) | |
*) | |
--rubyコードを実行して結果を返す | |
--do_ruby_script({"require 'uri'", "URI.escape(%q|" & "tell application \"System Events\" --ショートカット操作をする限り" & "|)"}) | |
on do_ruby_script(ruby_code) | |
set ruby_code to ruby_code as list | |
set last_code to ruby_code's last item | |
if (count of ruby_code) ≥ 2 then | |
set pre_code to join(ruby_code's items 1 thru -2, ";") & ";" | |
else | |
set pre_code to "" | |
end if | |
set shell_code to "ruby -e \"" & pre_code & "puts(" & last_code & ")\"" | |
log shell_code | |
do shell script shell_code | |
end do_ruby_script | |
--URIエンコードして結果を返す | |
--uri_escape("set lib to load script file ((path to scripts folder as text) & \"_lib.scpt\")") | |
--uri_escape(the clipboard) | |
on uri_escape(str) | |
str | |
replace(result, "\"", "__DQT__") | |
replace(result, "\\", "__BSL__") | |
replace(result, "__DQT__", "\\\"") | |
--log result | |
do_ruby_script({"require 'uri'", "URI.escape(%q|" & result & "|)"}) | |
replace(result, "__BSL__", "%5C") | |
end uri_escape | |
--正規表現の比較をして真偽値を返す | |
--re("/\\d/", "abc1") | |
--re("/^[\\+\\-]?[\\d\\.\\,]+$/", "+123,456.789") | |
on reg(reg_text, str) | |
try | |
do_ruby_script(reg_text & " =~ '" & str & "'") as integer | |
true | |
on error | |
false | |
end try | |
end reg | |
--数値を3桁区切りのテキストにする | |
on number_with_delimiter(num) | |
--注意:バックスラッシュは、バックスラッシュでエスケープすること(\\)。AppleScriptでは特殊な文字として扱われるため。 | |
--(num.to_s =~ /[-+]?¥d{4,}/) ? (num.to_s.reverse.gsub(/¥G((?:¥d+¥.)?¥d{3})(?=¥d)/, '¥1,').reverse) : num.to_s | |
--(num.to_s =~ /[-+]?\\d{4,}/) ? (num.to_s.reverse.gsub(/\\G((?:\\d+\\.)?\\d{3})(?=\\d)/, '\\1,').reverse) : num.to_s | |
do_ruby_script("('" & num & "' =~ /[-+]?\\d{4,}/) ? ('" & num & "'.reverse.gsub(/\\G((?:\\d+\\.)?\\d{3})(?=\\d)/, '\\1,').reverse) : '" & num & "'") | |
end number_with_delimiter | |
--printfコマンド | |
--printf("%3d:", 1) | |
--" 1:" | |
on printf(format, value) | |
do shell script "printf" & space & format & space & value | |
end printf | |
--金額の書式を整える | |
--number_to_currency(金額, 小数点以下の桁数, 先頭文字, 末尾文字) | |
--lib's number_to_currency(1000.5, 2, "¥", "円") | |
--"¥1,000.50円" | |
--on number_to_currency(num, decimal_place, header, footer) | |
on number_to_currency(num, decimal_place) | |
--do shell script "printf" & space & "%" & "." & decimal_place & "f" & space & num | |
printf("%" & "." & decimal_place & "f", num) | |
number_with_delimiter(result) | |
--header & result & footer | |
end number_to_currency | |
(* | |
on number_to_currency(arg) | |
do shell script "printf" & space & "%" & "." & arg's decimal_place & "f" & space & arg's num | |
number_with_delimiter(result) | |
arg's header & result & arg's footer | |
end number_to_currency | |
*) | |
--xが何者であるか判定する | |
(* | |
x's class is integer | |
x's class is real | |
x's class is text | |
x's class is list | |
x's class is record | |
*) | |
--数値かどうか真偽値を返す | |
--is_number("1") | |
on is_number(num) | |
num's class is integer or num's class is real | |
(* | |
if num = {} or num = "" then | |
false | |
else | |
(count of num) is 0 | |
end if | |
*) | |
end is_number | |
--数字(数値に変換できるテキスト)かどうか真偽値を返す | |
on is_number_text(str) | |
try | |
str as number | |
true | |
on error | |
false | |
end try | |
end is_number_text | |
--テキストを数値に変換する | |
--数値に変換できない場合は、そのままテキストを返す | |
on number_from(str) | |
try | |
str as number | |
on error | |
str | |
end try | |
end number_from | |
--10進数値と桁数を指定して、16進数文字列を返す | |
--利用例: | |
--hex_from(123, 2) | |
-- "7B" | |
on hex_from(num, digit) | |
set a_list to {} | |
repeat while num > 0 | |
set a_list to a_list & num mod 16 | |
set num to num div 16 | |
end repeat | |
repeat digit - (count a_list) times | |
set a_list to a_list & 0 | |
end repeat | |
"" | |
repeat with hex in a_list's reverse | |
result & "0123456789ABCDEF"'s item (hex + 1) | |
end repeat | |
end hex_from | |
--二重のリストに補正する | |
--本来、リストの中にリストを指定する想定なのだが... | |
-- {{"class","AppleScript"}, {"style","color:rgb(0,0,0);"}} | |
--リスト一つだけでは以下のように書いてしまいがち | |
-- {"class","AppleScript"} | |
--そのような状況で、本来の二重リストに修正する | |
-- {{"class","AppleScript"}} | |
on double_list_from(aList) | |
if aList's item 1's class is list then | |
aList | |
else | |
{aList} | |
end if | |
end double_list_from | |
--文字を繰り返し、連結して返す | |
--t_repeat(文字, 繰り返し回数) | |
--t_repeat("*", 3) as text | |
on t_repeat(str, aCount) | |
set t to "" | |
repeat aCount times | |
set t to t & str | |
end repeat | |
t | |
end t_repeat | |
--文字列を中央寄せ | |
--t_center(文字列, 文字列幅, 埋める文字) | |
--t_center("123", 6, "*") | |
on t_center(str, width, padding) | |
set len to str's length | |
set len_L to round_down((width - len) / 2, 0) --端数は切り捨て | |
set len_R to width - len_L - len | |
t_repeat(padding, len_L) & str & t_repeat(padding, len_R) | |
end t_center | |
--文字列を左寄せ | |
--t_left(文字列, 文字列幅, 埋める文字) | |
--t_left("123", 4, " ") | |
on t_left(str, width, padding) | |
--(str & t_repeat(padding, width))'s text 1 thru width | |
set str to str as text | |
str & t_repeat(padding, width - (count str)) | |
end t_left | |
--文字列を右寄せ | |
--t_right(文字列, 文字列幅, 埋める文字) | |
--t_right("123", 4, " ") | |
on t_right(str, width, padding) | |
--(t_repeat(padding, width) & str)'s text -1 thru -width | |
set str to str as text | |
t_repeat(padding, width - (count str)) & str | |
end t_right | |
--sourceTextをseparatorでリストに変換する | |
--split("1,2,3,4", ",") | |
-- 結果:{"1", "2", "3", "4"} | |
on split(sourceText, separator) | |
if sourceText = "" then return {} | |
set oldDelimiters to AppleScript's text item delimiters | |
set AppleScript's text item delimiters to {separator} | |
set theList to text items of sourceText | |
set AppleScript's text item delimiters to oldDelimiters | |
return theList | |
end split | |
--sourceListをseparatorで区切ったテキストに変換する | |
--join({"1", "2", "3", "4"}, ",") | |
-- 結果:"1,2,3,4" | |
--join({{1, 2}, {3, 4}}, ",") | |
-- 結果:"1,2,3,4" | |
on join(sourceList, separator) | |
set oldDelimiters to AppleScript's text item delimiters | |
set AppleScript's text item delimiters to {separator} | |
set theText to sourceList as text | |
set AppleScript's text item delimiters to oldDelimiters | |
return theText | |
end join | |
--sourceText中の全てのtext1をtext2に置き換える | |
--replace("abcdefg", "bc", "_bc_") | |
-- 結果:"a_bc_defg" | |
on replace(sourceText, text1, text2) | |
join(split(sourceText, text1), text2) | |
end replace | |
--sourceText中の全てのlist1をlist2に置き換える | |
--every_replace("abcdefg", {"bc", "e", "g"}, {"_bc_", "_e_", "_g_"}) | |
-- 結果:"a_bc_d_e_f_g_" | |
on every_replace(sourceText, list1, list2) | |
repeat with i from 1 to list1's number | |
set sourceText to replace(sourceText, list1's item i, list2's item i) | |
end repeat | |
end every_replace | |
--sourceText中の最初のtext1をtext2に置き換える | |
--replace_first("--tell application \"APP_NAME\" to activate--必要に応じて、アプリケーション\"APP_NAME\"をアクティブにする", "--", "--<span>") | |
--replace_first("end tell", "--", "--<span>") | |
on replace_first(sourceText, text1, text2) | |
set aList to split(sourceText, text1) | |
if (count aList) < 2 then | |
return sourceText | |
end if | |
set topText to join(aList's items 1 thru 2, text2) | |
if (count aList) = 2 then | |
topText | |
else | |
join({topText} & aList's items 3 thru -1, text1) | |
end if | |
end replace_first | |
--大文字に変換 | |
on upcase(aText) | |
do_ruby_script("'" & aText & "'.upcase") | |
end upcase | |
--小文字に変換 | |
on downcase(aText) | |
do_ruby_script("'" & aText & "'.downcase") | |
end downcase | |
--四捨五入する、丸め位置指定可能 | |
--round_mid(数値, 丸め位置) | |
--小数位置は10の指数で指定する | |
-- −2: 10^-2...小数第2位まで求める | |
-- 3: 10^3...千の位まで求める | |
on round_mid(num, place) | |
if place ≥ 0 then | |
set p to 10 ^ place as integer | |
else | |
set p to 10 ^ place | |
end if | |
(round num / p rounding as taught in school) * p | |
end round_mid | |
--切り上げする、丸め位置指定可能 | |
--round_up(数値, 丸め位置) | |
on round_up(num, place) | |
if place ≥ 0 then | |
set p to 10 ^ place as integer | |
else | |
set p to 10 ^ place | |
end if | |
(round num / p rounding up) * p | |
end round_up | |
--切り捨てする、丸め位置指定可能 | |
--round_down(数値, 丸め位置) | |
on round_down(num, place) | |
if place ≥ 0 then | |
set p to 10 ^ place as integer | |
else | |
set p to 10 ^ place | |
end if | |
(round num / p rounding down) * p | |
end round_down | |
(*速い | |
set a_time to current date | |
repeat 100000 times--10万回で5秒 | |
offset_in({"ab", "cde", 1, 108, {}}, {}) | |
end repeat | |
(current date) - a_time--5 | |
*) | |
--offset_in({"ab", "cde", 1, 108, {}}, 108) | |
on offset_in(src_list, find_item) | |
set i to 0 | |
repeat with a_item in src_list | |
set i to i + 1 | |
if a_item as list is find_item as list then return i | |
end repeat | |
0 | |
end offset_in | |
(*遅い | |
set a_time to current date | |
repeat 10000 times--1万回で5秒 | |
offset_in2({"ab", "cde", 1, 108, {}}, {}) | |
end repeat | |
(current date) - a_time --5 | |
*) | |
--offset_in2({"ab", "cde", 1, 108, {}}, 108) | |
on offset_in2(src_list, find_item) | |
set delimiter to "__,__" | |
set src_text to "__" & join(src_list, delimiter) & "__" | |
set find_item to "__" & find_item & "__" | |
set i to offset of find_item in src_text | |
(src_text's items 1 thru i as text) & "_" | |
count split(result, delimiter) | |
end offset_in2 | |
--max({3, 2, 5, 1, 4}) | |
on max(a_list) | |
a_list's item 1 | |
repeat with a_item in a_list | |
if a_item > result then | |
a_item | |
else | |
result | |
end if | |
end repeat | |
result's contents | |
end max | |
--max_offset({3, 2, 5, 1, 4}) | |
on offset_of_max(a_list) | |
set max_i to 1 | |
repeat with i from 1 to a_list's number | |
if a_list's item i > a_list's item max_i then | |
set max_i to i | |
end if | |
end repeat | |
max_i | |
end offset_of_max | |
--min({3, 2, 5, 1, 4}) | |
on min(a_list) | |
a_list's item 1 | |
repeat with a_item in a_list | |
if a_item < result then | |
a_item | |
else | |
result | |
end if | |
end repeat | |
result's contents | |
end min | |
--min_offset({3, 2, 5, 1, 4}) | |
on offset_of_min(a_list) | |
set min_i to 1 | |
repeat with i from 1 to a_list's number | |
if a_list's item i < a_list's item min_i then | |
set min_i to i | |
end if | |
end repeat | |
min_i | |
end offset_of_min | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* | |
RTFクラス | |
アプリケーション名と書類の名前あるいは番号を指定して、RTF情報にアクセスする | |
アプリケーション名が""の場合は、その時アクティブなアプリケーションになる | |
書類の名前が""の場合は、document 1(最前面のウィンドウの書類)になる | |
利用例: | |
set RTF_OBJ to new("", "") | |
RTF_OBJ's everyText | |
RTF_OBJ's everyFont | |
RTF_OBJ's everySize | |
RTF_OBJ's everyColor | |
開発&テスト環境 | |
MacBook OSX 10.5.6 | |
AppleScript 2.0.1 | |
Script Editor 2.2.1 (100.1) | |
*) | |
--インスタンスを生成する(コンストラクタ) | |
on new(app_name, doc_name_or_num) | |
if app_name = "" then set app_name to frontmost_app() | |
if doc_name_or_num = "" then set doc_name_or_num to 1 | |
script RTF_instance | |
property parent : me | |
--global everyText, everyFont, everySize, everyColor | |
property everyText : missing value | |
property everyFont : missing value | |
property everySize : missing value | |
property everyColor : missing value | |
--初期化 | |
on initalize() | |
--validate(検証)の順序大事 | |
validate_presence_of_document() | |
parse() | |
validate_rtf() | |
validate_presence_of_text() | |
me | |
end initalize | |
--リッチテキスト情報を取得する(都度、メソッド呼び出しで処理すると、とっても遅くなったので、変数に代入することに) | |
on parse() | |
try | |
tell application app_name | |
tell document doc_name_or_num's paragraph | |
set everyText to (every attribute run) | |
set everyFont to (every attribute run)'s font | |
set everySize to (every attribute run)'s size | |
set everyColor to (every attribute run)'s color | |
end tell | |
end tell | |
end try | |
end parse | |
--documentの存在を検証 | |
on validate_presence_of_document() | |
tell application app_name | |
try | |
if (count document) > 0 then return | |
end try | |
"ドキュメントがありません。" | |
--display dialog result buttons "OK" default button "OK" giving up after 10 | |
display alert result giving up after 10 | |
error | |
end tell | |
end validate_presence_of_document | |
--テキストの存在を検証 | |
on validate_presence_of_text() | |
tell application app_name | |
try | |
if everyText's number > 0 then return | |
end try | |
"変換するテキストがありません。" | |
--display dialog result buttons "OK" default button "OK" giving up after 10 | |
display alert result giving up after 10 | |
error | |
end tell | |
end validate_presence_of_text | |
--変換できるリッチテキストかどうか検証 | |
on validate_rtf() | |
tell application app_name | |
try | |
if everyText's number = everyFont's number and ¬ | |
everyText's number = everySize's number and ¬ | |
everyText's number = everyColor's number then return | |
end try | |
"リッチテキストでないため変換できません。" | |
--display dialog result buttons "OK" default button "OK" giving up after 10 | |
display alert result giving up after 10 | |
error | |
end tell | |
end validate_rtf | |
end script | |
result's initalize() | |
end new | |
--最前面のアプリケーション名(拡張子なし)を取得する | |
on frontmost_app() | |
--short name of (info for (path to frontmost application)) -- short name属性がない場合、missing valueが返ってくる | |
--name of (path to frontmost application) --拡張子が付属してしまう。"Script Editor.app" | |
tell application "System Events" | |
set name_list to processes's name whose frontmost is true | |
name_list's first item | |
end tell | |
end frontmost_app | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* | |
通貨両替機(サンプルコード) | |
関連日記: | |
AppleScriptで通貨両替計算機を作ってみる | |
http://d.hatena.ne.jp/zariganitosh/20090212/1234442419 | |
オブジェクト指向AppleScript言語 | |
http://d.hatena.ne.jp/zariganitosh/20090210/1234233639 | |
*) | |
property LIB : load script file ((path to scripts folder as text) & "_lib.scpt") | |
property kind_list : {"米ドル", "ユーロ", "英ポンド", "スイスフラン"} | |
(* | |
init() | |
input_rate() | |
repeat | |
exchange() | |
end repeat | |
*) | |
init() | |
repeat | |
input_rate() | |
repeat | |
try --キャンセル ボタンを捕まえるため | |
exchange() | |
on error msg number num from obj partial result try_obj to class_name | |
--display dialog msg & space & num | |
if num is 128 then --キャンセルならループを抜ける | |
exit repeat | |
else --キャンセル以外はそのままエラー | |
error msg number num from obj partial result try_obj to class_name | |
end if | |
end try | |
end repeat | |
end repeat | |
--必要なだけ両替機を生成する | |
on init() | |
if my exchanger's all() is {} then | |
repeat with aKind in kind_list | |
my exchanger's new(aKind) | |
end repeat | |
end if | |
end init | |
--変換レートを入力する | |
on input_rate() | |
repeat with aExchanger in my exchanger's all() | |
set msg to "交換レート: 1" & aExchanger's currency & "は 何円?" | |
display dialog msg default answer aExchanger's rate | |
aExchanger's set_rate(text returned of result) | |
end repeat | |
end input_rate | |
--両替の計算をする | |
on exchange() | |
display dialog "金額を入力してください。" default answer "" buttons {"キャンセル", "外貨→円", "円→外貨"} | |
if button returned of result is "外貨→円" then | |
display dialog my exchanger's all_yen_from(text returned of result) as text | |
else if button returned of result is "円→外貨" then | |
display dialog my exchanger's all_other_from(text returned of result) as text | |
end if | |
end exchange | |
--通貨両替機クラス(Exchangerクラスは、_Exchangerインスタンスを生成・管理する能力を持っている) | |
--このクラスにnewを送信すると、ある外貨の両替に対応した両替機が一つ生成される。 | |
--生成された両替機は、プロパティitem_listに追加され、このクラスでまとめて管理される。 | |
script exchanger | |
property item_list : {} | |
on new(aCurrency) | |
set aItem to _new(aCurrency) | |
set item_list to item_list & aItem | |
aItem | |
end new | |
on _new(aCurrency) | |
script _Exchanger | |
property currency : aCurrency | |
property rate : 0 | |
on set_currency(amounts) | |
set currency to amounts | |
end set_currency | |
on set_rate(theRate) | |
set rate to theRate | |
end set_rate | |
--外貨から円に変換する | |
on yen_from(other) | |
--表示例:"1,000米ドル → 100,000.99円" | |
my LIB's number_to_currency(other, 0) & my LIB's t_left(currency, 6, " ") & " → " & my LIB's number_to_currency(other * rate, 2) & "円" & return | |
--other & currency & " → " & (other * rate) & "円" & return | |
end yen_from | |
--円から外貨に変換する | |
on other_from(yen) | |
--表示例:"100,000円 → 1,000.99米ドル" | |
my LIB's number_to_currency(yen, 0) & "円" & " → " & my LIB's number_to_currency(yen / rate as text, 2) & currency & return | |
--yen & "円" & " → " & (yen / rate) & currency & return | |
end other_from | |
end script | |
end _new | |
on all() | |
item_list | |
end all | |
on all_yen_from(other) | |
set msg_list to {} | |
repeat with aItem in item_list | |
set msg_list to msg_list & aItem's yen_from(other) | |
end repeat | |
msg_list | |
end all_yen_from | |
on all_other_from(yen) | |
set msg_list to {} | |
repeat with aItem in item_list | |
set msg_list to msg_list & aItem's other_from(yen) | |
end repeat | |
msg_list | |
end all_other_from | |
end script | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* | |
メール送信後にテキストエンコーディングを自動に設定して文字化け対策 | |
フォルダアクションから利用する | |
関連日記: | |
GUIスクリプティングなAppleScript環境を快適にする | |
http://d.hatena.ne.jp/zariganitosh/20090218/1235018953 | |
*) | |
property GUI : load script file ((path to scripts folder as text) & "_gui.scpt") | |
on adding folder items to this_folder after receiving added_items | |
tell application "Finder" to open added_items | |
GUI's init() | |
GUI's check() | |
GUI's shortcut("Mail", "command-option-1") | |
GUI's shortcut("", "command-W") | |
GUI's click_menu("", "ウインドウ/メッセージビューア") | |
GUI's shortcut("", "command-W") | |
GUI's shortcut("", "command-option-N") | |
end adding folder items to |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* | |
リッチテキストをシンタックスハイライトなHTMLに変換する | |
関連日記: | |
シンタックスハイライトなHTMLに変換するオブジェクト指向AppleScript その1 | |
http://d.hatena.ne.jp/zariganitosh/20090222/1235458945 | |
シンタックスハイライトなHTMLに変換するオブジェクト指向AppleScript その2 | |
http://d.hatena.ne.jp/zariganitosh/20090223/1235459255 | |
シンタックスハイライトなHTMLに変換するオブジェクト指向AppleScript その3 | |
http://d.hatena.ne.jp/zariganitosh/20090224/1235460563 | |
シンタックスハイライトなHTMLに変換するオブジェクト指向AppleScript その4 | |
http://d.hatena.ne.jp/zariganitosh/20090225/1235510758 | |
*) | |
property LIB : load script file ((path to scripts folder as text) & "_lib.scpt") | |
property RTF : load script file ((path to scripts folder as text) & "_rtf.scpt") | |
property FIND_TEXTS : {"\t", "&", "<", ">", "¬"} --"\t" = tab | |
property PUTS_TEXTS : {" ", "&", "<", ">", "¬"} | |
property defaultFontFamily : "CourierNewPSMT" | |
property defaultFontSize : "12px" | |
property defaultColor : missing value | |
set RTF_OBJ to RTF's new("", "") | |
set defaultColor to most_hex_color(RTF_OBJ's everyText, RTF_OBJ's everyColor) | |
--set line_num_format to "%" & (count (RTF_OBJ's everyText's number as text)) & "d:" | |
set html to "" | |
repeat with i from 1 to RTF_OBJ's everyText's number | |
set line_text to RTF_OBJ's everyText's item i | |
set line_font to RTF_OBJ's everyFont's item i | |
set line_size to RTF_OBJ's everySize's item i | |
set line_color to RTF_OBJ's everyColor's item i | |
set html to html & space | |
--set html to html & LIB's printf(line_num_format, i) & space | |
repeat with j from 1 to line_text's number | |
set aText to line_text's item j | |
set aFont to line_font's item j | |
set aSize to line_size's item j | |
set aColor to line_color's item j | |
set html to html & text_or_tag(aText, aFont, aSize, aColor) | |
end repeat | |
end repeat | |
set the clipboard to tag("pre" & return, html, {"style", default_css()}) | |
(* | |
htmlに変換するハンドラ | |
*) | |
--見えない文字はそのまま、見える文字はタグで囲って返す | |
on text_or_tag(aText, aFont, aSize, aColor) | |
--if reg("/^[\\t\\s\\r]+$/", originalText) then--処理が遅過ぎ | |
if is_invisible(aText) then | |
content_text(aText) | |
else | |
tag(tag_by_font(aFont), content_text(aText), {"style", css(aFont, aSize, aColor)}) | |
end if | |
end text_or_tag | |
--見えない文字の連続かどうか真偽値で返す(見えない:true) | |
on is_invisible(str) | |
str's item 1 & LIB's replace(str, str's item 1, "") | |
result is in {tab, space, return} | |
end is_invisible | |
--タグで囲って返す | |
--利用例: | |
-- tag("span", "ABC", {{"class","AppleScript"}, {"style","color:rgb(0,0,0);"}}) | |
-- <span class="AppleScript" style="color:rgb(0,0,0);">ABC</span> | |
--ペアリストが一つだけの場合は下記でもOK | |
--利用例: | |
-- tag("span", "ABC", {"style","color:rgb(0,0,0);"}) | |
-- <span style="color:rgb(0,0,0);">ABC</span> | |
-- tag("pre", "ABC", "") | |
-- <pre>ABC</pre> | |
-- tag("pre"&return, "ABC", "") | |
-- <pre> | |
-- ABC | |
-- </pre> | |
-- | |
on tag(tag_name, str, attr_pair_list) | |
if tag_name's item -1 is in {return, "\n"} then | |
return tag(tag_name's items 1 thru -2 as text, return & str & return, attr_pair_list) & return | |
end if | |
attr_text(double_list_from(attr_pair_list)) | |
if result ≠ "" then | |
"<" & tag_name & result & ">" & str & "</" & tag_name & ">" | |
else if tag_name is not in {"span"} then | |
"<" & tag_name & ">" & str & "</" & tag_name & ">" | |
else | |
str | |
end if | |
end tag | |
--二重のリストに補正する | |
--本来、リストの中にリストを指定する想定なのだが... | |
-- {{"class","AppleScript"}, {"style","color:rgb(0,0,0);"}} | |
--リスト一つだけでは以下のように書いてしまいがち | |
-- {"class","AppleScript"} | |
--そのような状況で、本来の二重リストに修正する | |
-- {{"class","AppleScript"}} | |
on double_list_from(aList) | |
if aList's item 1's class is list then | |
aList | |
else | |
{aList} | |
end if | |
end double_list_from | |
--ペアリストから属性を指定するテキストを返す | |
--ペアリストとは{キー,値}のリストから構成されるリストを想定している | |
--{{"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}} | |
--利用例: | |
-- attr_text({{"class","AppleScript"}, {"style","color:rgb(0,0,0);"}}) | |
-- " class=\"AppleScript\" style=\"color:rgb(0,0,0);\"" | |
on attr_text(pair_list) | |
set aText to "" | |
repeat with pair in pair_list | |
if pair's item 2 ≠ "" then | |
set aText to aText & space & pair's item 1 & "=\"" & pair's item 2 & "\"" | |
end if | |
end repeat | |
aText | |
end attr_text | |
--必要な置き換えをしたテキストを返す | |
on content_text(str) | |
LIB's every_replace(str, FIND_TEXTS, PUTS_TEXTS) | |
end content_text | |
--デフォルトのインラインスタイルを返す | |
on default_css() | |
"color:" & defaultColor & ";" & "font-size:" & defaultFontSize & ";" & "font-family:" & defaultFontFamily & ";" | |
end default_css | |
--インラインスタイルを返す | |
on css(aFont, aSize, aColor) | |
--css_color(aColor) & css_font_size(aSize) & css_font_weight(aFont) | |
--css_color(aColor) & css_font_size(aSize) & css_font_family(aFont) | |
css_color(aColor) -- & css_font_weight(aFont) | |
end css | |
--フォントの色の設定コードを返す color:rgb(255,255,255); | |
on css_color(aColor) | |
hex_color(aColor) | |
if result = defaultColor then | |
return "" | |
else | |
"color:" & result -- & ";" | |
end if | |
end css_color | |
--フォントサイズの設定コードを返す font-size:12px; | |
on css_font_size(aSize) | |
aSize & "px" | |
if result = defaultFontSize then | |
return "" | |
else | |
"font-size:" & result & ";" | |
end if | |
end css_font_size | |
--フォントの太さの設定コードを返す font-weight:bold; | |
on css_font_weight(aFont) | |
if "bold" is in aFont then | |
"font-weight:bold;" | |
end if | |
end css_font_weight | |
--フォントの種類の設定コードを返す font-family:Osaka | |
on css_font_family(aFont) | |
aFont | |
if result = defaultFontFamily then | |
return "" | |
else | |
"font-family:" & result & ";" | |
end if | |
end css_font_family | |
--フォントに応じたタグを返す | |
on tag_by_font(aFont) | |
if "bold" is in aFont then | |
"b" | |
else | |
"span" | |
end if | |
end tag_by_font | |
--RGB指定のカラー文字列を返す | |
--利用例: | |
--rgb_color({65535, 65535, 65535}) | |
-- 結果:"rgb(255,255,255)" | |
on rgb_color(color_list) | |
set R to (color_list's item 1) div 256 | |
set G to (color_list's item 2) div 256 | |
set B to (color_list's item 3) div 256 | |
"rgb(" & R & "," & G & "," & B & ")" | |
end rgb_color | |
--16進数のカラー文字列を返す | |
--利用例: | |
--hex_color({65535, 65535, 65535}) | |
-- 結果:"#FFFFFF" | |
on hex_color(color_list) | |
"" | |
repeat with i in color_list | |
--result & LIB's hex_from(i div 256, 2) | |
result & LIB's hex_from(i div 4096, 1) | |
end repeat | |
"#" & result | |
end hex_color | |
--一番多く出現する16進数カラーを返す | |
on most_hex_color(every_text, every_color) | |
sum_every_color(every_text, every_color) | |
hex_color(result's item 1's item (LIB's offset_of_max(result's item 2))) | |
end most_hex_color | |
--カラー値を集計して、カラーと出現回数のリストで返す(見えない文字のカラーは集計しない) | |
--返されるリストの例: | |
-- { | |
-- {{65535, 52428, 26214}, {46003, 46003, 46003}, {10530, 0, 65535}, {16383, 32767, 0}, {0, 0, 65535}, {0, 0, 0}}, | |
-- {404, 59, 203, 238, 72, 79} | |
-- } | |
on sum_every_color(every_text, every_color) | |
set sum_colors to {} | |
set sum_counts to {} | |
repeat with i from 1 to every_text's number | |
set line_text to every_text's item i | |
set line_color to every_color's item i | |
repeat with j from 1 to line_text's number | |
set a_text to line_text's item j | |
set a_color to line_color's item j | |
if is_invisible(a_text) is false then | |
set colors_i to LIB's offset_in(sum_colors, a_color) | |
if colors_i = 0 then | |
set sum_colors to sum_colors & {a_color} | |
set sum_counts to sum_counts & 1 | |
else | |
set sum_counts's item colors_i to (sum_counts's item colors_i) + 1 | |
end if | |
end if | |
end repeat | |
end repeat | |
{sum_colors, sum_counts} | |
end sum_every_color | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* | |
選択中のテキストでスポットライト検索する | |
Quicksilver等でショートカットを割り当てて利用する | |
関連日記: | |
GUIスクリプティングなAppleScript環境を快適にする | |
http://d.hatena.ne.jp/zariganitosh/20090218/1235018953 | |
*) | |
property GUI : load script file ((path to scripts folder as text) & "_gui.scpt") | |
GUI's init() | |
GUI's shortcut("", "command-c") | |
GUI's shortcut("", "control-space") | |
GUI's shortcut("", "command-V") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment