「AppleScriptによるWebブラウザ自動操縦ガイド」をmacOS 13向けに内容更新中です。Ver.1.3になります。
本文の更新はできているので、添付のScriptの動作確認がひととおり終わればリリースします。すでにお買い上げの方は、Ver.1.3のリリースにともない、再ダウンロードすることで最新版をご覧いただけます。
Google Chromiumのみ、普通にインストールしても動かなかったのでv1.2と同様、Intel Binary版での検証となります。
「AppleScriptによるWebブラウザ自動操縦ガイド」をmacOS 13向けに内容更新中です。Ver.1.3になります。
本文の更新はできているので、添付のScriptの動作確認がひととおり終わればリリースします。すでにお買い上げの方は、Ver.1.3のリリースにともない、再ダウンロードすることで最新版をご覧いただけます。
Google Chromiumのみ、普通にインストールしても動かなかったのでv1.2と同様、Intel Binary版での検証となります。
Piymaru Softwareによる電子書籍の72冊目、「AppleScript基礎テクニック(29)セキュリティ機能解除」を発売しました。PDF 36ページ+サンプルScript Zipアーカイブで構成されています。
→ 販売ページ
macOS上の主要アプリケーション、FileMaker Pro、ミュージック.app、Webブラウザ、iWork(Keynote、Pages、Numbers)、CotEditorときて、ご要望の多かった「メール」(Mail.app)についてのScripting本です。macOS 13.1+Mail.app v16対応。PDF 369ページ+サンプルScript Zipアーカイブで構成されています。
macOS 10.7以降、それ自体の機能を制限するための「セキュリティ機能」が強化されるようになりました。つまり、機能を「制限する機能」です。macOS 10.10以降になると、セキュリティ機能の制約はAppleScriptにも及ぶようになり、デフォルトの状態では各種機能を動作できない設定状態でOSがリリースされるようになりました。
AppleScriptからmacOSのフル機能を利用するためには、各種セキュリティ機能の解除を行う必要があるわけです。AppleScriptからアプリケーションを操作しようとすると、「プライバシーとセキュリティ」>「オートメーション」などで実行側のプログラム(AppleScriptアプレットなど)に対して実行許可が必要です。
この解除方法を知らなければ、AppleScriptの制限解除が行えないわけで、「Scriptが動かなくなった!」「Scriptが壊れた!」と騒いでいる人を見かけますが、ほとんどがこれです。そして、Appleがこうした説明をしないため、知識や情報を持たない人はOSの機能を十分に発揮させられません。macOSの足枷を外して、本来のパワーを取り戻すための1冊です。もちろん、危険なことには手を出しません。
初期状態のままだと最新の環境でASが動かない
macOSのバージョンとセキュリティ機能の変化
macOS 12までの「セキュリティとプライバシー」
macOS 13からの「プライバシーとセキュリティ」
①アクセシビリティ
②フルディスクアクセス
③ファイルとフォルダ
④オートメーション
オートメーションの認証状態を取得
アクセシビリティの認証状態をScriptで確認
AppleScriptアプレットを実行する場合には
実行環境1:スクリプトエディタ
実行環境2:スクリプトメニュー
実行環境3:Automator
実行環境4:ショートカット.app
実行環境5:/usr/bin/osascript
AppleScript 各ランタイム環境情報(1/2)
AppleScript 各ランタイム環境情報(2/2)
Image Eventsが使えない!
ドロップレットでファイルを受信できない!
Safari でAppleScriptのコマンドがエラーに!
Safari 10以降のdo JavaScript設定
Keynoteの最前面の書類中の、現在表示中のスライドの表の選択中のセル中のテキストを取得してDeepLのREST APIを呼び出して指定言語に翻訳し、表のセルに翻訳後のテキストを書き戻すAppleScriptです。
DeepLのREST API呼び出しのためには、DeepL SE社のWebサイトで「DeepL API Free」(無料コース)か「DeepL API Pro」プランにサインアップして、API Keyを取得して、プログラムリスト中に記入したうえで実行してください。
▲実行前。Keynote書類上の表の翻訳対象のセルを選択して実行
▲実行後。Keynote書類上の表の翻訳対象のセルをに翻訳後の内容をストア
実際に使ってみると、けっこう翻訳に時間がかかるのと、一度翻訳した同じフレーズを再度翻訳させるのはコストがかかるため、ローカルに「翻訳キャッシュ」を作って、翻訳ずみの内容を再翻訳しないように工夫する必要がありそうです。
AppleScript名:Keynoteの表の選択中のセルのデータをDeepLで翻訳して書き戻す.scpt |
— – Created by: Takaaki Naganoya – Created on: 2023/01/30 — – Copyright © 2023 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use scripting additions property NSString : a reference to current application’s NSString property NSCountedSet : a reference to current application’s NSCountedSet property NSJSONSerialization : a reference to current application’s NSJSONSerialization property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding set myAPIKey to "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" set myTargLang to "EN" –翻訳ターゲット言語 set aTableDat to returnSelectedTableCellDataOnCurrentSlide() of me –> {"プロパティ項目", "データ型", "読み/書き", "内容(サンプル)", "説明"} set nList to {} repeat with i in aTableDat set j to contents of i set tRes to translateWithDeepL(j, myAPIKey, myTargLang) of me set the end of nList to tRes end repeat –表に翻訳した内容を書き戻す storeSelectedTableCellDataOnCurrentSlide(nList) of me on storeSelectedTableCellDataOnCurrentSlide(sList) tell application "Keynote" tell front document tell current slide try set theTable to first table whose class of selection range is range on error return false –何も選択されてなかった場合 end try tell theTable set cList to every cell of selection range if (length of cList) is not equal to (length of sList) then error set aCount to 1 repeat with i in cList set j to contents of i tell j set value of it to (contents of item aCount of sList) end tell set aCount to aCount + 1 end repeat end tell end tell end tell end tell end storeSelectedTableCellDataOnCurrentSlide on returnSelectedTableCellDataOnCurrentSlide() tell application "Keynote" tell front document tell current slide try set theTable to first table whose class of selection range is range on error return false –何も選択されてなかった場合 end try tell theTable set vList to value of every cell of selection range set cCount to count of column of selection range set rCount to count of row of selection range –複数行選択されていた場合にはエラーを返すなどの処理の布石 return vList end tell end tell end tell end tell end returnSelectedTableCellDataOnCurrentSlide –DeepLのAPIを呼び出して翻訳する on translateWithDeepL(myText, myAPIKey, myTargLang) set sText to "curl -X POST ’https://api-free.deepl.com/v2/translate’ -H ’Authorization: DeepL-Auth-Key " & myAPIKey & "’ -d ’text=" & myText & "’ -d ’target_lang=" & myTargLang & "’" try set sRes to do shell script sText on error error end try set jsonString to NSString’s stringWithString:sRes set jsonData to jsonString’s dataUsingEncoding:(NSUTF8StringEncoding) set aJsonDict to NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value) set tRes to aJsonDict’s valueForKeyPath:"translations.text" if tRes = missing value then set erMes to (aJsonDict’s valueForKey:"message") as string error erMes else return contents of first item of (tRes as list) end if end translateWithDeepL |
1987年に結成し、1994年まで会誌を発行し続けていたポケットコンピュータのユーザーズサークル「LL」の会報Vol.19の復刻・電子書籍版を刊行しました。
→ 販売ページ
Piyomaru Softwareによる電子書籍の71冊目です。例によって制作過程では大量のAppleScriptが使用されていますが、AppleScriptに関する本ではありません。
1987年に結成された、ポケコンサークル「LL」の会誌最終号(Vol.19)の復刻版です(当時のLL会員の方には無償配布)。1994年に発行された会誌Vol.19のバックアップCD-Rデータから再作成して蘇った電子書籍版。PDF 282ページ。
・欧州の森に謎のPC-1560を見た!
・幸福の青いPC-1500″D”
・月々240円で昔の彼女に会える
・SC61860をサポートするクロスアセンブラ
・2022年に新発売のMEPに驚愕!
・これがCE-140Fエミュレータだ!
・PC-1600用 大容量RAMモジュール
・露国在住のHWRなあんちくしょう
・多機種対応/合体式Bluetoothモジュール
・CE-126Pエミュレータで感熱紙不要の印刷を
・鉄人・堀川浩司氏のイベント参加魂!
・独仏のWebサイトは一味も二味も違う!
・東京都青梅市に古パソコン動態保存の「夢の図書館」
・ポケコン用のLCDをオリジナルで作成・販売
・ポケコン用周辺機器の製造・販売を行う高松製作所
・ポケコンなどの3Dモデルをフリー公開
・日本国内外のパソコンメーカー栄枯盛衰
ちょっとした16進数の計算を行いたいときに、AppleScriptのネイティブ機能にはそういうのはないので、別のものが持っている機能を利用することになります。
いろいろCocoa系の機能も探してみたものの、結局「shellのbcコマンドが手っ取り早くていいよね!」ということに。
ポケコンサークルの会誌のダンプリストをもとに、入力用のBASICのリストを自動作成するとき、アドレスを変更しなくては入力できないことが判明。このさい、アドレス計算を行うのに16進数の加算が必要でした。そのために作ってみたものです。
AppleScript名:16進数の計算.scpt |
— – Created by: Takaaki Naganoya – Created on: 2023/01/25 — – Copyright © 2023 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use scripting additions set a to "8030" set b to "6000" set h1 to hexStrAdd(a, b) of me –> "E030" set h3 to hexStrSub(a, b) of me –> "2030" on hexStrAdd(aStr as string, bStr as string) set sStr to "echo \"ibase=10; obase=10; " & aStr & "+" & bStr & "\" | bc" set aRes to do shell script sStr return aRes as string end hexStrAdd on hexStrSub(aStr as string, bStr as string) set sStr to "echo \"ibase=10; obase=10; " & aStr & "-" & bStr & "\" | bc" set aRes to do shell script sStr return aRes as string end hexStrSub |
はるかかなた昔の、MZ-80Bが採用していた単音3オクターブの範囲の音楽再生を行うPLAY文、それに準拠したポケットコンピュータ用の音楽再生プログラムのデータ「アルハンブラの想い出」の再生を行うため「だけ」に、そのMML再生プログラムをAppleScriptで作ってみたものです(2時間ぐらいだったか)。
音階再生用に、オープンソースの「MPSoundEngine」フレームワークをUniversal Binaryでビルドし直して、これを用いて音階データと音の長さのデータのテーブルを作って再生しています。
–> Download mpSoundKit_univ.framework(To ~/Library/Frameworks)
オリジナルのMZにしてもポケットコンピュータのMML再生プログラムにしても、単音しか出ない仕様ですが、このデータの原作者が楽譜を細切れにしてアルペジオ奏法で演奏させているかのような効果を生み出しています。これは、当時も腰を抜かしましたが、普通こんなものはやらない狂気の産物、人類レベルの遺産といえます。
MPSoundEngineをフレームワーク化したものを呼び出しているため、実行にはScript Debuggerが必要です。macOS 11よりも古い環境では以前に掲載したFramework(Intelバイナリのみ)がそのまま利用できるはずです。
まだ、いまひとつ休符(R)の処理などがうまく行っていないようで、この曲以外のデータを再生させると、首をひねってしまう演奏をしてしまうものの、それはオリジナルのデータの出来がよくなかったのか、あるいはこのプログラムの再現度が高くないためかは不明です。
AppleScript名:SHARP MZ MML再生_アルハンブラ_mono.scptd |
— – Created by: Takaaki Naganoya – Created on: 2022/12/22 — – Copyright © 2022 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use framework "mpSoundKit" –https://github.com/matthiasplappert/MPSoundEngine use scripting additions script spd property musStr : "" property musList : {} property mmlList : {} end script set octL to {"-C", "-#C", "-D", "-#D", "-E", "-F", "-#F", "-G", "-#G", "-A", "-#A", "-B", "C", "#C", "D", "#D", "E", "F", "#F", "G", "#G", "A", "#A", "B", "+C", "+#C", "+D", "+#D", "+E", "+F", "+#F", "+G", "+#G", "+A", "+#A", "+B"} set lenL to {130.81, 138.59, 146.83, 155.56, 164.81, 174.61, 185.0, 196.0, 207.65, 220.0, 233.08, 246.94, 261.63, 277.18, 293.66, 311.13, 329.63, 349.23, 369.99, 392.0, 415.3, 440.0, 466.16, 493.88, 523.25, 554.37, 587.33, 622.25, 659.25, 698.46, 739.99, 783.99, 830.61, 880.0, 932.33, 987.77} set noteList to {"9", "8", "7", "6", "5", "4", "3", "2", "1", "0"} set noteTime to {4, 3, 2, 1.5, 1, 0.75, 0.5, 0.375, 0.25, 0.125} set aDict to current application’s NSMutableDictionary’s dictionaryWithObjects:(lenL) forKeys:(octL) set bDict to current application’s NSMutableDictionary’s dictionaryWithObjects:(noteTime) forKeys:(noteList) set (musStr of spd) to "-A0+E+E+EE+E+E+E+C0+E+E+EE+E+E+EB0+D+D+DE+D+D+D-A0+C+C+CE+C+C+CA0+C+C+CE+C+C+CB0+D+D+DE+D+D+D-A0+E+E+EE+E+E+E+C0+E+E+EE+E+E+E+C0+E+E+EE+E+E+E-A0+E+E+EE+E+E+E+C0+E+E+EE+E+E+E+D0+F+F+FG+F+F+FC0+G+G+GG+G+G+G+E0+G+G+GG+G+G+G+E0+F+F+FG+F+F+FC0+E+E+EG+E+E+E+C0+E+E+EG+E+E+E+D0+F+F+FG+F+F+FC0+G+G+GG+G+G+G+E0+G+G+GG+G+G+G+E0+G+G+GG+G+G+GC0+G+G+GG+G+G+G+E0+G+G+GG+G+G+G+E0+G+G+GG+G+G+G-F0+C+C+CC+C+C+CA0+C+C+CC+C+C+CG0+B+B+BC+B+B+B-F0+A+A+AC+A+A+A+F0+A+A+AC+A+A+A-D0+B+B+BF+B+B+B-E0+A+A+AB+A+A+A+E0+#G+#G+#GB0+#G+#G+#G+E0+#G+#G+#GB0+#G+#G+#G-E0+#G+#G+#G+D0+#G+#G+#G+E0+#G+#G+#G+D0+#G+#G+#G+E0+#G+#G+#G+D0+#G+#G+#G-A0+#A+#A+#A+#C0+#A+#A+#A+E0+#A+#A+#A+#C0+#A+#A+#A+E0+A+A+A+#C0+A+A+A#C0+G+G+GA+G+G+G+E0+G+G+GA+G+G+G+F0+A+A+AA+A+A+AD0+G+G+G+E+G+G+G+D0+F+F+FA+F+F+F+D0+F+F+FA+F+F+FD0+F+F+FA+F+F+F+D0+F+F+FA+F+F+F+D0+F+F+FA+F+F+FD0+E+E+EA+E+E+E+B0+E+E+EA+E+E+E+B0+D+D+DA+D+D+D-F0+C+C+C#D+C+C+CA0+C+C+C#D+C+C+CA0+D+D+DD+D+D+D-E0+C+C+CE+C+C+C#G0BBBEBBB#G0BBBEBBB-E0BBBEBBB#G0BBBEBBB#G0BBBEBBB-A0+E+E+EE+E+E+E+C0+E+E+EE+E+E+EB0+D+D+DE+D+D+D-A0+C+C+CE+C+C+CA0+C+C+CE+C+C+CB0+D+D+DE+D+D+D-A0+E+E+EE+E+E+E+C0+E+E+EE+E+E+E+C0+E+E+EE+E+E+E-A0+E+E+EE+E+E+E+C0+E+E+EE+E+E+E+D0+F+F+FG+F+F+FC0+G+G+GG+G+GE0+G+G+GG+G+G+G+E0+F+F+FG+F+F+FC0+E+E+EG+E+E+E+C0+E+E+EG+E+E+E+D0+F+F+FG+F+F+FC0+G+G+GG+G+G+G+E0+G+G+GG+G+G+G+E0+G+G+GG+G+G+GC0+G+G+GG+G+G+G+E0+G+G+GG+G+G+G+E0+G+G+GG+G+G+G-F0+C+C+CC+C+C+CA0+C+C+CC+C+C+CG0+B+B+BC+B+B+B-F0+A+A+AC+A+A+A+F0+A+A+AC+A+A+A-D0+B+B+BF+B+B+B-E0+A+A+AB+A+A+A+E0+#G+#G+#GB0+#G+#G+#G+E0+#G+#G+#GB0+#G+#G+#G-E0+#G+#G+#GD0+#G+#G+#G+E0+#G+#G+#G+D0+#G+#G+#G+E0+#G+#G+#GD0+#G+#G+#G-A0+#A+#A+#A+#C0+#A+#A+#A+E0+#A+#A+#A+#C0+#A+#A+#A+E0+A+A+A+#C+A+A+A#C0+G+G+GA+G+G+G+E0+G+G+GA+G+G+G+F0+A+A+AA+A+A+AD0+G+G+G+E+G+G+G+D0+F+F+FA+F+F+F+D0+F+F+FA+F+F+FD0+F+F+FA+F+F+F+D0+F+F+FA+F+F+F+D0+F+F+FA+F+F+FD0+E+E+EA+E+E+E+B0+E+E+EA+E+E+E+B0+D+D+DA+D+D+D-F0+C+C+C#D+C+C+CA0+C+C+C#D+C+C+CA0+D+D+DD+D+D+D-E0+C+C+CE+C+C+C#G0BBBEBBB#G0BBBEBBB-E0BBBEBBB#G0BBBEBBB#G0BBBEBBB-A0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+EB0+D+D+DE+D+D+D-A0+#C+#C+#CE0+#C+#C+#CA0+#C+#C+#CE0+#C+#C+#CB0+D+D+DE+D+D+D-A0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E-A0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E-A0+#F+#F+#F#F0+#F+#F+#F+D0+#F+#F+#F#F0+#F+#F+#F+D0+#F+#F+#F#F0+#F+#F+#F-A0+D+D+DD+D+D+DB0+D+D+DD+D+D+DD0+#F+#F+#F#F0+#F+#F+#F-A0+#F+#F+#F-D0+#F+#F+#G+#F+#C0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E-A0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E-#F0+A+A+A#F+A+A+AA0+A+A+A+#C+A+A+AA0+A+A+A#F+A+A+A#G0+#G+#G+#G#G0+#G+#G+#G#B0+#G+#G+#G#D0+#G+#G+#G#B0+#D+#D+#D#G0+#D+#D+#D#C0+#F+#F+#F#G0+#F+#F+#F+#C0+E+E+E#G+E+E+E+#C0+E+E+E#G+E+E+E#C0+E+E+E#G0+E+E+E+#C0+E+E+E#G+E+E+E+#C0+E+E+E#G+E+E+E-B0+D+D+DF+D+D+DF0+D+D+DD+D+D+DE0+D+D+DF+D+D+D-E0+#C+#C+#CE0+#C+#C+#CE0+#C+#C+#CE0+#C+#C+#C-E0BBBDBBB-A0BBBEBBBE0AAAEAAA#F0AAAGAAA-A0AAAEAAA#C0AAAEBBBA0+#C+#C+#CB0+D+D+D-A0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+EB0+D+D+DE+D+D+D-A0+#C+#C+#CE0+#C+#C+#CA0+#C+#C+#CE0+#C+#C+#CB0+D+D+DE+D+D+D-A0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E-A0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E-A0+#F+#F+#F#F0+#F+#F+#F+D0+#F+#F+#F#F0+#F+#F+#F+D0+#F+#F+#F#F0+#F+#F+#F-A0+D+D+DD+D+D+DB0+D+D+DD+D+D+DD0+#F+#F+#F#F0+#F+#F+#F-A0+#F+#F+#F-D0+#F+#F+#F+#C0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E-A0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E-#F0+A+A+A#F+A+A+AA0+A+A+A+#C+A+A+AA0+A+A+A#F+A+A+A#G0+#G+#G+#G#G0+#G+#G+#G#B0+#G+#G+#G#D0+#G+#G+#G#B0+#D+#D+#D#G0+#D+#D+#D#C0+#F+#F+#F#G0+#F+#F+#F+#C0+E+E+E#G+E+E+E+#C0+E+E+E#G+E+E+E#C0+E+E+E#G+E+E+E+#C0+E+E+E#G+E+E+E+#C0+E+E+E#G+E+E+E-B0+D+D+DF+D+D+DF0+D+D+DD+D+D+DE0+D+D+DF+D+D+D-E0+#C+#C+#CE0+#C+#C+#CE0+#C+#C+#CE0+#C+#C+#C-E0BBBDBBB-A0AAAEAAAE0AAAEBBBA0+C+C+CB+D+D+D-A0+E+E+EE+E+E+E+C0+E+E+EE+E+E+EB0+D+D+DE+D+D+D-A0+C+C+CE+C+C+CA0+C+C+CE+C+C+CB0+D+D+DE+D+D+D-A0+E+E+EE+E+E+E+C0+E+E+EE+E+E+E+C0+E+E+EE+E+E+E-A0+E+E+EE+E+E+E+C0+E+E+EE+E+E+E+D0+F+F+FG+F+F+FC0+G+G+GG+G+G+G+E0+G+G+GG+G+G+G+E0+F+F+FG+F+F+FC0+E+E+EG+E+E+E+C0+E+E+EG+E+E+ED0+F+F+FG+F+F+FC0+G+G+GG+G+G+G+E0+G+G+GG+G+G+G+E0+G+G+GG+G+G+GC0+G+G+GG+G+G+G+E0+G+G+GG+G+G+G+E0+G+G+GG+G+G+G-F0+C+C+CC+C+C+CA0+C+C+CC+C+C+CG0+B+B+BC+B+B+B-F0+A+A+AC+A+A+A+F0+A+A+AC+A+A+A-D0+B+B+BF+B+B+B-E0+A+A+AB+A+A+A+E0+#G+#G+#GB0+#G+#G+#G+E0+#G+#G+#GB0+#G+#G+#G-E0+#G+#G+#GD0+#G+#G+#G+E0+#G+#G+#G+D0+#G+#G+#G+E0+#G+#G+#G+D0+#G+#G+#G-A0+#A+#A+#A+#C0+#A+#A+#A+E0+#A+#A+#A+#C0+#A+#A+#A+E0+A+A+A+#C+A+A+A#C0+G+G+GA+G+G+G+E0+G+G+GA+G+G+G+F0+A+A+AA+A+A+AD0+G+G+G+E+G+G+G+D0+F+F+FA+F+F+F+D0+F+F+FA+F+F+FD0+F+F+FA+F+F+F+D0+F+F+FA+F+F+F+D0+F+F+FA+F+F+FD0+E+E+EA+E+E+E+B0+E+E+EA+E+E+E+B0+D+D+DA+D+D+D-F0+C+C+C#D+C+C+CA0+C+C+C#D+C+C+CA0+D+D+DD+D+D+D-E0+C+C+CE+C+C+C#G0BBBEBBB#G0BBBEBBB-E0BBBEBBB#G0BBBEBBB#G0BBBEBBB-A0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+EB0+D+D+DE+D+D+D-A0+#C+#C+#CE0+#C+#C+#CA0+#C+#C+#CE0+#C+#C+#CB0+D+D+DE+D+D+D-A0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E-A0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E-A0+#F+#F+#F#F0+#F+#F+#F+D0+#F+#F+#F#F0+#F+#F+#F+D0+#F+#F+#F#F0+#F+#F+#F-A0+D+D+DD+D+D+DB0+D+D+DD+D+D+DD0+#F+#F+#F#F0+#F+#F+#F-A0+#F+#F+#F-D0+#F+#F+#F+#C0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E-A0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E-#F0+A+A+A#F+A+A+AA0+A+A+A+#C+A+A+AA0+A+A+A#F+A+A+A#G0+#G+#G+#G#G0+#G+#G+#G#B0+#G+#G+#G#D0+#G+#G+#G#B0+#D+#D+#D#G0+#D+#D+#D#C0+#F+#F+#F#G0+#F+#F+#F+#C0+E+E+E#G0+E+E+E+#C0+E+E+E#G0+E+E+E#C0+E+E+E#G0+E+E+E+#C0+E+E+E#G+E+E+E+#C0+E+E+E#G+E+E+E-B0+D+D+DF+D+D+DF0+D+D+DD+D+D+DE0+D+D+DF+D+D+D-E0+#C+#C+#CE0+#C+#C+#CE0+#C+#C+#CE0+#C+#C+#C-E0BBBDBBB-A0BBBEBBBE0AAAEAAA#F0AAAGAAA-A0AAAEAAAE0AAAEAAAE0AAAEAAA-A0AAAFAAAF0AAAFAAAF0AAAFAAA-A0BBBFBBBA0+C+C+CF+C+C+CA0+D+D+DF+D+D+D-A0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E-A0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E-E0+E+E+E#G+E+E+E#G0+E+E+E#G+E+E+E#G0+E+E+E#G+E+E+E-E0+D+D+D#F+D+D+DE0+C+C+CE+C+C+C-E0BBBDBBB-A0AAAEAAAE0AAA#EAAAF0AAA#EAAA-A0AAAEAAAE0AAAEAAAE0AAAEAAA-A0AAAFAAAF0AAAFAAAF0AAAFAAA-A0BBBFBBBA0+C+C+CF+C+C+CA0+B+B+BF+B+B+B-A0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E-A0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E+#C0+E+E+EE+E+E+E-E0+#G+#G+#GE0+#G+#G+#G+E0+#G+#G+#GE0+#G+#G+#G+E0+#G+#G+#GE0+#G+#G+#G-E0+#F+#F+#FE0+#F+#F+#F+#C0+E+E+EE+E+E+EB0+D+D+DE+D+D+D-A0+#C+#C+#CE0+#C+#C+#CA0+#C+#C+#CE0+#C+#C+#C#F0+#C+#C+#CA0+#C+#C+#C-A0+#C+#C+#CE0+#C+#C+#CA0+#C+#C+#C-E0+#C+#C+#C-#B0+#C+#C+#C#C0+#C+#C+#C-A0+#C+#C+#CE0+#C+#C+#CA0+#C+#C+#C-E0+#C+#C+#C-#B0+#C+#C+#C#C0+#C+#C+#C-A3EA+#C+E+A+E8A7R7" set baseTime to 0.25 set (musList of spd) to characters of (musStr of spd) set octV to 0 –Ave Octave set defaultNote to {octave:0, noteStr:missing value, sharpF:missing value, flatF:missing value, noteLength:missing value} copy defaultNote to curNote set prevNoteLength to -1 set (mmlList of spd) to {} repeat with i in (musList of spd) set j to contents of i considering case if j = "-" then if noteStr of curNote is not equal to missing value then set the end of (mmlList of spd) to curNote set prevNoteLength to noteLength of curNote copy defaultNote to curNote set (noteLength of curNote) to prevNoteLength set octave of curNote to -1 else set octave of curNote to -1 end if else if j = "+" then if noteStr of curNote is not equal to missing value then set the end of (mmlList of spd) to curNote set prevNoteLength to noteLength of curNote copy defaultNote to curNote set (noteLength of curNote) to prevNoteLength set octave of curNote to 1 else set octave of curNote to 1 end if (* else if j = "b" then –Flat if noteStr of curNote is not equal to missing value then set the end of mmlList to curNote set prevNoteLength to noteLength of curNote copy defaultNote to curNote set (noteLength of curNote) to prevNoteLength else set flatF of curNote to true end if *) else if j = "#" then –Sharp if noteStr of curNote is not equal to missing value then set the end of (mmlList of spd) to curNote set prevNoteLength to noteLength of curNote copy defaultNote to curNote set (noteLength of curNote) to prevNoteLength else set sharpF of curNote to true end if else if j is in {"C", "D", "E", "F", "G", "A", "B", "R"} then if noteStr of curNote is not equal to missing value then set the end of (mmlList of spd) to curNote set prevNoteLength to noteLength of curNote copy defaultNote to curNote set (noteLength of curNote) to prevNoteLength end if set (noteStr of curNote) to j else if j is in noteList then set noteLength of curNote to j if noteStr of curNote is not equal to missing value then set the end of (mmlList of spd) to curNote set prevNoteLength to noteLength of curNote copy defaultNote to curNote set (noteLength of curNote) to prevNoteLength else set the end of (mmlList of spd) to curNote end if end if end considering end repeat if noteStr of curNote is not equal to missing value then set the end of (mmlList of spd) to curNote –Append Last Item –return mmlList –Play set engine to current application’s MPMonoSoundEngine’s alloc()’s init() engine’s start() repeat with i in (mmlList of spd) set j to contents of i set curOctave to octave of j set curOctaveStr to encodeOctave(curOctave) of me set sharpFlag to sharpF of j set flatFlag to flatF of j set sfStr to encodeSharpAndFlat(sharpFlag, flatFlag) of me set noteLenStr to noteLength of j set noteLenTime to (bDict’s valueForKey:noteLenStr) as real set noteString to noteStr of j if noteString = "R" then engine’s |stop|() (current application’s NSThread’s sleepForTimeInterval:(((noteLenTime * baseTime)) as real)) –delay (noteLenTime * baseTime) / 2 engine’s start() else set noteKey to curOctaveStr & sfStr & noteString try set noteFreq to (aDict’s valueForKey:noteKey) as real on error engine’s |stop|() return end try (engine’s channel’s setFrequency:noteFreq) –(engine’s rightChannel()’s setFrequency:noteFreq) (current application’s NSThread’s sleepForTimeInterval:(((noteLenTime * baseTime)) as real)) end if end repeat engine’s |stop|() on encodeSharpAndFlat(sharpF, flatF) if {sharpF, flatF} = {missing value, missing value} then return "" if {sharpF, flatF} = {true, missing value} then return "#" if {sharpF, flatF} = {missing value, true} then return "b" if {sharpF, flatF} = {true, true} then error "Sharp and Flat in one note" end encodeSharpAndFlat on encodeOctave(curOctave) if curOctave = 0 then set curOctaveStr to "" else if curOctave = 1 then set curOctaveStr to "+" else if curOctave = -1 then set curOctaveStr to "-" end if return curOctaveStr end encodeOctave |
これも同じく、8bitコンピュータ時代のクロスアセンブラが出力していたダンプリストを、BASICのPOKE文に展開して出力するという、20〜30年前の仕様のテキスト変換を行うために作ったものです。
CotEditorでオープン中のダンプリストのテキストの変換対象行を選択しておいた状態で実行すると、変換したリストを新規書類に出力します。
AppleScript名:HexDump to BASIC.scpt |
— – Created by: Takaaki Naganoya – Created on: 2023/01/09 — – Copyright © 2023 Piyomaru Software, All Rights Reserved — tell application "CotEditor" tell front document set aaSel to paragraphs of contents of selection end tell end tell set sNum to 100 set allText to "" repeat with i in aaSel set tmpL to "" set bList to words of i set aStr to retOnLineBasicPoke(bList) of me set allText to allText & ((sNum as string) & ": ") & aStr & return set sNum to sNum + 1 end repeat tell application "CotEditor" set newDoc to make new document tell newDoc set contents of it to allText end tell end tell on retOnLineBasicPoke(aList) set addrStr to first item of aList set aList to rest of aList set aaList to items 1 thru 8 of aList set aStr to "POKE #0, &" & addrStr & ", " repeat with i in aaList set j to contents of i set aStr to aStr & "&" & j & ", " end repeat return text 1 thru -3 of aStr end retOnLineBasicPoke |
これ、8bitコンピュータ時代のクロスアセンブラが出力していたIntel Hexaフォーマットのダンプリスト(EPROMライター向けの出力フォーマットらしい)を、BASICのPOKE文に展開して出力するという、20〜30年前の仕様のテキスト変換を行うために作ったものです。
CotEditorでオープン中のIntel Hexaのテキストの変換対象行を選択しておいた状態で実行すると、変換したリストを新規書類に出力します。
汎用性は一切ないのですが、実際にさまざまな本を作る際に、こうした「ちょっとしたツール」を作るのと作らないのとでは生産性が段違いです。
ただ、元データと最終成果物を示すと途中のロジックをプログラム側で考えて出力してくれるといいのに、とは思います。
AppleScript名:Intel Hexa to BASIC.scpt |
— – Created by: Takaaki Naganoya – Created on: 2023/01/09 — – Copyright © 2023 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" use scripting additions use framework "Foundation" tell application "CotEditor" tell front document set aaSel to paragraphs of contents of selection end tell end tell set sNum to 100 set allText to "" repeat with i in aaSel set tmpL to "" set j to contents of i set {addrStr, hexList} to procOneLine(j) of me set aStr to retOnLineBasicPoke(addrStr, hexList) of me set allText to allText & ((sNum as string) & " ") & aStr & return set sNum to sNum + 1 end repeat tell application "CotEditor" set newDoc to make new document tell newDoc set contents of it to allText end tell end tell on retOnLineBasicPoke(addrStr, aList) set aStr to "POKE #0, &" & addrStr & ", " repeat with i in aList set j to contents of i set aStr to aStr & "&" & j & ", " end repeat return text 1 thru -3 of aStr end retOnLineBasicPoke on procOneLine(a) set fChar to first character of a if fChar is not equal to ":" then error set byteC to text 2 thru 3 of a set byteNum to retIntFromHexString(byteC) of me set addrStr to text 4 thru 7 of a set hList to {} repeat with i from 10 to (10 + (2 * (byteNum – 1))) by 2 set tmpStr to text i thru (i + 1) of a set the end of hList to tmpStr end repeat return {addrStr, hList} end procOneLine on retIntFromHexString(aHex as string) set {aRes, hexRes} to (current application’s NSScanner’s scannerWithString:aHex)’s scanHexInt:(reference) if aRes = false then return "" –エラーの場合 else return hexRes end if end retIntFromHexString |
Piymaru Softwareによる電子書籍の70冊目は、AppleScript対応アプリケーション徹底解説シリーズの第6弾。
macOS上の主要アプリケーション、FileMaker Pro、ミュージック.app、Webブラウザ、iWork(Keynote、Pages、Numbers)、CotEditorときて、ご要望の多かった「メール」(Mail.app)についてのScripting本です。macOS 13.1+Mail.app v16対応。PDF 369ページ+サンプルScript Zipアーカイブで構成されています。
→ 販売ページ
本書は、Mail.appのAppleScriptによるScriptingについて基礎からハイ・テクニックまで、詳細にまとめた決定版です。
メールの詳細な情報取得や送信、ファイル添付送信、メールのスレッドをマインドマップ風に可視化して表示したり、REST API経由で高速メール配信サービスを用いた送信まで。幅広く実用的なメール関連のAppleScriptのノウハウをご紹介しています。
ずいぶん時間をかけて書いた本で、あとから企画が出た数冊の本が追い抜いていました。CotEditor本も、あとから企画したものの、あちらが先に完成しました。とにかくアプリケーションの規模が大きく、機能が多く、試しておくべき機能が多いので、とにかく時間がかかるんですね。実際、年末年始も書いていました。
以前から(2004年ぐらいから)受信メールのサブフォルダへの再仕分けScriptを運用しており、いまも利用していますが、これを添付しています。
また、選択したメールスレッドのマインドマップ形式の可視化Scriptも、別途アプリケーションをインストールしなくても利用できるものを添付しています。
SendGridのREST APIを呼び出して超高速にメール送信を行うScriptは、あんまり速いので腰が抜けるほどですが、これも一見の価値あるものでしょう。
Numbersの表に入れたデータをもとに、メールの文面にデータを差し込んで送信するScriptも添付しているので、年末年始のごあいさつなどに威力を発揮することでしょう。
スクリプトエディタを起動しよう
スクリプトエディタを起動しよう!
スクリプトエディタのヘルプ
色設定を変えてみよう!
スクリプトを入力してみよう
スクリプトを保存しよう
スクリプトを実行しよう(1/2)
スクリプトを実行しよう(2/2)
セキュリティとプライバシー
プライバシーとセキュリティ(13.x以降)
セキュリティとプライバシー>プライバシー
プライバシーとセキュリティ(macOS 13)
メール.appを起動しよう
メール(Mail.app)を指定
メール.appを起動
メール.appを終了
メール.appのAppleScript用語辞書の調べ方
メニュー項目や画面強制操作の調べ方
メール.appの詳細仕様について
メール.appの情報を取得しよう
メール.appの名前を取得
メール.appのバージョンを取得
メール.appのプロパティ項目と内容(1/2)
メール.appのプロパティ項目と内容(2/2)
選択中のメールボックス、メールを取得
selected mainboxes=選択中のメールボックス
selected messages=選択中のメール
selection=選択中のメッセージを取得
メールボックスのプロパティ項目と内容
メール情報の取得
メッセージ(メール)の内容を取得
メッセージ(メール)のソースを取得
メッセージ(メール)の各種情報を取得
メッセージのプロパティ項目と内容
メッセージのプロパティ項目と内容
メッセージのプロパティ項目と内容
条件に合ったメールの抽出
条件に合うメッセージを取得
メールアカウント情報
メールアカウントは複数存在可能
accountオブジェクトの詳細情報を取得
アカウントのプロパティ項目と内容①
アカウントのプロパティ項目と内容②
メールアドレスを取り出す
文字列からメールアドレスと氏名を抽出
選択中のメッセージからメールアドレスと氏名を抽出
シグネチャ(署名)
設定>署名で「署名」を管理
署名から情報を取得
アプリケーションの選択中署名情報
署名の属性値の書き換え(名称、本文)
スクリプトメニューからの操作
スクリプトメニューからの操作①
スクリプトメニューからの操作②
スクリプトメニューからの操作③
プリントアウト
メール.appから印刷出力(GUI側)
AppleScriptによる印刷
AppleScript(GUI Scripting)による印刷
アカウントを指定しての新着メール確認
メールアカウント種類ごとのメール確認
新着メール確認スケジュールの設定/停止
SMTPサーバー
SMTPサーバー情報の取得
指定アカウントのSMTPサーバー設定を切り替え
SMTPサーバーのプロパティ項目と内容
新規メール作成
メッセージの新規作成
メール送信
メッセージの新規作成+送信
GUI側で作成していたメールの送信①
GUI側で作成していたメールの送信②
添付ファイルつきメール送信
メッセージの新規作成+ファイル添付+送信
メッセージの新規作成+アーカイブファイル添付+送信①
メッセージの新規作成+アーカイブファイル添付+送信②
メールの添付ファイルを処理
選択中のメールの添付ファイルを保存
選択中のメールの添付ファイルの種別を集計①
選択中のメールの添付ファイルの種別を集計②
選択中のメールに添付ファイルがあれば背景色を赤く変更
メール返信
選択中のメールへの返信①
選択中のメールへの返信②
メール転送(Forward)
選択中のメールの転送(forward)①
選択中のメールへの転送②
メールのリダイレクト
選択中のメールの非破壊転送(redirect)①
メールボックスへのアクセス
特別なメールボックスのオブジェクト
特別なメールボックスへのアクセス
アカウント毎の特別なメールボックスへのアクセス
メールフォルダのパス情報
メールボックスのパス表記
選択中のメールボックスのフルパスを取得
フルパス文字列でメールボックスを指定
メールのフォルダ間の移動
メールの指定①
メールの指定②
メールのコピー
メールの移動
ビューアウィンドウの操作
メール.appのウィンドウ種別
ビューアウィンドウ操作
message viewerのプロパティ項目と内容①
message viewerのプロパティ項目と内容②
メールのルールを扱う
受信メールから条件実行するアクション「ルール」
「ルール」の「AppleScriptを実行」環境
テンプレートのメール.app用プラグインScript
ルールにAppleScript側からアクセス
ルールの「条件」にアクセスするrule condition
rule conditionとGUI上の内容との対比
ルールの「操作」の内容にアクセス
ルール「操作」の詳細にアクセス
URL Eventの発生/受信
メール.appが対応しているURLイベント
mailto: URLイベント(概要)
mailto: URLイベントを発生してメール作成
message: ローカルのメールのURLを求めて表示
メールヘッダー情報の取得
メッセージヘッダーの内容を取得
メッセージ(メール)のヘッダーを取得
ヘッダーの構成例
ヘッダーからフィールド名一覧を取得
メーラー名(x-mailer)を集計
メールスレッドの可視化
スレッドの可視化①
スレッドの可視化②選択中のメール情報
スレッドの可視化③各メールヘッダ情報
スレッドの可視化④.dotデータの作成
スレッドの可視化⑤.dotデータを表示
メーリングリストの振り分け先フォルダを抽出する
メーリングリストを処理するルールを抽出
メッセージ移動先がないルールを抽出
メールの再仕分け
「メールの再仕分け」とは?
「メールの再仕分け」Script変更履歴
「メールの再仕分け」Script処理概要
「メールの再仕分け」Script①
「メールの再仕分け」Script②
「メールの再仕分け」Script③
「メールの再仕分け」Script④
「メールの再仕分け」Script⑤
「メールの再仕分け」Script⑥
「メールの再仕分け」Script⑦
「メールの再仕分け」Script⑧
スタイル付きテキストのメール作成+データ差し込み
スタイル付きメールを作成するために
書式スタイル付きメールを作成
HTMLからスタイル付きメールを作成
RTFからスタイル付きメールを作成①
RTFからスタイル付きメールを作成②
Numbers上のデータをもとにさしこみメール作成
データ差し込みメール送信【概要】
データ差し込みメール送信①
データ差し込みメール送信②
データ差し込みメール送信③
データ差し込みメール送信④
高速・大量メール送信
高速メール配信サービスの利用
高速メール配信サービス一覧
SendGridのAPI Key取得までの道①
SendGridのAPI Key取得までの道②
SendGridのAPI Key取得までの道②
SendGridによるメール配信テスト(メール.app)
SendGridによるメール配信テスト(メール.app)
メール.appによるメール配信プログラム(SendGrid使用)
REST APIによるメール高速配信プログラム
SendGridを用いたメール送信所要時間(500通)
メール.appで大量送信後のメモリの状態
ランタイム環境の選択
AppleScriptの実行環境はたくさんある
実行中に止まる、落ちるという場合には
メール.appのAppleScript用語辞書解説
メール.app用語辞書
メール.appのAppleScript用語の変遷
メール.app用語辞書の変遷
メール.app&AppleScript Q&A
AppleScriptに関するQ&A❶
AppleScriptに関するQ&A❷
AppleScript mini Reference
macOS搭載 AppleScript関連ドキュメント
AppleScript関連の情報源
macOSバージョンとAppleScriptの動向
macOSとAppleScriptの要素技術史
各macOSごとのAppleScript解説(2/4)
各macOSごとのAppleScript解説(3/4)
各macOSごとのAppleScript解説(4/4)
macOS内AppleScript補助ツールの歴史
System EventsのAppleScript用語辞書変更点
AppleScript 各ランタイム環境情報
AppleScript 関連ツール
Cocoa Scripting 関連ツール
AppleScript予約語一覧
サードパーティ製FrameworkやAppleScript Librariesを呼ぶ
Script BundleにFramework / AppleScript Librariesを入れる
Shane StanleyのScript Toolの変遷
Shane StanleyのScript Libraries
Piyomaru SoftwareのScript Libraries (1/2)
Piyomaru SoftwareのScript Libraries (2/2)
エラーコード表
AppleScriptのエラーコード
AppleScript Errors
Mac OS Errors
AppleEvent Errors (1/2)
AppleEvent Errors (2/2)
OSA Errors
あとがき
2022年に使用していたmacOS:macOS 12→13
毎年行なっている、Piyomaru Softwareが書いたAppleScriptの1年を振り返る記事の2022年版です。
→ 2018年に書いた価値あるAppleScript
→ 2019年に書いた価値あるAppleScript
→ 2020年に書いた価値あるAppleScript
→ 2021年に書いた価値あるAppleScript
2022年も大変な1年でした。macOSやApple純正アプリケーションのバグが発生したり治ったりのジェットコースター状態。macOS 13.0についても「冗談だよね?」という出来で、
「もう、OSがアップデートされて半年ぐらい待たないとリリース状態にならないのかも?」
と感じるものです。
13.1でずいぶんまともになりましたが、13.1の出来になってからリリースすべきなのでは? というところ。
たいした追加機能がない割にバグがその数十倍もてんこもりについてくるのは、どうなんでしょう? Appleは機能を開発しているのではなく、もはや「いやがらせのための機能」や「新たなバグ」を開発しているメーカーであるように感じます。β版の段階で開発者/ユーザーが検証して「この新たな嫌がらせの機能は納得できない」とフィードバックしないと、延々と嫌がらせのための機能が増えてくるので、油断できません。
macOS 13のシステム設定も、警告音のフォルダにサウンド以外のAppleScript書類を入れても警告音一覧にそれが出てきてしまうので(さすがに再生はできない)初心者が作るへっぽこアプリケーション並みの作りになっていることが見て取れます。
今年執筆した書籍はおよそ、41冊。いま書いている「Mail.app Scripting Book With AppleScript」が年内に書きあがれば(無理無理無理無理)42冊。
ピークの4月は1か月間に8冊。3日に1冊のペースで出していました。感想やら何やら事前に読んでいただいているEdama2さんのご協力に感謝しています。本当にありがとうございます。
「基礎テクニック集」は、今年あらたに立ち上げた書籍シリーズで、「こういうのがないとダメなんじゃないか?」という議論の中から生まれた、基礎を重点的に解説する本です。まだ、書いていない積み残したテーマがあるので、続く感じでしょう。
「実践テクニック集」は、前述の「基礎テクニック集」ではおさまりきらない大きなテーマを扱うシリーズとして立ち上げました。「GUI Scripting」はまとめておくべき大きなテーマであり、方向性やノウハウやツールの使い方など(UI Browserなど)を徹底的に紹介しています。
そんなわけで、本ばかり書いていたので毎日KeynoteやPagesばかり使っており、これらのアプリケーションを操作するAppleScriptが必要になったら書いて作業を効率化するという繰り返し。本数はそれほど多くないものの、けっこう強力なものがそろっています。
一方で今年書いたAppleScriptで価値あるもの……といったときに、月ごとにリストアップする形式に無理を感じるようになってきたので、毎月1本といった固定形式にせず、適宜リストアップします。
・AS関連データの取り扱いを容易にする(はずの)privateDataTypeLib
オブジェクトからデータを取り出すのにデータアクセス文字列で指定するという試みです。この手の仕組みがないと、プログラムが冗長になりがちなので用意してみようかというお話しです。
・Bundle IDで指定したアプリケーションのSDEFからコマンドを抽出テスト(指定コマンドのコマンド属性取り出し)
・Bundle IDで指定したアプリケーションのSDEFからオブジェクトを抽出
・Bundle IDで指定したアプリケーションのSDEFからXPathで指定したClassにアクセス v2
アプリケーション内蔵のAppleScript用語辞書を解釈して、Scriptを自動生成するための試みです。割とできるようになるんじゃないかと思っていますが、まだ基礎実験を行なっているだけの状態です(そういうの多いな!)
・Keynoteの表で選択中のセルの文字列長さを一覧表で表示
自分の書いた本の既刊分の説明文をKeynoteの表に入れ、文字が多いとか少ないといった「ゆらぎ」を調べるためのものです。決められたスペースに入れなくてはならないので、この手の細かい作業は割と発生し、こうした確認用Scriptをいったん作っておけば次回からはきわめて短い時間で作業できます。
・Keynote上でテキストアイテムとn重のシェープの重なりを検出 v2
ある意味、Cocoaの機能とGUIアプリケーションの機能をブレンドした内容で、GUIアプリケーションの機能だけでは実現できなかった処理です。矩形オブジェクトが2重とか3重に重なっている場合に検出するというのは、半透明のオブジェクトを重ねて何かを表現している中で生まれたものです。
・Keynote書類中のスライドのトビラページを推測する
Keynoteのマスターページの名前の分布から扉ページを推測するというものです。自分の作る本の傾向を反映させたもので、どの人でも普遍的に使用できるわけではありませんが、、、。
・RectangleBinPackを用いて2D Bin Packを解く v2.3
2D BinPackは、指定の矩形エリア内に指定の複数のオブジェクトを最適化配置して詰め込むもので、KeynoteのようなGUIアプリケーションに対して実行できるのは、非常に効果的です。
・Safariで表示中のYouTubeムービーのサムネイル画像を取得
本当は指定の再生ポジションのサムネイル画像を取得したかったのですが、まだそこまで研究が進んでいません。
・Keynoteの最前面の書類の現在のスライド上の表オブジェクトの重なり合い(2つ以上対応)を検出 v3
これは、書籍に添付しているコマンド表が重なって配置されるという「事故」から、それを検出するScriptを作成したものです。Keynoteの表オブジェクトだけでなく、他のアプリケーションの他のオブジェクトの重なり合わせも検出できることでしょう。
・書籍フォルダの階層をさかのぼって、ツメに掲載する最大チャプターを推測 v2
Pages書類が入っているフォルダの親フォルダをたどって、そのフォルダに記入されている章の数字から最大のものを計算することで、ツメ(ページ端に記載するインデックス)の大きさを変更するものです。ツメをつけると可読性が上がる本がある一方で、ツメの作成や変更を手作業で行うなんて耐えられません。そういうものこそAppleScriptで自動処理させるべきです。
・リストに入れたテキストで、冒頭に入ったマルつき数字をリナンバーする
丸つき数字のリナンバーは、つまらない内容の割に手間がかかる作業であり、これも手作業を撲滅したい内容の上位に入ってくるものです。
・与えられた自然言語テキストから言語を推測して、指定の性別で、TTSキャラクタを自動選択して読み上げ
この手の処理は、AppleScriptのコマンドレベルで普通にできてほしい内容です。ないので自分で書きましたが、macOS 13でText To SpeechキャラクタのID周りに手が入って、これも書き直さないといけないかもしれません。
・Intel MacとApple Silicon Macの速度差〜画像処理
内容はもちろんタイトルどおりですが、これでM1を集積したM1 ProであるとかM1 Ultraの処理性能がメーカー側が言うほどリニアに向上しているわけではないことがわかりました。つまり、M1よりもそれらの上位CPUの方が「処理が遅くなるものもけっこうある」ということです。ここから、M1世代でM1を集積したMac Proが出たら、相当にM1よりも遅い処理が出てくるのでは? と噂していたものですが、作ってはみたもののキャンセルされたようなので、見立て通りといったところだったのでしょう。
UI Browser 3の開発と販売が終了し、LateNight Softwareに移管された、というのが1つの大きな流れです。Swiftで書き直されたUI Browser 4についてはgithub上でオープンソースで開発が継続されています。
そして、Font Book.appがMac Catalystのアプリケーションに変更され、それにともなってAppleScript用語辞書が削除されました。これが復活するのかどうかは不明ですが、ここに新たに「Catalyst堕ち」という言葉が爆誕。Mac Catalyst化=機能低下バージョンという方針が明らかになってきました。
今年参加したコンテストはFileMaker Proの「バカスタム App選手権」。これに入賞しています。
Piyomaru Software Booksの69冊目。「CotEditor Scripting Book with AppleScript」を発売しました。PDF 343ページ+サンプルScriptZipアーカイブ で構成されています。
→ 販売ページ
アプリケーションのすべてのScriptingをわかりやすく詳細にまとめた徹底解説シリーズの第5弾。
CotEditorは(起動、動作が)速い、うまい、フリー、と3拍子そろった、Macユーザー定番のテキストエディタです。
macOS専用に作られているため、その分、macOSならではの機能を活かす方向に全振りした作りになっています。
そんなCotEditorはもちろんAppleScriptに対応しており、さまざまな作業の部品としてCotEditorを利用したり、CotEditor自体の機能をAppleScriptで追加することもできます。macOS 12以降に対応。
・スクリプトエディタを起動しよう
スクリプトエディタを起動しよう!
スクリプトエディタのヘルプ
色設定を変えてみよう!
スクリプトを入力してみよう
スクリプトを保存しよう
スクリプトを実行しよう(1/3)
スクリプトを実行しよう(2/3)
セキュリティとプライバシー
プライバシーとセキュリティ(13.x以降)
セキュリティとプライバシー>プライバシー
プライバシーとセキュリティ(macOS 13)
・CotEditorを起動しよう
CotEditorを指定
CotEditor.appを起動
CotEditor.appを終了
CotEditorのAppleScript用語辞書の調べ方
メニュー項目や画面強制操作の調べ方
CotEditorの詳細仕様について
・CotEditor自体の情報を取得しよう
CotEditorの名前を取得
CotEditorのバージョンを取得
CotEditorのプロパティ項目と内容
・オープン中の書類へのアクセス
CotEditorでオープン中の書類へのアクセス
最前面の書類、ウインドウにアクセス
documentの属性情報にアクセス
windowの属性情報にアクセス
ウインドウ関連の操作で「できない」こと
・書類の選択部分へのアクセス
selection=選択中のテキスト
selection自体のプロパティ
selection内容のテキストの取得
selection内容の書き換え
selectionの作成
・書類のスクロールとジャンプ
書類のスクロール①
書類のスクロール②
書類の指定行にジャンプ
書類の乱数行にジャンプ
・ウインドウの操作
ウインドウの属性値へのアクセス
指定ウインドウを最前面に表示
指定ウインドウの表示状態を変更
指定ウインドウをズーム表示
参考:最前面のウインドウをフルスクリーン表示
指定ウインドウのサイズを変更
・CotEditor内蔵コンソールへの文字列出力
コンソールに文字列を出力
・内蔵/OS搭載スクリプトメニューからの操作
2つのScript Menu環境
CotEditor内蔵スクリプトメニュー
macOS搭載標準スクリプトメニュー
各スクリプトメニューの技術仕様
・AppleScriptからCotEditorを操作するパターン
・ファイルのオープン
ファイルを指定して書類をオープン
複数のファイルを指定して書類をオープン
コラム「CotEditorが使用するパス表現」
・ファイルの保存
書類を指定パスに保存
書類を新規作成して本文を設定して指定パスに保存
保存済み書類に変更が加わっていたら保存
・ファイルのクローズ
書類をクローズ(with saving)
書類をクローズ(without saving)
書類をクローズ(saving ask)
新規書類をクローズ
・各種文字操作(選択範囲の操作)
change case
change kana
change roman width
shift right
shift left
move line up
move line down
sort lines
delete duplicate line
comment out
uncomment
smarten quotes
straighten quotes
smarten dashes
normalize unicode
・各種文字操作(document全体の操作)
find(1/2)
find(2/2)
replace
string
・タブ、改行コードの取り扱い
改行コードの変更タブ幅の変更
文字コードの指定
convert
reinterpret
・書式つきテキスト対応機能
CotEditorの書式つきテキスト対応機能
書式つきテキスト機能にAppleScriptからアクセス
・AppleScript非対応機能を呼び出す
AppleScriptで操作可能な範囲
GUI Scripting:メニューなどを強制操作①
GUI Scripting:メニューなどを強制操作②
GUI Scripting:メニューへのアクセス
指定ウインドウを最前面に移動
・プリントアウト
CotEditorからの印刷出力(macOS 13)
AppleScriptによるプリントアウト
GUI Scriptingによるプリントアウト①
GUI Scriptingによるプリントアウト②
GUI Scriptingによるプリントアウト③
GUI Scriptingによるプリントアウト④
GUI Scriptingによるプリントアウト⑤
正規表現
正規表現が使えるAppleScriptコマンド
findコマンド+正規表現(GUI側との対応)
replaceコマンド+正規表現(GUI側との対応)
replace サンプル①
replace サンプル②
replace サンプル③
replace サンプル④
・オープン時に縦/横書きを強制できる書類仕様
xattrコマンドで強制的に縦書き表示
・文字数のカウント
CotEditorの文字数カウント機能
AppleScriptの文字カウント
・内蔵スクリプトメニューの独自仕様
フォルダ階層構造がそのまま反映される
内蔵スクリプトメニューの独自機能
メニュー上の並び順を指定
メニュー上の区切りセパレータ表示指定
キーボードショートカットの指定
Scriptをメニューに出さない(非表示設定)
・CotEditorのAppleScript関連機能のバグ(v4.4.2)
・高度なサンプル集
AppleScriptで操作可能な範囲
最前面のウィンドウをフルスクリーン表示(1/2)
最前面のウィンドウをフルスクリーン表示(2/2)
選択範囲のテキストをhexdump(1/2)
選択範囲のテキストをhexdump(2/2)
選択範囲のカンマ区切りテキストをNumbersへ(1/2)
選択範囲のカンマ区切りテキストをNumbersへ(2/2)
選択範囲のテキストの文字比率グラフを表示(1/8)
選択範囲のテキストの使用文字比率のグラフ表示(2/8)
選択範囲のテキストの使用文字比率のグラフ表示(3/8)
選択範囲のテキストの使用文字比率のグラフ表示(4/8)
選択範囲のテキストの使用文字比率のグラフ表示(5/8)
選択範囲のテキストの使用文字比率のグラフ表示(6/8)
選択範囲のテキストの使用文字比率のグラフ表示(7/8)
選択範囲のテキストの使用文字比率のグラフ表示(8/8)
・便利な他のプログラムや周辺機器
さまざまなAppleScript呼び出しプログラムから操作①(1/2)
さまざまなAppleScript呼び出しプログラムから操作①(2/2)
さまざまなAppleScript呼び出しプログラムから操作②
さまざまなAppleScript呼び出しプログラムから操作③
さまざまなAppleScript呼び出しプログラムから操作④
・CotEditorのAppleScript用語辞書解説
・CotEditorのAppleScript用語の変遷
・CotEditor&AppleScript Q&A
・AppleScript mini Reference
・macOS搭載 AppleScript関連ドキュメント
・AppleScript関連の情報源
・macOSバージョンとAppleScriptの動向
・AppleScript予約語一覧
・サードパーティ製FrameworkやAppleScript Librariesを呼ぶ
・エラーコード表
macOS 11以降用の常駐ツール、クリップボードに入った書式つきテキストをプレーンテキスト化する「PlainerText」を開発、販売を開始しました(macOS 11以降)。
起動すると常駐し、メニューバー右側のステータスバー・エリアに「P」の絵文字を表示します。クリップボードを0.5秒ごとに監視し、スタイル付きテキストが入っていた(スタイル付きテキストをコピーした)場合にはプレーンテキストに変換して、beep音を鳴らします。
–> Download Trial Version (Work for 10 minutes)
PlainerTextはBOOTHで500円でダウンロード販売しています。
また、動作内容がわからないと安心できないという人向けに、ソースコードおよび詳細なソースコード解説書を別途販売中です。
ご注意:PlainerTextでAppleScriptの継続記号(¬)をプレーンテキスト変換されてしまうと、継続記号として認識されなくなります。ご注意ください(誤ってAppleにバグ報告してしまいましたが、自分のアプリのせいでした)。
macOS 13のリリース版でスクリプトエディタを使うと、新規書類を作成しても「保存できない」とか、作成した書類を破棄できないとか、そもそもAppletとしてエクスポートする際にCode Signを指定するとハングアップするとかいう、macOS 13β版でも発生していなかった不具合のオンパレード。
もはや「この状態で何をバグレポートしろと?」「絶対に、リリース前にチェックとか一切してないだろ」という仕上がりに、開いた口がふさがりませんでした。
macOS 13.1の正式アップデートがリリースされ、これらの挙動は解消されたように見えます。見えるのですが、macOS 12でさんざんやらかしまくったように、β版で同じようなバグをノーチェックで出してくるので、油断ができないというべきなのか、信じた奴がバカなのかという状況。
とはいえ、β版でやらかしたトンでもないバグをApple側が認識していないこともままあるので、Appleの魔の手から環境を守るためにはβ版を試さないといけないんでしょう。Appleは、OSを開発しているんでしょうか? それとも、全世界に嫌がらせをしているんでしょうか?
また、Appleがやらかしてくれたようです。あの会社はNSNotFoundの定義値を何回間違えたら気が済むんでしょうか。これで通算4回目ぐらいです。macOS 10.12で発生し10.13.1で修正された定義値のミスをまたやったわけで、失敗がまったく生かされていない。大したものです。
今回のバグは、文字列の検索処理を行っているときに発見しました。指定文字列から対象文字列の登場位置と長さをリストで返す処理を行っていたところ、NSRangeからlocationを取得したときに、これ以上見つからない場所まで来たときにNSNotFoundを返すことを期待されるわけですが、そこに前回(macOS 10.12…10.13)と同様のおかしな値を返してきました。
この(↓)AppleScriptをmacOS 13上で実行すると、エラーになります。
追記:macOS 13.1でもエラーになります。
AppleScript名:テキストのキーワード検索(結果をNSRangeのlistで返す).scptd |
— Created 2017-08-09 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" –http://piyocast.com/as/archives/4771 property NSString : a reference to current application’s NSString property NSMutableArray : a reference to current application’s NSMutableArray property NSLiteralSearch : a reference to current application’s NSLiteralSearch set aStr to "ATGC ACGT ATGC AGTC ATGC ACGT ATGC AGTC ATGC ACGT ATGC AGTC ATGC ACGT ATGC AGTC " set aRes to searchWordRanges(aStr, "ATGC") of me as list –> {{location:0, length:4}, {location:10, length:4}, {location:20, length:4}, {location:30, length:4}, {location:40, length:4}, {location:50, length:4}, {location:60, length:4}, {location:70, length:4}} on searchWordRanges(aTargText as string, aSearchStr as string) set aStr to NSString’s stringWithString:aTargText set bStr to NSString’s stringWithString:aSearchStr set hitArray to NSMutableArray’s alloc()’s init() set cNum to (aStr’s |length|()) as integer set aRange to current application’s NSMakeRange(0, cNum) repeat set detectedRange to aStr’s rangeOfString:bStr options:(NSLiteralSearch) range:aRange set aLoc to detectedRange’s location log aLoc if (detectedRange’s location) is equal to (current application’s NSNotFound) then exit repeat hitArray’s addObject:detectedRange set aNum to (detectedRange’s location) as number set bNum to (detectedRange’s |length|) as number set aRange to current application’s NSMakeRange(aNum + bNum, cNum – (aNum + bNum)) end repeat return hitArray end searchWordRanges |
症状も前回とまったく同じなので、対処も前回と同じです。Appleは定期的にNSNotFoundの定義値を間違えるトンでもない会社なので(計測された事実)、NSNotFoundまわりはAppleがバグをやらかすことを前提に書いておくべきなんでしょう。
AppleScript名:テキストのキーワード検索(結果をNSRangeのlistで返す)v2.scptd |
— Created 2017-08-09 by Takaaki Naganoya — Modified 2022-12-01 by Takaaki Naganoya — 2022 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" property NSString : a reference to current application’s NSString property NSMutableArray : a reference to current application’s NSMutableArray property NSLiteralSearch : a reference to current application’s NSLiteralSearch set aStr to "ATGC ACGT ATGC AGTC ATGC ACGT ATGC AGTC ATGC ACGT ATGC AGTC ATGC ACGT ATGC AGTC " set aRes to searchWordRanges(aStr, "ATGC") of me as list –> {{location:0, length:4}, {location:10, length:4}, {location:20, length:4}, {location:30, length:4}, {location:40, length:4}, {location:50, length:4}, {location:60, length:4}, {location:70, length:4}} –> {{location:0, |length|:4}, {location:10, |length|:4}, {location:20, |length|:4}, {location:30, |length|:4}, {location:40, |length|:4}, {location:50, |length|:4}, {location:60, |length|:4}, {location:70, |length|:4}} on searchWordRanges(aTargText as string, aSearchStr as string) set aStr to NSString’s stringWithString:aTargText set bStr to NSString’s stringWithString:aSearchStr set hitArray to NSMutableArray’s alloc()’s init() set cNum to (aStr’s |length|()) as integer set aRange to current application’s NSMakeRange(0, cNum) repeat set detectedRange to aStr’s rangeOfString:bStr options:(NSLiteralSearch) range:aRange set aLoc to detectedRange’s location –macOS 13でAppleが新たに作ったバグを回避 if (aLoc > 9.999999999E+9) or (aLoc = current application’s NSNotFound) then exit repeat hitArray’s addObject:detectedRange set aNum to (detectedRange’s location) as number set bNum to (detectedRange’s |length|) as number set aRange to current application’s NSMakeRange(aNum + bNum, cNum – (aNum + bNum)) end repeat return hitArray end searchWordRanges |
Appleと協議した結果、そこは仕様として認識していないという話で、とくに仕様を変えていないという話で平行線をたどってしまいました。
結局、書き方を少々変えることで問題そのものを「なかったこと」にする方向で決着。納得はできませんが、macOS 10.11とか10.12の時代に書いたScriptでもあり、その実行環境は手元に残っていません(macOS 10.13は何台か存在しています。macOS 11のASのCocoa呼び出しバグの検証時に活躍)。
AppleScript名:テキストのキーワード検索(結果をNSRangeのlistで返す)v3.scptd |
— Created 2017-08-09 by Takaaki Naganoya — Modified 2022-08-29 by Takaaki Naganoya — 2023 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" property NSString : a reference to current application’s NSString property NSLiteralSearch : a reference to current application’s NSLiteralSearch property NSMutableArray : a reference to current application’s NSMutableArray set aStr to "ATGC ACGT ATGC AGTC ATGC ACGT ATGC AGTC ATGC ACGT ATGC AGTC ATGC ACGT ATGC AGTC " set aRes to searchWordRanges(aStr, "ATGC") of me as list –> {{location:0, |length|:4}, {location:10, |length|:4}, {location:20, |length|:4}, {location:30, |length|:4}, {location:40, |length|:4}, {location:50, |length|:4}, {location:60, |length|:4}, {location:70, |length|:4}} on searchWordRanges(aTargText as string, aSearchStr as string) set aStr to NSString’s stringWithString:aTargText set bStr to NSString’s stringWithString:aSearchStr set hitArray to NSMutableArray’s alloc()’s init() set cNum to (aStr’s |length|()) as integer set aRange to current application’s NSMakeRange(0, cNum) repeat set detectedRange to aStr’s rangeOfString:bStr options:(NSLiteralSearch) range:aRange set aLen to (detectedRange’s |length|) as number if aLen = 0 then exit repeat hitArray’s addObject:detectedRange set aNum to (detectedRange’s location) as number set bNum to (detectedRange’s |length|) as number set aRange to current application’s NSMakeRange(aNum + bNum, cNum – (aNum + bNum)) end repeat return hitArray end searchWordRanges |
Piyomaru Software Booksの66冊目。「AppleScript基礎テクニック集(28)アプリケーションとの対話」を発売しました。PDF 35ページ+サンプルScriptZipアーカイブ で構成されています。
→ 販売ページ
AppleScriptの文法をひととおり知っていて、実際に書くことができたとしても、それだけで何かをできるというものでもありません。各種GUIアプリケーションなりOSの機能を呼び出して、なにがしかの作業を自動化できなければ意味がありません。
ここで、いきなり「いつも行っている仕事をまるごと自動化しよう!」といった壮大な野望を目指しても失敗します。マウスやトラックパッドでGUIアプリケーションを操作するのと、AppleScriptで操作するのとでは「やりかた」や「方法」は若干異なります。そこには明確に「慣れ」が必要です。
その最初の第一歩が、アプリケーションとの間の「対話」です。対話してみて、様子を見て、それでアプリケーション操作の挙動を確認していきます。対話の仕方を知ることは、自動化を行うために必須の第一関門をクリアするためのノウハウなのです。
書く前にアプリケーションとの対話が欠かせない
対話の第一歩は、正確なアプリケーション名の指定から
参考資料:名前がローカライズされているアプリケーション
最初の会話「あなたの名前は?」
最初の会話「あなたの年齢は?」
AppleScript用語辞書で会話できる言葉を調査
選択中のオブジェクトを示すselectionを調査
「selection」の意味を調べる
オブジェクト選択してselectionの動作を調査
「selection range」の意味を調べる
表を選択してselection rangeの動作を調査
選択中のオブジェクトが「何か」を尋ねる
選択中のオブジェクトが「どうか」を尋ねる
書類上のオブジェクトを作成できないか?
audio clipを作成できないか?①
audio clipを作成できないか?②
対象オブジェクトに実行できるコマンドは?①
対象オブジェクトに実行できるコマンドは?②
対象オブジェクトに実行できるコマンドは?③
処理を組み立てるには「対話」が欠かせない
macOS 13.1Betaで地味でうっとおしく、わずらわしく嫌がらせとしか思えないバグが1つ。スクリプトエディタでテンプレートから新規作成したAppleScriptが、ファイル保存も破棄もできない状態になっています。
普通に新規作成したScriptも、デフォルトでiCloud Driveに自動保存され、破棄できなかったのでiCloud Drive上のファイルを削除したら、スクリプトエディタ上の名称未設定書類を破棄できるようになりました。
作業するたびに画面上に保存も破棄もクローズもできないゾンビ状態のスクリプトエディタ書類がたまっていくのですが、これはどういう検証をしたらこういう状態になるんだか。
保存も破棄もできないスクリプトエディタ書類をGUI側からいろいろ確認してみたところ、デフォルトの保存先が「アプリケーション」フォルダになっており、それで一時ファイルも作れず、保存もできない状態になっているようです。
もう少し試して、デフォルト保存先を「アプリケーション」以外のユーザーディレクトリのどこか(デスクトップとか)に指定したら、複数あったゾンビ書類は破棄できるものも出てきたのですが、このデフォルト保存先フォルダをいろいろいじくらないと破棄できないとかいうのは、正直ダメすぎる動作だと思います。
Twitter上で@usagimaruma氏がレポートしたところにより、FinderにSiri用の隠しAppleScriptコマンド「openVirtualLocation」が存在していることが明らかになりました。
ドキュメントに載っていないFinder AppleScriptの命令を見つけた。tell構文でFinderに対して 'openVirturalLocation "AirDrop"' みたいにすると、AirDropやiCloud Driveのウインドウを直接開ける。 pic.twitter.com/SZHb8c14T7
— usagimaru ⌘ (@usagimaruma) November 19, 2022
tell application "Finder" openVirtualLocation "AirDrop" end tell
/System/Library/CoreServices/Finder.app/Contens/Applications の下にある、
といった小型アプリケーションが、上記のコマンドを利用して機能を呼び出しています。バイナリをダンプすると、”openVirtualLocation”コマンドの部分を生AppleEventsで記述してあり、少し不思議な雰囲気です。
早速、手元の環境でチェックしてみたところ、報告されたとおりに動きます。
hidden=”yes”に設定されているために、普通にFinderをsdefをスクリプトエディタで確認しただけでは表示されません。
過去にさかのぼって、どのバージョンのOSから使えるのかを確認してみたところ、
macOS 10.14:NG
macOS 10.15:NG
macOS 11.6:Exist
macOS 12.6:Exist
macOS 13.x:Exist
と、Siriの搭載とリンクしているというよりは、ショートカット.appの搭載とリンクしているように見えるので、macOS 11のFinderにこのコマンドは搭載されていないのではないか、と推測します。
CotEditor v4.4.1+macOS 13.1 Betaの組みわせで発生しているAppleScriptの問題について書いておきます。
CotEditorの内蔵スクリプトメニューから呼び出すAppleScriptは、実行プログラムがosascriptで、macOS標準搭載のスクリプトメニューと部品は同じですが、挙動や制約条件が異なります。
macOS 13+CotEditorの内蔵スクリプトメニューから呼び出すAppleScriptで、「path to me」を実行したらエラーになる現象に直面しています。
AppleScript名:mepath_without_block.scpt |
set mePath to POSIX path of (path to me) display dialog mePath as string |
ただし、解決策はすぐに見つかって、tellブロックでpath to meを囲ってあげることです。tell current applicationで囲ってあげるのが一番手っ取り早いところ。using terms from scripting additionsも使えそうです。
AppleScript名:mepath.scpt |
tell current application set mePath to POSIX path of (path to me) end tell display dialog mePath as string |
「AppleScript実践的テクニック集(1)GUI Scripting」をmacOS 13環境に合わせた内容にアップデートしました。初版の283ページから315ページに増加。初版をお買い上げの方は、購入ページから再ダウンロードすることでアップデート版を入手していただけます。
→ 販売ページ
Update:macOS 13環境に合わせた記述変更、画面キャプチャ
macOS 13環境に合わせた記述変更(背景を黄色く塗ったページ)や、画面キャプチャを再度行い、macOS 13環境でも迷わないように内容を修正しました。
Update:UI Browserについての使い方を補足
PffiddlesoftからLate Night Software, ltdに移管された、GUI Scripting必携ツール「UI Browser」についての使い方を説明する章を追加しました。
Update:システム設定の各Paneの表示Scriptを掲載
macOS 12→13への変更で各ユーザーに影響の大きい「システム環境設定」から「システム設定」への移行にともない、各設定項目を呼び出す従来のやり方が通じなくなってしまいました。
本アップデートでは、システム設定の各Paneを表示するためのAppleScriptを多数収録。すべてのPaneを表示できるようにしているほか、第2階層のUIについても選択できるようにしています。
Update:macOSとの互換性の低いアプリケーションのGUI Scripting例をご紹介
他のOS上の互換開発環境で作られた、macOSと互換性の低いアプリケーションをGUI Scriptingで操作する実例について、ご紹介しています。
macOS 13でTTS(Text To Speech)キャラクタが追加され、日本語環境では各種読み上げ機能で「O-Ren」(女性)と「Hattori」(男性)というSiriの音声が使えるようになりました。
macOS 13の「システム設定」(System Settings.app)の「アクセシビリティ」>「読み上げコンテンツ」で、「システムの声」(TTS読み上げキャラクタ)を選択、追加できるわけですが……
ただし、AppleScriptのsayコマンド(音声読み上げ、音声ファイルへのレンダリング)で、「Hattori」「O-Ren」が使えるというわけではありません。逆に、OSのサービス経由で音声名称を取得すると、
{"Kyoko", "Kyoko(拡張)", "Otoya", "Otoya(拡張)"}
などと結果が返ってくるものの、”Kyoko(拡張)”, “Otoya(拡張)”をsayコマンドで指定するとエラーになります。
say "こんにちは" using "Kyoko(拡張)" --> AppleScript Execution Error
AppleScript名:TTS Voiceを言語で抽出.scpt |
— Created 2017-03-28 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "AppKit" set aLoc to (current application’s NSLocale’s currentLocale()’s identifier()) as string –> "ja_JP" set vList to getTTSVoiceNameWithLanguage(aLoc) of me –> {"Kyoko", "Otoya"}–macOS 12まで –> {"Kyoko", "Kyoko(拡張)", "Otoya", "Otoya(拡張)"}–macOS 13 on getTTSVoiceNameWithLanguage(voiceLang) set outArray to current application’s NSMutableArray’s new() set aList to current application’s NSSpeechSynthesizer’s availableVoices() set bList to aList as list repeat with i in bList set j to contents of i set aDIc to (current application’s NSSpeechSynthesizer’s attributesForVoice:j) (outArray’s addObject:aDIc) end repeat set aPredicate to current application’s NSPredicate’s predicateWithFormat_("VoiceLocaleIdentifier == %@", voiceLang) set filteredArray to outArray’s filteredArrayUsingPredicate:aPredicate set aResList to (filteredArray’s valueForKey:"VoiceName") as list return aResList end getTTSVoiceNameWithLanguage |
TTS Voiceの環境に合わせて何かこれらのTTS Voiceのファミリー名称などを返すようにしないとダメなのかも???
AppleScript名:TTS Voiceを言語で抽出 v2.scpt |
— Created 2017-03-28 by Takaaki Naganoya — Modified 2022-11-12 by Takaaki Naganoya — 2022 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "AppKit" set aLoc to (current application’s NSLocale’s currentLocale()’s identifier()) as string –> "ja_JP" set vList to getTTSVoiceNameWithLanguage(aLoc) of me –> {"Kyoko", "Otoya"}–macOS 12まで –> {"Kyoko", "Otoya"}–macOS 13 on getTTSVoiceNameWithLanguage(voiceLang) set outArray to current application’s NSMutableArray’s new() set aList to current application’s NSSpeechSynthesizer’s availableVoices() set bList to aList as list repeat with i in bList set j to contents of i set aDIc to (current application’s NSSpeechSynthesizer’s attributesForVoice:j) (outArray’s addObject:aDIc) end repeat set aPredicate to current application’s NSPredicate’s predicateWithFormat_("VoiceLocaleIdentifier == %@", voiceLang) set filteredArray to outArray’s filteredArrayUsingPredicate:aPredicate set aResList to (filteredArray’s valueForKey:"VoiceNameRoot") –Voice Rootを取得 –要素をユニーク化 set theSet to current application’s NSOrderedSet’s orderedSetWithArray:aResList return (theSet’s array()) as list end getTTSVoiceNameWithLanguage |