Keynote書類の現在表示中のスライド上で選択中のテキストアイテム(ボックス)の内容をもとに、後続の記事トビラページのタイトルを設定するAppleScriptです。Keynote 14.3+macOS 15.4betaで動作確認していますが、とくにバージョン依存した書き方などは行なっていません。
また、本来はiWork汎用オブジェクトの座標によるソート機能をライブラリとして独立させ、バンドル形式のScript書類に入れてあったのですが、Blog掲載のためにフラットなScriptに書き換えています。
本来、Keynoteのようにスライドのインデント(レベル変更)を行って階層構造を形成できるアプリでは、それぞれのスライド(ページ)のレベルを取得したり変更できることが望ましいのですが、Keynoteの機能セットの範囲内ではAppleScriptからそのような操作は行えません。そこで、各スライドのベースレイアウトに何を用いているかによって擬似的にレベルを判定しています。
KeynoteのAppleScript対応機能はiWork Apps中では屈指の対応度を誇っていますが、レイアウトした画像の内容データにアクセスできないのと、各スライドのレベルの取得/変更が行えない点がものすごく残念です。
電子書籍「Cocoa Scripting Course」の作成用に、以前にも作ったことがあるかもしれませんが、ふたたび作ってしまいました。ちょっと大きめの書き捨てScriptです。
▲Keynote書類の章トビラ上で章の記事内容を示すテキストボックスを選択した状態で本AppleScriptを実行。複数のボックスを選択してあっても、座標値でソートして順番を決定
▲各記事のトビラページに、章トビラから取得したテキストを設定。以下、繰り返し
AppleScript名:現在のスライド上で選択中のテキストをもとに、後続の記事トビラページのタイトルに内容を設定 v2a.scptd |
— – Created by: Takaaki Naganoya – Created on: 2025/03/23 — – Copyright © 2025 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use scripting additions –use iwoSortLib : script "iWorkObjSortLib" tell application "Keynote" tell front document –章扉の上にあるテキストアイテム(各記事タイトルが入っているものと想定、複数可能)を取得 set aSelList to selection set bSelList to {} set sCount to count every slide –画面上で選択しておいたオブジェクトのうち、text itemのみを抽出(念のため) repeat with i in aSelList set j to contents of i set aClass to class of j if aClass is text item then set the end of bSelList to j end if end repeat set cSelList to sortIWorkObjectsByPositionAndRetObjRef(bSelList, {"positionX", "positionY"}, {true, true}) of iWorkObjSort –章トビラ上のテキストアイテム(複数可)をループしつつ、中のテキストを行ごとに分解してリスト化 –(連結前にあらかじめX座標をもとにソートしておいたほうがいい??) set textList to {} repeat with i in cSelList set tmpCon to object text of i set tmpList to paragraphs of tmpCon set textList to textList & tmpList end repeat –return textList –章トビラのページの情報を取得 tell current slide set curSlideNum to slide number set curSlideLayout to name of base layout end tell –章トビラの次のページの情報を取得(ここが必ず記事トビラであるという前提のもとに処理) tell slide (curSlideNum + 1) set nextSlideLayout to name of base layout end tell set targSlideList to {} repeat with i from (curSlideNum + 1) to sCount tell slide i set tSTheme to name of base layout if tSTheme = curSlideLayout then –章トビラを検出したら処理終了 exit repeat else if tSTheme = nextSlideLayout then –扉+1ページのスライド(記事カバー)を検出したら記録 set the end of targSlideList to i end if end tell end repeat –return targSlideList set iCount to 1 repeat with i in targSlideList try set tmpT to contents of item iCount of textList tell slide i set object text of default title item of it to tmpT end tell set iCount to iCount + 1 on error return end try end repeat end tell end tell –ライブラリとしてバンドル形式のAppleScript書類に組み込んでいたものをBlog掲載用に展開した script iWorkObjSort property parent : AppleScript use AppleScript use framework "Foundation" use framework "AppKit" use scripting additions script spd property aaSel : {} end script –Keynote上のiWork ObjをXY座標でソートして結果を返す(App Obj情報はitem noだけ) on sortIWorkObjectsByPosition(aaSel, sortLabelLIst, sortDirectionList) tell application "Keynote" set aVer to version if aVer < "12.0" then return tell front document set posList to {} set aCount to 1 repeat with ii in aaSel set jj to contents of ii set bClass to class of jj 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} set aCount to aCount + 1 end repeat –座標データをもとにソート set sortedList to sortRecListByLabel(posList, sortLabelLIst, sortDirectionList) of me end tell end tell return sortedList end sortIWorkObjectsByPosition –Keynote上のiWork ObjをXY座標でソートして結果を返す(App Objだけ返す) on sortIWorkObjectsByPositionIncludingObjRef(aaSel, sortLabelLIst, sortDirectionList) tell application "Keynote" set aVer to version if aVer < "12.0" then return tell front document set posList to {} set aCount to 1 repeat with ii in aaSel set jj to contents of ii set bClass to class of jj 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} set aCount to aCount + 1 end repeat –座標データをもとにソート set sortedList to sortRecListByLabel(posList, sortLabelLIst, sortDirectionList) of me –データを返す配列にiWork Object への参照を含める set sCount to 1 repeat with i from 1 to (length of aaSel) set tmpID to objID of contents of item i of sortedList set tmpObj to contents of item tmpID of aaSel set (item tmpID of sortedList) to (item tmpID of sortedList) & {objRef:tmpObj} end repeat end tell end tell return sortedList end sortIWorkObjectsByPositionIncludingObjRef –Keynote上のiWork ObjをXY座標でソートして結果を返す(App Obj入りのリストを返す) on sortIWorkObjectsByPositionAndRetObjRef(aaSel, sortLabelLIst, sortDirectionList) tell application "Keynote" set aVer to version if aVer < "12.0" then return tell front document set posList to {} set aCount to 1 repeat with ii in aaSel set jj to contents of ii set bClass to class of jj 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} set aCount to aCount + 1 end repeat –座標データをもとにソート set sortedList to sortRecListByLabel(posList, sortLabelLIst, sortDirectionList) of me –データを返す配列にiWork Object への参照を含める set sCount to 1 set retList to {} repeat with i from 1 to (length of aaSel) set tmpID to objID of contents of item i of sortedList set tmpObj to contents of item tmpID of aaSel set the end of retList to tmpObj end repeat end tell end tell return retList end sortIWorkObjectsByPositionAndRetObjRef –リストに入れたレコードを、指定の属性ラベルの値でソート 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 end script |