Keynoteでオープン中の最前面の書類の現在のスライド(ページ)の上で3重のshapeオブジェクトを下に敷いているテキストアイテムを検出し、文字色を変更するAppleScriptです。
macOS 12.5beta+Keynote v12.1の組み合わせで作成・チェックしてみましたが、Keynote v12.xの固有の機能などは使っていないので、もっと古い環境でも動くはずです。
▲処理後 右側のテキストの色まで変わってしまっているのは意図しなかった処理(わかってたけど)
Keynote書類上でshapeオブジェクトを重ねて何かを表現することはよくありますが、重ねた場所の上に置いてある文字色だけ変更したい場合が往々にしてあります。
さっさと動かすことだけ考えて、ありものの「オブジェクトの重ね合わせ検出」Scriptを使い回しました。そのため、本当に入れ子状態の3つのオブジェクトを検出しているわけではなく、重ね合わせが3回発生しているテキストアイテムを検出しています。
もうちょっと凝った処理を行えば、本当に3階層の入れ子状態のshapeを検出できそうな気はしますが、さすがに使い捨てレベルのScriptにそんなに手間暇をかけるわけにもいかないので、現状ではこんなものでしょう。
Keynoteのselectionがまともに動くようになったので、いろいろ実践的なレベルのScriptを書けるようになりましたが、オブジェクトの重ね合わせ順なども取れたりすると、もっといろいろ書けそうです。
オブジェクトのposition、width、heightを取得する処理は、もうちょっと高速に実行できるように書けそうです(まだまだ、安全第一の処理内容)。
あとは、imageオブジェクトのpathとかイメージデータそのものを取得して、各種画像フィルタをかけてKeynote書類に書き戻せるとよさそうな気がします。
AppleScript名:テキストアイテムと1重のシェープの重なり検出 v2.scptd |
— – Created by: Takaaki Naganoya – Created on: 2022/06/25 — – Copyright © 2022 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use scripting additions set collisonNum to 1 set targPointSize to 32.0 set targColList to {0, 0, 0} –Black set tList to {} –text items set trList to {} set sList to {} –shapes set srList to {} –set bgColList to {} –background color set colList to choose color tell application "Keynote" tell front document tell current slide –text itemの情報抽出ループ set allTList to every text item repeat with i in allTList 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 tList to j set the end of trList to aRect end repeat –shapeの情報抽出ループ set allSList to every shape repeat with i in allSList set j to contents of i tell j set {xPos, yPos} to position set aWidth to width set aHeight to height –set aBGCol to background color set aRect to makeRect(xPos, yPos, aWidth, aHeight) of me end tell set the end of sList to j set the end of srList to aRect set the end of bgColList to aBGCol end repeat set atLen to length of trList set arLen to length of srList set outTlist to {} –shapeと重ね合わせが発生しているtext itemの検出ループ repeat with i from 1 to atLen set atRec to contents of item i of trList set atObj to contents of item i of tList set collisionC to 0 set tmpCSize to point of first character of object text of atObj –当該text itemに対して、shapeオブジェクトとのNSRectの重ね合わせが指定数発生しているかをチェック repeat with ii from 1 to arLen set tmpRect to contents of item ii of srList set aF to detectRectanglesCollision(atRec, tmpRect) of me –背景色(background color)のリストを確認 set aBG to contents of item ii of bgColList –if {aF, aBG, tmpCSize} = {true, targColList, targPointSize} then set collisionC to collisionC + 1 if {aF, tmpCSize} = {true, targPointSize} then set collisionC to collisionC + 1 end repeat –オブジェクトのRectangleが重なり合っている「回数」で判定 if collisionC = collisonNum then set the end of outTlist to atObj end if end repeat end tell end tell end tell –文字色を塗り替えるループ tell application "Keynote" tell front document tell current slide repeat with i in outTlist set j to contents of i ignoring application responses set color of object text of j to colList end ignoring end repeat 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 |