Pagesで作成した書類で、プログラムリストの上に配置したタイトルのテキストを取得するAppleScriptです。
割といきあたりばったりで作ってしまったツールです。
Pagesで電子書籍を作成し、レイアウトしたAppleScriptのプログラムリストのファイル名を求めるために、プログラムリストの上に配置した白い文字で記述したテキストフレーム(Pages上ではShapeオブジェクト)を特定します。
フィルタ参照で相対座標値を表現できるといいのですが、そういうのはできないので、地道に距離計算しています。
「上」「下」という相対的な位置関係を表現するのに、結局数値比較しかできないので、どうしたものかと考えていたのですが、結局この「上」という表現は用いずじまいでした。「一番距離が近いテキストフレーム、文字色は白っぽい」だけで割と正確に特定できたので、いいだろうかというところです。相対位置関係を表記するライブラリなども作っておくといいかもしれません。
予想外の要素が、白いとだけ思っていた文字色が、RGB値では若干ゆらいでいたので、そのあたりの辻褄合わせを地味にやっています。カラードメイン(色名をラフに計算する)系のライブラリを使えば「white」などと雑な表現で指定できたかもしれません。
実際に使っているものは、本Scriptにくわえて選択中のテキストフレームの内容をAppleScriptとしてメモリ上で構文確認とコンパイルを行なって、ここで取得したファイル名でAppleScriptとして保存する処理を行なっています。
AppleScript名:Pagesで選択中のテキストボックスの一番近くにある白い文字のボックスの名前を取得.scpt |
— – Created by: Takaaki Naganoya – Created on: 2025/01/16 — – Copyright © 2025 Piyomaru Software, All Rights Reserved — use AppleScript use scripting additions use framework "Foundation" use framework "OSAKit" property |NSURL| : a reference to current application’s |NSURL| property OSANull : a reference to current application’s OSANull property NSString : a reference to current application’s NSString property OSAScript : a reference to current application’s OSAScript property OSALanguage : a reference to current application’s OSALanguage property NSFontAttributeName : a reference to current application’s NSFontAttributeName property OSALanguageInstance : a reference to current application’s OSALanguageInstance property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey tell application "Pages" tell front document set aSel to selection if aSel = {} then return set aaSel to first item of aSel set targPos to position of aaSel set targCon to object text of aaSel –選択中のtext frame(Pages上ではShape)の本文 tell current page –文字が入っているiWork objectのみが対象 set tList to every shape whose object text is not equal to targCon and object text of it is not equal to "" –オブジェクト set pList to position of every shape whose object text is not equal to targCon and object text of it is not equal to "" –座標 set cList to color of object text of every shape whose object text is not equal to targCon and object text of it is not equal to "" –文字色 end tell –クレヨンピッカーから指定しても、白色に若干の「ゆらぎ」があるようなので、数値比較で抽出 set aRes to findItemNums({65500, 65500, 65500}, cList) of me set aLen to length of aRes if aLen = 0 then display dialog "No Hit(error)" else if aLen = 1 then set tmpTarg to first item of aRes set tmpTargTextFrame to item tmpTarg of tList set oRes to object text of tmpTargTextFrame else set p2List to {} repeat with i in aRes set j to contents of i set the end of p2List to contents of item j of pList end repeat set L2ItemNums to retNearestItemByPosition({targPos}, p2List) of me set oRes to object text of (item (first item of L2ItemNums) of tList) end if end tell end tell return oRes –RGBの値がaNumにlistで入ってくる{r, g, b} –リスト中に入っている指定要素をサーチして、各チャネルの値よりも大きい場合に合致したとみなし、出現アイテム番号を返す(複数対応) on findItemNums(aNum, aList) if aList = {missing value} then return {} if aNum = {missing value} then return {} set iCount to 1 set hitF to false set hitList to {} copy aNum to {aNum1, aNum2, aNum3} repeat with i in aList set j to contents of i if j is not equal to missing value then copy j to {tmpR, tmpG, tmpB} if (tmpR > aNum1) and (tmpG > aNum2) and (tmpB > aNum3) then set the end of hitList to iCount end if end if set iCount to iCount + 1 end repeat return hitList end findItemNums on retNearestItemByPosition(L1Pos, L2Pos) set resItemNum to {} repeat with i in L1Pos set j to contents of i set iCount to 1 set tDList to {} repeat with ii in L2Pos set jj to contents of ii copy jj to {tmpX1, tmpY1} copy j to {tmpX2, tmpY2} if tmpX1 ≥ tmpX2 then set xDist to tmpX1 – tmpX2 else set xDist to tmpX2 – tmpX1 end if if tmpY1 ≥ tmpY2 then set yDist to tmpY1 – tmpY2 else set yDist to tmpY2 – tmpY1 end if set tArea to xDist * yDist set t2Area to absNum(tArea) of me set the end of tDList to {area:t2Area, itemNum:iCount} set iCount to iCount + 1 end repeat set resList to sortRecListByLabel(tDList, "area", true) of me –> {{itemNum:2, area:100}, {itemNum:3, area:1739}, {itemNum:4, area:3780}, {itemNum:1, area:4554}} set tItem to itemNum of first item of resList set the end of resItemNum to tItem end repeat return resItemNum end retNearestItemByPosition on arrangeTargItemByItemNumList(L2Pos, L2ItemNums) set L3Pos to {} repeat with i in L2ItemNums set j to contents of i set the end of L3Pos to item j of L2Pos end repeat return L3Pos end arrangeTargItemByItemNumList on absNum(q) if q is less than 0 then set q to –q return q end absNum –リストに入れたレコードを、指定の属性ラベルの値でソート on sortRecListByLabel(aRecList as list, aLabelStr as string, ascendF as boolean) set aArray to current application’s NSArray’s arrayWithArray:aRecList set sortDesc to current application’s NSSortDescriptor’s alloc()’s initWithKey:aLabelStr ascending:ascendF set sortedArray to aArray’s sortedArrayUsingDescriptors:{sortDesc} set bList to (sortedArray) as anything return bList end sortRecListByLabel |