Keynote v12.0以降でオープン中の最前面の書類の、表示中のスライド(ページ)上で選択中のグループから、その内部に収められているオブジェクトからテキストを取り出し、リスト(配列)にまとめるAppleScriptです。
▲1冊分のデータがグループにまとめられており、グループ内にオブジェクトを格納
いったんデータを組み上げた「書類」からデータを抜き出すのは、AppleScriptの重要な仕事です。各データ内のフィールドについて座標情報から自動判別するようにしていますが、座標値が想定どおりになっていない場合もあるため、これでもまだ不十分なので、相対的な位置関係(左上、右上、下 などといった)を定義してデータを取り出すようにするとよいでしょう。
……そこまで高度なものを作らなくても、文字列の長さに着目してソートしたら瞬殺でした。
AppleScript名:選択中のGroup内オブジェクトを座標でソートし、テキスト抜き出し.scpt |
use AppleScript version "2.8" use framework "Foundation" use framework "AppKit" use scripting additions property NSFont : a reference to current application’s NSFont property NSColor : a reference to current application’s NSColor property NSFontAttributeName : a reference to current application’s NSFontAttributeName property NSMutableAttributedString : a reference to current application’s NSMutableAttributedString property NSForegroundColorAttributeName : a reference to current application’s NSForegroundColorAttributeName script spd property allList : {} property aaSel : {} end script set (allList of spd) to {} tell application "Keynote" set aVer to version if aVer < "12.0" then return set acceptClass to {text item, shape} tell front document set (aaSel of spd) to selection –need Keynote v12.0 or later repeat with i in (aaSel of spd) set j to contents of i set aClass to class of j if aClass = group then tell j set gItemList to every iWork item end tell set posList to {} set aCount to 1 repeat with ii in gItemList set jj to contents of ii set bClass to class of jj if bClass is in acceptClass then tell jj set {posX, posY} to position try set tmpStr to object text as string on error set tmpStr to "" end try end tell set the end of posList to {positionX:posX, positionY:posY, objID:aCount, myStr:tmpStr} end if set aCount to aCount + 1 end repeat –座標データをもとにソート set sortedList to sortRecListByLabel(posList, {"positionY", "positionX"}, {true, true}) of me –1グループ分のテキストを組み立てる set tmpList to {} repeat with ii in sortedList set jj to contents of ii set aStr to myStr of jj set the end of tmpList to aStr end repeat set the end of (allList of spd) to tmpList end if end repeat end tell end tell return (allList of spd) –> {{"変数名", "❺", "意外と苦労している人が多い、変数やプロパティ名の命名ルール。とくに、予約語と衝突しない名前について"}, {"条件分岐", "❼", "条件分岐はプログラムに必須。自転車でいえば、カーブで曲がれないとか、水たまりを避けられないぐらい困ります。"}, {"用語辞書", "❹", "読めないと書けない、でも、あの人もこの人も読めない用語辞書。自由自在に読めれば、自由自在に書ける!"}, {"ループ処理", "➓", "プログラムをシンプルに書くための一番大事な構文。書き方によって速度が違ったり、高度な処理を簡潔に書ける!"}, {"アプレット", "⓫", "AppleScriptをアプリケーションとして書き出す、簡易アプリケーション「アプレット」の最新動向!"}, {"間接指定", "❶", "対象としたデータだけでなく、幅広いデータに対応できるよう、プログラムに柔軟性を与える間接指定"}, {"ダイアログ表示", "❾", "簡単に行えるメッセージ表示手段。外部ライブラリの利用でさらなる高機能ダイアログを紹介。"}, {"環境整備", "❽", "macOSに標準で入っているツールを呼び出しやすくしたり設定したりする程度。全体像を掴んでレッツ環境整備。"}, {"フィルタ参照", "❻", "AppleScript独特の概念で、「膨大なデータから正規表現で絞り込む」などの他の処理系と異なる、基礎にして奥義"}, {"tellブロック", "❷", "AppleScriptの7割以上を占める、tellブロックの記述や整理方法を楽に書く秘訣のかずかず"}, {"❸", "ファイルパス", "まさに「基礎」中の「基礎」。「できて当たり前」といえるパス操作。知っているだけで差がつく基礎"}} –リストに入れたレコードを、指定の属性ラベルの値でソート 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 |