実際に出てきた本もあれば、出すのをストップした本もあります。
これ(↑)がそうで、作っているうちに「これ、基礎じゃなくね?」「なんか、上級者向けじゃね?」という話になって、ほとんど出来上がっていたのにストップしました。
内容は…..いい感じですし、内容も詰まっているので「基礎レベルではない」といった説明ができれば、割とそのまま(実例のコードを掲載しつつ)出してもいいとは思っています。
こんなかんじで。
こういうかんじでも。
実際に出てきた本もあれば、出すのをストップした本もあります。
これ(↑)がそうで、作っているうちに「これ、基礎じゃなくね?」「なんか、上級者向けじゃね?」という話になって、ほとんど出来上がっていたのにストップしました。
内容は…..いい感じですし、内容も詰まっているので「基礎レベルではない」といった説明ができれば、割とそのまま(実例のコードを掲載しつつ)出してもいいとは思っています。
こんなかんじで。
こういうかんじでも。
電子書籍の新刊を発売しました。新シリーズ「AppleScript基礎テクニック集」の第8巻、「環境整備」です。PDF 42ページ、スクリプトエディタ上にAppleScriptのスニペットを入力する開発支援用Script集「Piyomaru Script Assistant v2.0」つき。
→ 販売ページ
AppleScriptの開発に必要なツールはmacOSに最初から入っています。整備も何も、追加で揃える必要がありそうなのは、Late Night SoftwareのScript Debuggerのお試し版ぐらいのものです。情報として伝えるなら100文字以内で終わってしまいそうなお話です。
それでも「難しい」と感じる方がいるとすれば、それはノウハウが分散していて、どれを使うとかどれをどう設定しておくといった話がまとめられていないから、ということなんでしょう。ここに、AppleScriptの開発環境がどういうものか、詳細にご紹介いたします。
自分でマシンの管理を行えることが必要
AppleScriptの開発環境〜安定動作の平均的な環境
キーボード/マウスの選択
プリンタは?
ネット接続
複数台あったほうが便利
iPhoneと共通のiCloud設定
Apple Developper Account
スクリプトエディタ:編集、実行、書き出し
アクティビティモニタ:プロセス監視、終了
Script Debugger:統合開発環境
作業手順をまとめておく:Keynote
各種AppleScriptライブラリ
Piyomaru Script Assistant
各種AppleScript対応アプリケーション
スクリプトエディタ:構文フォーマット設定
スクリプトエディタ:ライブラリ設定
スクリプトメニュー
Finderの拡張子設定を使用環境で統一
システム環境設定
システム環境設定
定期的な再起動
定期的なディスクメンテナンス
異常プロセスの監視
電子書籍の新刊を発売しました。新シリーズ「AppleScript基礎テクニック集」の第7巻、「条件分岐(if文)」です。PDF 34ページ、掲載Scriptアーカイブつき。
→ 販売ページ
if文が書けないとプログラムを書けないも同然。自転車でいえば、カーブで曲がれ ないとか、水たまりを避けられない走り方しかできない状態です。if文で華麗なコー ナリングを決められたら、初心者レベルは超えられたことでしょう。
条件分岐ってなに?
if文による条件分岐
if文による条件分岐
if文による条件分岐
if文で気をつけるべき点
比較演算ってなに?(数値)〜同一比較
比較演算ってなに?(数値)〜大小比較
参考資料:比較演算の演算子
文字の大小比較演算
特別な文字比較を行えるオプション
特別な文字比較のサンプル
複数の条件をリストにして、is inで照合
文字を含む、始まる、終わる演算
論理の反転
参考資料:is in演算子のはたらき
参考資料:「計算機」で16→10進数変換
UnicodeのNormalizeを強制して文字比較
アプリケーションのオブジェクト同士の照合
異なるアプリケーションのオブジェクト同士の照合
電子書籍の新刊を発売しました。新シリーズ「AppleScript基礎テクニック集」の第6巻、「フィルタ参照」です。PDF 41ページ、掲載Scriptアーカイブつき。
→ 販売ページ
「フィルタ参照」はAppleScript独特の概念であり、「膨大なデータから正規表現で絞り込む」といった他の環境でありがちな方法とは異なります。
データのしぼりこみができないものと誤解されたり、説明しておく必要性をとても感じるものです。本書が好評を得られるかといった話は度外視してでも、書かないとダメという存在です。
条件に合うものを抽出するフィルタ参照①
条件に合うものを抽出するフィルタ参照②
条件に合うものを抽出するフィルタ参照③
フィルタ参照に使われる予約語
フィルタ参照の書き方
フィルタ参照の書き方
フィルタ参照の書き方
オブジェクトの各属性を指定して抽出
とくに指定しにくい属性値
フィルタ参照の傾向と対策
フィルタ参照の注意点
複数条件でしぼりこむ
開始日、終了日を指定
まとめて設定(無条件フィルタリング)
任意の項目をランダムで抽出
直接指定できない場合に、間接指定的に使う①
直接指定できない場合に、間接指定的に使う②
アプリケーションのフィルタ参照例紹介
メール(Mail)
リマインダー(Reminders)
メモ(Notes)
連絡先(Contacts)
ミュージック(Music)
Keynote
Pages
Pages:ページ中の指定サイズの文字のテキスト
Numbers
AppleScriptの環境を構成する大きな要素部品である「PFiddlesoft UI Browser」が、開発者のBill Cheesemanのリタイアに伴い、製品終了になることが2022/4/17に表明されました。
GUI Scriptingの登場と同時に、この技術を完全にカバーし、生産性を格段に向上させるツールとしてUI Browserが登場しました。これを持っているかどうかでGUI ScriptingによるScript記述は天と地ほども差が出ます。
AppleScriptを書くのであれば、まず必携といっても過言ではないというツールであったわけです。
Script DebuggerとUI Browserを柱として、AppleScript系の開発環境が構築されてきたわけで、たいへんに重要なパーツであったことは誰にも否定できないことでしょう。
Bill Cheesemanの動向は定期的にウォッチしていたのですが、「引退した法律家からプログラマに転身」「いいかげん、けっこう高齢」といった認識は持っていたものの、「PreFab Software」から改名した「PFiddlesoft」というユニット名を使っていたあたりで「誰かに引き継ぎを考えているんだろう」と(勝手に)思っていました。
ただ、C++でゴリゴリにmacOSの深いところを叩きまくるようなアクセシビリティ系のプログラムを組むことはストレスが大きかったことでしょう。Cocoaの上からAppleScriptでOSのサービスを叩いていても「またバグが」「勝手な仕様変更が」などと苛立たしいことこの上ないわけで、もっと深い部分で叩いていたら、よりストレスは大きなものとなっていたことでしょう。
正直、このあたりの技術について同等の理解と技術力を有している人間といわれると、世界でも6人ぐらいしかいないことでしょう。Shane、Mark、Sal、Has、あとはAppleの現役エンジニア(世間せまっ!)。
その割にユーザーサポートの負担なども重圧となっていたことでしょうし、Billが続けられないという英断をしたことについては尊重すべきだと考えます。
とはいえ、その大きすぎる「穴」をどうやって埋めていくかというテーマを抱えてしまっているわけです。LateNight Softwareが継承する、とかいった話は(技術的な)可能性としてありそうではあるものの、(マーケティング的かつ費用的な意味では)ちょっとわかりません。
UI Browserの代替技術、代替製品という意味では「Piyomaru Dynamic Menu Clicker」があります。メニューについていえば、「このアプリケーションのこのメニューのこの項目」と指定すると、それを強制的にクリックするような仕組みをすでに作れています。
ただ、Webブラウザ上のコンテンツをGUI Scriptingを用いて操作するような用途では、ちょっと代替手段を持っていません。
UI Browserの基礎的な部品を各種Frameworkとして提供しているものの、ちょっとAppleScriptから気軽に叩いて機能を呼び出すというのは難しそうだと思われました。
UI Browser自体、販売終了するということなので、必要な人はすぐに購入すべきでしょう。そして、Webサイトも閉じる予定とのことなので、必要な資料などをPFiddlesoftのWebサイトからダウンロードしてバックアップしておくべきでしょう。
電子書籍の新刊を発売しました。新シリーズ「AppleScript基礎テクニック集」の第5巻、「変数、プロパティ名」です。PDF 31ページ、掲載Scriptアーカイブつき。
→ 販売ページ
変数名の決め方……自分がそこで困ったり悩んだり苦しんだりしたことはないのですが、いろいろ聞いてみると意外なほど困っている様子。え、そこなの????
長い変数名、短い変数名、プロパティとグローバル変数はどこが違うの? といった聞きたいけど聞く相手がいないといった「素朴な疑問」をなるべくあぶり出して、明確になるようまとめてみました。PDF 31ページ、掲載ScriptのZipアーカイブを添付。
変数ってなに?
変数に入れられるものは?
ローカル変数とグローバル変数
変数の型ってあるの?
変数の型の確認方法は?
propertyと変数の違い(1/2)
propertyと変数の違い(2/2)
暗黙のrunハンドラ
暗黙のrunハンドラ内の変数
propertyの有効範囲=スコープ
propertyの有効範囲を超える
暗黙のrunハンドラ内の変数と各ローカル変数との衝突?
変数名の命名ルール
「予約語」と衝突しない命名を
「予約語」と衝突しない命名を
アプリケーションの予約語
AppleScriptの単語が何として認識されているか
かんたんな変数名/プロパティ名の付け方
変数/プロパティの運用の要点
スクリプトメニューやService Stationなど、「メニューやウィンドウを持たないGUIなしツール」がたくさんmacOS環境にありますが、macOS 12.4上ではこれらのAppleScript起動ツールから起動したAppleScriptから、UniformtypeIdentifiers.frameworkを用いたUTIの取得をブロックされているようです。
スクリプトメニューで実行を確認した(途中までで実行がブロックされてしまった)AppleScriptを、スクリプトエディタ上で実行したところ、問題なく実行されます。ちなみに、内容は選択した画像ファイルをPixelmator Proで超解像処理してクリップボードに設定する(コピーする)という「おかわいらしい」内容のものです。
Service Stationは、コンテクストメニューからのAppleScript実行を可能にするAppleScript実行ツールですが、これについてもしかるべきハンドラを書いて同じAppleScriptを実行させるようにしてみたものの、UTIの取得をブロックされるようです。
→ 追試で、Terminal.app上からosascript経由で実行してみたところ、UniformtypeIdentifiers.frameworkの呼び出しに失敗することが判明
明示的にMain threadで実行しないとダメ???>UniformtypeIdentifiers.framework
AppleScript名:🟧選択中の画像を超解像💝処理してコピー.scpt |
— – Created by: Takaaki Naganoya – Created on: 2021/03/25 — – Copyright © 2021 Piyomaru Software, All Rights Reserved — use AppleScript version "2.8" — Yosemite (10.10) or later use framework "Foundation" use framework "UniformtypeIdentifiers" use scripting additions property |NSURL| : a reference to current application’s |NSURL| property NSArray : a reference to current application’s NSArray property NSPredicate : a reference to current application’s NSPredicate property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey set acceptUTI to "public.image" set aFile to choose file (* tell application "Finder" set aFile to first item of (selection as alias list) end tell *) –set aUTI to getUTIFromFile(aFile) of me –選択ファイルからUTIを –display dialog aUTI –if aUTI is equal to missing value then return –set uRes to filterUTIList({aUTI}, acceptUTI) of me –選択ファイルのUTIが、受付可能UTIに含まれるかどうかチェック –if uRes is equal to {} then return –選択したファイルが画像ではなかった –掃除 tell application "Pixelmator Pro" to close every document without saving –取得した画像を超解像処理してコピー tell application "Pixelmator Pro" try open aFile on error close every document without saving return end try tell front document with timeout of 3000 seconds super resolution end timeout end tell end tell tell application "Pixelmator Pro" tell front document select all copy close without saving end tell end tell on getUTIFromFile(aFile) set aPath to POSIX path of aFile set aWS to current application’s NSWorkspace’s sharedWorkspace() set pRes to (aWS’s isFilePackageAtPath:aPath) as boolean if pRes = false then set superType to (current application’s UTTypeData) else set superType to (current application’s UTTypePackage) end if set pathString to current application’s NSString’s stringWithString:aPath set aExt to (pathString’s pathExtension()) as string set aUTType to current application’s UTType’s typeWithFilenameExtension:aExt conformingToType:(superType) set aUTIstr to aUTType’s identifier() as string return aUTIstr end getUTIFromFile –UTIリストが指定UTIに含まれているかどうか演算を行う on filterUTIList(aUTIList, aUTIstr) set anArray to NSArray’s arrayWithArray:aUTIList set aPred to NSPredicate’s predicateWithFormat_("SELF UTI-CONFORMS-TO %@", aUTIstr) set bRes to (anArray’s filteredArrayUsingPredicate:aPred) as list return bRes end filterUTIList |
Keynote v12で正常化した「selection」を用いて、選択中のshapeオブジェクトの範囲に、選択中のtext itemを指定数敷き詰めるAppleScriptです。
Keynote書類上に、敷き詰める領域を示すshapeオブジェクトを1つ、敷き詰める内容を示すtext itemオブジェクトを1つ配置し、これら2つを選択して本Scriptを実行。
選択状態で実行。
指定の最小文字サイズから最大文字サイズ(Keynote書類上で選択したtext item中の文字サイズ)までの間で乱数選択しつつ、指定個数を指定エリア中に作成します。
AppleScript名:選択中のtext itemとshapeをもとにtext itemを敷き詰める.scpt |
— – Created by: Takaaki Naganoya – Created on: 2022/04/15 — – Copyright © 2022 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use scripting additions property textItem : missing value property shapeItem : missing value property objMax : 200 –生成するオブジェクト(text item)の個数 property fontSizeMin : 12 –生成するオブジェクト内のobject textのフォントサイズ(これ以下のサイズは生成しない) tell application "Keynote" set aVer to (version as real) if aVer < 12 then return tell front document –書類上で選択中のオブジェクトを種別に抽出する set aaSel to selection if length of aaSel is not equal to 2 then error "You have to select one text item and one shape." repeat with i in aaSel set j to contents of i set tmpClass to class of j if tmpClass = text item and textItem = missing value then set textItem to j else if tmpClass = shape and shapeItem = missing value then set shapeItem to j end if end repeat if {textItem, shapeItem} contains missing value then error "Selected objects are not suitable" –選択されたshapeオブジェクトから情報を取得 set aPos to (position of shapeItem) set minX to item 1 of aPos set maxX to minX + (width of shapeItem) set minY to item 2 of aPos set maxY to minY + (height of shapeItem) –選択されたtext itemオブジェクトから情報を取得 set maxFSize to size of object text of textItem set oText to object text of textItem set tWidth to width of textItem set tHeight to height of textItem –shapeオブジェクトで指定された領域に、text itemを生成 repeat objMax times –座標を乱数で指定 set randomX to random number from minX to (maxX – tWidth) set randomY to random number from minY to (maxY – tHeight) –文字サイズを乱数で指定 set randomCSize to random number from fontSizeMin to maxFSize tell current slide set tmpT to make new text item with properties {object text:oText, position:{randomX, randomY}, width:tWidth, height:tHeight} at the end ignoring application responses set size of every character of object text of tmpT to randomCSize end ignoring end tell end repeat end tell end tell |
SF Symbolsに収録されている文字を、名称で指定してデスクトップにPNG画像で書き出すAppleScriptです。
同フォントは、アプリ上のアイコン素材3,300個以上をフォント化し、再利用しやすくすることで、アイコンで何かの意図を示すことを規格化したいという、現代における象形文字の再発明みたいな存在です。
文化や人種を超えた、非言語コミュニケーションを促進するための基盤としてAppleが整備を行なっているものなんでしょう。文化を縦断したインフラみたいな。
アイコン素材を自分で作るのはつらいので、正直助かっています。Appleが配布しているSF Symbols 3アプリケーションを使って画面上でいろいろ探して、文字を指定できます。
一応、SF Symbols.app自体にも指定フォントを画像化する機能はついているのですが、レンダリング時の指定解像度が低すぎて、プレゼン資料や本のイラストとして利用するには不便すぎます(本来の利用目的である、タブバーのアイコンに指定するのには向いている解像度なんでしょうけれども)。
そこで、指定のフォントの文字を名称で指定するとPNG画像にレンダリングするAppleScriptを作成してみました。
文字を指定するのはできているのですが、フォントのファミリーとかマルチカラーとかの指定の方法がよくわかりません。
AppleScript名:SF Symbolsを名称で指定してPNG画像化 v1a.scptd |
— – Created by: Takaaki Naganoya – Created on: 2022/04/14 — – Copyright © 2022 Piyomaru Software, All Rights Reserved — use AppleScript version "2.8" — Monterey (12) or later use framework "Foundation" use framework "AppKit" use framework "QuartzCore" use scripting additions set aName to "paperplane.circle.fill" set anImage to current application’s NSImage’s imageWithSystemSymbolName:(aName) accessibilityDescription:(missing value) set resImg to resizeNSImage(anImage, 50.0) of me set aDesktopPath to current application’s NSString’s stringWithString:(POSIX path of (path to desktop)) set savePath to aDesktopPath’s stringByAppendingString:((current application’s NSUUID’s UUID()’s UUIDString())’s stringByAppendingPathExtension:"png") set fRes to saveNSImageAtPathAsPNG(resImg, savePath) of me on resizeNSImage(aSourceImg, aScale) set aSize to aSourceImg’s |size|() set newWidth to (width of aSize) * aScale set newheight to (height of aSize) * aScale set targFrame to current application’s NSMakeRect(0, 0, newWidth, newheight) set targImage to current application’s NSImage’s alloc()’s initWithSize:{newWidth, newheight} set aKey to {current application’s NSImageHintInterpolation} set aObj to current application’s NSNumber’s numberWithInt:(current application’s NSImageInterpolationLow) set hintRec to current application’s NSDictionary’s dictionaryWithObject:aObj forKey:aKey targImage’s lockFocus() aSourceImg’s drawInRect:targFrame fromRect:(current application’s NSZeroRect) operation:(current application’s NSCompositeCopy) fraction:1.0 respectFlipped:true hints:hintRec targImage’s unlockFocus() return targImage end resizeNSImage –NSImageを指定パスにPNG形式で保存 on saveNSImageAtPathAsPNG(anImage, outPath) set imageRep to anImage’s TIFFRepresentation() set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep set pathString to current application’s NSString’s stringWithString:outPath set newPath to pathString’s stringByExpandingTildeInPath() set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value)) set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean return aRes –成功ならtrue、失敗ならfalseが返る end saveNSImageAtPathAsPNG |
いまひとつ、「こういう表現を行いたいんだけど、どう操作していいのかわからない」感のあるPixelmator Pro。毎回、メニューを漁っては「これ、どう作るんだろうーなー」という手探り感があります。
Photoshopで育って、どっぷりPhotoshopで画像処理を理解した人がPixelmator Proを理解するのに、敷居の高さを感じます。これ、絶対に「こういう完成物を作りたい」という人向けに「こういう手順で操作すればいい」というマニュアル的なものが必要です。
さて、Pixelmator Proの新バージョンv2.4.1が登場。機械学習を利用した人物写真の自動切り抜き機能が目玉のようです。
Student with laptop photo created by freepic.diller – www.freepik.com
おお!まつげの箇所だけちょっと切れてしまったけど、これはいい感じ!
Lookstudio – jp.freepik.com によって作成された people 写真
上半身はほぼ完璧! こーれーはすごい。
いろんなスナップ写真を切り抜かせてみましたが、人物の全身が写っているとヒット率が高いようです。つまり、おかしな箇所を切り抜かれる危険性が低くなるということです。白いTシャツが抜ける危険性が高いようで、、、
export formatに「Motion」(Motion project.)が追加された
コマンド「select subject」追加。
コマンド「smart refine selection」追加。
コマンド「remove background」追加。
エレメント「color adjustments layer」「effects layer」追加。
クラス「image layer」がコマンド「remove background」と「decontaminate colors」に応答するようになった。
クラス「group laye」に要素「color adjustments layer」「effects layer」を追加
クラス「color adjustments layer」「effects layer」を追加
コマンド「draw elliptical selection」の同義語(draw oval selection)を廃止
コマンド「resize image」の同義語(adjust size、image size)を廃止
コマンド「resize canvas」の同義語(adjust canvas、canvas size)を廃止
冒頭の人物自動切り抜きを行うAppleScriptを書いてみると、こんな感じです。Pixelmator ProのAppleScript用語辞書にもサンプルScriptが掲載されています。
AppleScript名:人物自動切り抜き.scpt |
tell application "Pixelmator Pro" tell front document remove background –v2.4.1 or later end tell end tell |
電子書籍の新刊を発売しました。新シリーズ「AppleScript基礎テクニック集」の第4巻、「AppleScript用語辞書の読み方」です。PDF 39ページ、掲載Scriptアーカイブつき。
→ 販売ページ
AppleScript用語辞書の読み方については、業務の一環として記述していても理解していない人も多いので、理解できると大きな力になる内容です。普段使っていないアプリケーションでも、AppleScriptが書きやすくなるはずです。
AppleScript用語辞書ってなに?
AppleScript用語辞書を読む前に
AppleScript用語辞書を読むために必要なもの
AppleScript用語辞書の確認方法
参考資料:えせスクリプタブルなアプリケーション一覧
AppleScript用語辞書の表示内容
AppleScript用語辞書掲載のサンプルScript
AppleScript用語辞書の生ファイルを表示
参考資料:用語辞書の生ファイルを得る意義
AppleScript用語辞書の構成要素
えせスクリプタブルな用語辞書の具体例
GUIアプリケーション操作のAppleScript記述例
アプリケーションのオブジェクト構造を調べる
document
へたくそなサンプルScriptをわかりやすく清書
より高機能なツールによる用語辞書の確認
オブジェクトのプロパティを取得して調査
オブジェクトの選択状態による結果の変化
オブジェクトのプロパティを取得して調査
複数クラスの属性を継承している場合に
オブジェクトのプロパティを変更するテスト
電子書籍の新刊を発売しました。新シリーズ「AppleScript基礎テクニック集」の第3巻、「ファイル・パス処理」です。PDF 38ページ、掲載Scriptアーカイブつき。
→ 販売ページ
本書は、まさに「基礎」中の「基礎」ともいえる「パス操作」の基礎的なサンプルを提示して段階的に紹介。最近はCocoaの機能ばかり使っているので、逆にFinderやSystem Events相手に苦労しました。
ファイル・パス関連オブジェクトの全体像
ファイルパス各形式の特徴や用途
ファイル・パス形式
ホームディレクトリのパスを取得
参考資料:path to で指定できるパラメータ
参考資料:path to temporary items
各種パス形式の変換
パスの組み立て
指定ファイルの親フォルダ(上位フォルダ)を求める
指定パスのファイル名だけを求める
指定パスの拡張子を求める
指定パスの拡張子だけを置換
指定フォルダの存在確認
指定フォルダに指定名称のファイルが存在するか確認
指定ファイルのリネーム(名称変更)
指定フォルダのリネーム(名称変更)
指定ファイルがパッケージかどうかを求める
指定パスからUTIを求める
指定パスがフォルダかどうかを求める
POSIX pathのチルダ(「~」)を展開
フルパスからチルダ(「~」)つきPOSIX pathを計算
特定パスのローカライズ名称を求める
特定パスが所属するドライブ名を求める
Keynote 12.0でまともになった「selection」を使って、選択状態にあるKeynote書類上のオブジェクト(text item)をX座標、Y座標でソートするAppleScriptです。
--> {{objID:2, positionY:219, myCon:"①①①①①", positionX:184}, {objID:4, positionY:492, myCon:"❷❷❷❷❷", positionX:184}, {objID:1, positionY:219, myCon:"③③③③③", positionX:1047}, {objID:3, positionY:492, myCon:"❹❹❹❹❹", positionX:1047}}
選択したtext itemを座標で並べ替え、内容を個別に評価してファイル書き出しするAppleScriptを別途用意して書籍作成用のツールとして、使っています。
書籍の作成作業用に作ったので、アホみたいに高機能です。text itemの内容をAppleScriptとして構文確認して、AppleScriptのオブジェクトを生成し、中間言語コードに解釈ずみの.scptファイルとして書き出しています(書籍のサンプルScript生成用)。こういうツールを作ってすぐに実戦投入できるのも、Keynoteのselectionがまともになったおかげです。
AppleScript名:選択中のオブジェクトを座標をもとにソート.scptd |
— – Created by: Takaaki Naganoya – Created on: 2022/04/09 — – Copyright © 2022 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use scripting additions tell application "Keynote" tell front document set aaSel to selection set posList to {} set aCount to 1 repeat with i in aaSel set j to contents of i set mySource to object text of j tell j set {posX, posY} to position end tell set the end of posList to {positionX:posX, positionY:posY, objID:aCount, myCon:mySource} set aCount to aCount + 1 end repeat end tell end tell set zList to sortRecListByLabel(posList, {"positionX", "positionY"}, {true, true}) of me –リストに入れたレコードを、指定の属性ラベルの値でソート on sortRecListByLabel(aRecList as list, aLabelStr as list, ascendF as list) set aArray to current application’s NSArray’s arrayWithArray:aRecList set aCount to length of aLabelStr set sortDescArray to current application’s NSMutableArray’s new() repeat with i from 1 to aCount set aLabel to (item i of aLabelStr) set aKey to (item i of ascendF) set sortDesc to (current application’s NSSortDescriptor’s alloc()’s initWithKey:aLabel ascending:aKey) (sortDescArray’s addObject:sortDesc) end repeat return (aArray’s sortedArrayUsingDescriptors:sortDescArray) as list end sortRecListByLabel |
昨日、iWork Apps(Keynote、Pages、Numbers)がVer.12.0にバージョンアップしていました。
AppleScript系ではgetコマンドが追加(Keynote、Pages)されたぐらいですが、これによって「selection」の動作がまともになりました。
前バージョンのアップデートで「スライド単位の選択」がselectionで取れなくなったことで、「何か変更しようとしている最中なんだろう」とは思っていました。予想どおりです。selection動作の空白期間を置かず、前バージョンの段階で実装されていたらもっとよかったのですが。
AppleScript対応アプリケーション、スクリプタブルなアプリケーションの世界観は、小さい世界観のものから大きい世界観のものまでいろいろです。
小さい世界観1(一番小さい):
アプリケーション起動、バージョン確認、書類のオープン、書類の印刷、アプリケーションの設定情報の確認
小さい世界観2:
小さい世界観1+アプリケーション固有のコマンドの実行
小さい世界観3:
小さい世界観2+書類やデータ作成のための機能、選択中のデータをおおまかに取得する機能
Keynote v11.xはここ
小さい世界観4:
小さい世界観3+書類上のオブジェクト作成/改変機能、選択中のデータやオブジェクトへの参照を取得する機能
Keynote v12.xはここ? まだ、Chart作成などで未サポートのグラフ形式などもあり、不完全
大きい世界観:
小さい世界観4+書類上のオブジェクトの多数を作成/改変する機能
Adobe InDesign、Word、Excel、PowerPoint、Pixelmator Proなど。かつての(v5ぐらいの)Pagesはここにいた
Keynoteでselectionを試してみたところ、何か書類上のオブジェクトを選択してselectionを実行すると、オブジェクトへの参照を(複数、リスト形式で)取れます。オブジェクトを選択した状態でなければ、書類上のどのスライドを表示中かというスライドへの参照が取得できるようです。
Keynoteにおける処理の自由度は大幅に上がりました。選択中のテキストボックスを取得できれば、その中に含まれるテキストなり書式つきテキストを取得して、書き直し、元のテキストボックスに書き戻すことができます。
選択中のイメージを取得できれば、その画像のパスを求めるかあるいはファイル名を求めて、オリジナルの画像ファイル(書類内に格納された画像、外部に存在する画像かはやってみないと)を画像フィルタ処理などを行って書き戻すといった処理が行いやすくなります。以前までのバージョンでは、選択した画像をいったんコピーしてクリップボードに格納し、そのクリップボード内の画像に対して画像処理していました。
Pagesでも、さまざまなオブジェクトへの参照がselectionによって取得できますが、あいかわらず「ページ」という概念があるんだかないんだか不明で、アプリケーションの根幹にかかわる部分なのでいまひとつ気軽に言えないところではあります。
むやみに、衝動的に本を書いているように見えるPiyomaru Software。同時にいくつも作っていると、たまたま仕上がりが近い時期に集まることはあります。
そんな中、企画を検討しては「テーマをまとめようがない」といった、企画倒れになったものもいくつもあります。
たぶん、一番ユーザー側が求めているのが、Numbersの自動化(たぶん)。しかし、Numbers自体の機能が素朴なので、Numbers書類からデータを取得したら、あとはScripter側で「配列データ」として処理しまくる、Cocoa Scriptingの見本市みたいな内容になるでしょう。実際そうなので。
AppleScriptから操作したら関数が増えるに違いない、といった「誤った期待」を抱いている人が多そうなので困り物。Excelとは完全に別モノなのにExcelと同じことをさせたがる人多数。
Numbers向けに意味があって有用なScriptを組むには、「ほとんどの処理を自前で書いてしまえる」ほどの腕前が必要になります。それは、ちょっと説明とかいうレベルではなくなってしまいますよね。
iWork系アプリケーションの中で、ユーザーから一番理解されていないアプリケーション。そして、Pages自体の機能も中途半端な印象。
おしゃれワープロなのか、DTPアプリケーションもどきなのか。そして、ページ単位の編集能力がないという理解不能な機能。
PagesのScriptingなんて説明する前に、「Pagesとはどういうアプリケーションで、何ができるのか」を説明する必要がある状態。個人的な利用率が上がっているので、悪いアプリケーションではないと思いつつも「それ、InDesignだったらいらない苦労なんじゃね?」と指摘されると何も言えない。
いろいろ考えてみたものの、これもやはりPixelmator Proでどういう結果を得るためにはどう操作したらといった「逆引き操作辞典」みたいな内容が最初にあるべき。このアプリケーションは、まずマニュアルがあるべき。使い始めると、意外と癖が強くて試行錯誤を余儀なくされる。
電子書籍の新刊を発売しました。新シリーズ「AppleScript基礎テクニック集」の第2巻、「tellブロックの整理」です。PDF 36ページ、掲載Scriptアーカイブつき。
→ 販売ページ
本書は、AppleScriptのプログラムの7割以上を占めると言われている、tellブロックの記述や整理方法についてまとめています。tellブロックの書き方が楽になれば、すなわちプログラムの7割以上の部分を楽に書けるともいえます。
tellブロックの記述は、AppleScriptのプログラミングにおいて、決して避けては通れない基礎テクニックなのです。
tellブロックの基本構造
省略表記が可能
省略表記の自動判別+自動展開
1行にまとめることも可能
変数, propertyに入れて指定
tellブロックにof itを補う必要があるケースも
it, me, AppleScript
tellブロックの分割
オブジェクト階層をサブルーチンに渡す
ちょっと凝ったtellブロック
画面上のGUI部品を強引に操作するGUI Scripting
手軽,遅い,tell文が深いGUI Scripting
tell文のネスティングを浅く書く工夫
対象アプリケーションの指定方法
アプリケーションの存在確認
アプリケーションのバージョンを検出
Spotlightでアプリケーションを検索
ご参考:Spotlight検索ライブラリをインストール
Spotlightで同じ名前のアプリケーション情報を取得
対象アプリケーションを名前以外で指定
「AppleScript最新リファレンス」は、Piyomaru Softwareでいうところの「広辞苑」「大辞典」みたいなもので、改訂しようとすると、おおごとになってしまいます。
単純にページ数だけならこれよりも巨大な本というのは割とあるんですが、要素が多くて、作るのに「決死の覚悟」が必要な1冊です。
その下に中辞典とかポケット辞典みたいな本があって、細かいテーマごとに最新のアップデートを行なっています。近頃では、「ランタイム環境」ごとの挙動の違いであるとか、制限事項といったものをまとめてみたのが割と「最新リファレンス」改訂を意識した動きです。
▲「やる必要がありそうなもの」をリストアップするとこのぐらいに。Notarization、やったことがないんですよねー。そして、やることが多すぎて嫌気が差してアップデートが頓挫するという….
何回か、最新リファレンスの改訂を思い立ったことはありますが、当時のmacOSがとても目も当てられない状況だったりして(macOS 10.13とか)、表紙だけ作ってみたり、試作品を作ってみては「いかがなものか」と見送ってきた経緯があります。
また、Cocoa Scripting Courseは「最新リファレンス」のために準備した原稿を流用して作っています。「最新リファレンス」の更新に頓挫していなければ、Cocoa Scripting Courseは出てこなかったことでしょう。
一応、理想というか妄想に近い「目標」を立てて、そこに向けて調整したり妥協したりして、たどり着く場所に漂着するというところなんでしょう。
割と「ハウツー要素」とか「入門向け要素」については別の本に肩代わりさせていますし、巨大なテーマであった「Cocoa Scripting」はCocoa Scripting Courseとして独立。OSのアップデートによる変化とか、Scriptの利用・実行環境について注目したり(WebブラウザScripting本で着手)、正直なところ500ページを超える規模の本をそうそう作っていられま…..
作っていますね(汗)。
電子書籍の新刊を発売しました。新シリーズ「AppleScript基礎テクニック集」の第1巻、「間接指定」です。PDF 36ページ、掲載Scriptアーカイブつき。
1年に15冊も書いていると、割とPiyomaru Softwareの電子書籍も数が増えてきまして……何がどういう人向けのものなのか、おおまかなマップを示してほしいという話を聞くようになりました。
「基礎」とはいっても、入門者が読むような内容ではなく、脱・初心者とか中級者(とりあえず、目的のScriptを組めるレベル)向けといったところでしょうか。
目次:
直接指定と間接指定
処理データの間接指定(配列から指定)
Unicode文字の間接指定
date(日付)オブジェクトの間接指定
ファイルパスの間接指定
参考資料:path to で指定できるパラメータ
音声読み上げキャラクタの間接指定
実行Scriptの間接指定
コマンドの間接指定
実行ハンドラ(サブルーチン)の間接指定
間接的に表同士の重なりを検出
間接的に表同士の重なりを検出
間接的にチェック範囲を検出
直接指定から間接指定に書き換えた結果
実際のScript
Keynote書類の現在のスライド(ページ)上に存在する表オブジェクトの重なり合いを検出するAppleScriptです。
前バージョンでは、複数の表オブジェクトが配置されていると、表オブジェクトの位置情報と大きさから生成したNSRect同士の重なりチェックを行なった際に、同じ表同士の重なりチェックも行なっていたので、
複数の表が存在していると、もれなく「重なっている」という警告が出てくるものでした。
本バージョンでは、同じ表同士を重なりチェックしないようにとか、1×3と3×1という「同じオブジェクト同士の重なりチェックを2度行っている」ようなものを排除しています。
今度の順列組み合わせパターン生成ルーチン「retPairPermutationsWithoutSelfCollision」では、これらのパターンを除去しています。
{{1, 2}, {1, 3}, {1, 4}, {1, 5}, {2, 3}, {2, 4}, {2, 5}, {3, 4}, {3, 5}, {4, 5}}
↑余計な組み合わせパターンは生成されなくなりました。
実際に本Scriptを用いて(複数ページ対応板)、121ページ分の表の重なり合わせチェックを行なってみたところ、M1 Mac miniで3.4秒程度です。
本Scriptの完全版を「AppleScript基礎テクニック集(1)〜間接指定」に収録しています。
AppleScript名:現在のスライド上の表オブジェクトの重なり合い(2つ以上対応)を検出 v3.scptd |
— – Created by: Takaaki Naganoya – Created on: 2022/04/03 — – Copyright © 2022 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use scripting additions tell application "Keynote" tell front document set docHeight to height tell current slide set tList to every table if length of tList < 2 then return false –複数の「表」がなかったら衝突は発生していない –表の座標とサイズによりNSRectangleを作成する set bList to {} repeat with i in tList set j to contents of i tell j set {xPos, yPos} to position set aWidth to width set aHeight to height set aRect to makeRect(xPos, yPos, aWidth, aHeight) of me end tell set the end of bList to aRect end repeat –作成したNSRectangleの順列組み合わせペア・パターンを作成して、NSRectangle同士の衝突判定を順次行う set aLen to length of bList set permuList to retPairPermutationsWithoutSelfCollision(aLen) of me set corruptList to {} repeat with i in permuList copy i to {i1, i2} set rectRes to detectRectanglesCollision(item i1 of bList, item i2 of bList) of me if rectRes = true then return true –表同士の衝突が発生している end repeat return false –表同士の衝突は発生していない end tell end tell end tell on makeRect(xPos, yPos, aWidth, aHeight) return current application’s NSMakeRect(xPos, yPos, aWidth, aHeight) end makeRect –NSRect同士の衝突判定 on detectRectanglesCollision(aRect, bRect) set a1Res to (current application’s NSIntersectionRect(aRect, bRect)) as {record, list} set tmpClass to class of a1Res if tmpClass = record then –macOS 10.10, 10.11, 10.12 return not (a1Res = {origin:{x:0.0, y:0.0}, |size|:{width:0.0, height:0.0}}) else if tmpClass = list then –macOS 10.13 or later return not (a1Res = {{0.0, 0.0}, {0.0, 0.0}}) end if end detectRectanglesCollision –1から任意の数までのアイテムで、2個ずつの組み合わせのすべての順列組み合わせパターンを計算して返す –ただし、1×1とか2×2などの同一アイテム同士の掛け合わせを除去するものとする on retPairPermutationsWithoutSelfCollision(aMax) set aList to {} repeat with x from 1 to aMax repeat with xx from 1 to aMax if x is not equal to xx then set tmpItem to {x, xx} set a2List to sort1DNumList(tmpItem, true) of me if {a2List} is not in aList then set the end of aList to a2List end if end if end repeat end repeat return aList end retPairPermutationsWithoutSelfCollision –1D List(数値)をsort / ascOrderがtrueだと昇順ソート、falseだと降順ソート on sort1DNumList(theList as list, aBool as boolean) tell current application’s NSSet to set theSet to setWithArray_(theList) tell current application’s NSSortDescriptor to set theDescriptor to sortDescriptorWithKey_ascending_(missing value, aBool) set sortedList to theSet’s sortedArrayUsingDescriptors:{theDescriptor} return (sortedList) as list end sort1DNumList |
Keynote書類の現在のスライド(ページ)上に存在する表オブジェクトの重なり合いを検出するAppleScriptです。
Cocoa Scripting Course #4のチェックを行なっていたら、表オブジェクトが重なり合っていたページがあってヘコみました(再チェック中です)。
これを自動でチェックするためのAppleScriptを書いてみました。とりあえず、現在表示しているスライド(ページ)を対象に。最終的には、開始と終了のスライドの番号を与えておくと、その間のスライドをすべてチェックできるとよいでしょう。
CocoaのNSRect同士であれば、重なり合いを検出できるので大変便利です。Keynote上の表オブジェクトから、位置情報と大きさの情報を取得すれば、簡単に目的のデータ(配列に入れたNSRect)を作れることでしょう。
ただし、NSIntersectionRectでNSRect同士の衝突検出を行えるとしても、1対1でしかチェックできないようなので、検出された表同士のすべての衝突チェック組み合わせを行うべく、順列組み合わせペア・パターンを計算する部品を急遽作って(以前作った、Permutation計算とは仕様が違うので)、2つずつ表(から作ったNSRect)を取り出して矩形座標の衝突判定を行なっています。
Keynoteの座標系は「左上」が原点座標で、Cocoaの座標系は左下のはずで….macOS 12で左上になったという話もありますが、実戦投入してみたら衝突が発生していないスライドでも衝突が検出されていたので、このあたり修正する必要があるかもしれません。
Keynoteのスライド上の表の配置状況をCocoaのNSRectで表現し、デバッグ用に画像で表示させてみました。重なりをシミュレーションするだけなら、とくに問題はなさそうです。
→ 原因がわかりました。表の座標とサイズから作ったNSRect同士を重なり合い計算するための、順列組み合わせパターン計算ルーチンで1×1とか2×2とかの「同じNSRect同士」の重なりを計算するようなパターンまで出力していたのが原因です。
つまり、現状では「複数の表オブジェクトが入っているスライド」を検出するだけの計算を行なってしまっているようです。
--> {{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5}, {3, 1}, {3, 2}, {3, 3}, {3, 4}, {3, 5}, {4, 1}, {4, 2}, {4, 3}, {4, 4}, {4, 5}, {5, 1}, {5, 2}, {5, 3}, {5, 4}, {5, 5}}
と計算してしまうところを、
--> {{1, 2}, {1, 3}, {1, 4}, {1, 5}, {2, 1}, {2, 3}, {2, 4}, {2, 5}, {3, 1}, {3, 2}, {3, 4}, {3, 5}, {4, 1}, {4, 2}, {4, 3}, {4, 5}, {5, 1}, {5, 2}, {5, 3}, {5, 4}}
のように、同じアイテム同士の組み合わせになるパターンだけを除外してあげればよかったわけです。自分で資料を作ってみてわかりました。
あとは、3×5と5×3は計算としては同じ意味なので、こういう重複パターンを除去してあげる必要があるのですが…重なりの「個数」を数えるのであるのであればともかく、重なりを「検出」するだけなら重複除去まではする必要がないでしょう。
AppleScript名:現在のスライド上の表オブジェクトの重なり合い(2つ以上対応)を検出 v2.scptd |
— – Created by: Takaaki Naganoya – Created on: 2022/04/03 — – Copyright © 2022 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use scripting additions tell application "Keynote" tell front document tell current slide set tList to every table if length of tList < 2 then return false –複数の「表」がなかったら衝突は発生していない –表の座標とサイズによりNSRectangleを作成する set bList to {} repeat with i in tList set j to contents of i tell j set {xPos, yPos} to position set aWidth to width set aHeight to height set aRect to makeRect(xPos, yPos, aWidth, aHeight) of me end tell set the end of bList to aRect end repeat –作成したNSRectangleの順列組み合わせペア・パターンを作成して、NSRectangle同士の衝突判定を順次行う set aLen to length of bList set permuList to retPairPermutations(aLen) of me set corruptList to {} repeat with i in permuList copy i to {i1, i2} set rectRes to detectRectanglesCollision(item i1 of bList, item i2 of bList) of me if rectRes = true then return true –表同士の衝突が発生している end repeat return false –表同士の衝突は発生していない end tell end tell end tell on makeRect(xPos, yPos, aWidth, aHeight) return current application’s NSMakeRect(xPos, yPos, aWidth, aHeight) end makeRect –NSRect同士の衝突判定 on detectRectanglesCollision(aRect, bRect) set a1Res to (current application’s NSIntersectionRect(aRect, bRect)) as {record, list} set tmpClass to class of a1Res if tmpClass = record then –macOS 10.10, 10.11, 10.12 return not (a1Res = {origin:{x:0.0, y:0.0}, |size|:{width:0.0, height:0.0}}) else if tmpClass = list then –macOS 10.13 or later return not (a1Res = {{0.0, 0.0}, {0.0, 0.0}}) end if end detectRectanglesCollision –1から任意の数までのアイテムで、2個ずつの組み合わせのすべての順列組み合わせパターンを計算して返す on retPairPermutations(aMax) set aList to {} repeat with x from 1 to aMax repeat with xx from 1 to aMax set tmpItem to {x, xx} if tmpItem is not in aList then set the end of aList to tmpItem end if end repeat end repeat return aList end retPairPermutations |