Menu

Skip to content
AppleScriptの穴
  • Home
  • Products
  • Books
  • Docs
  • Events
  • Forum
  • About This Blog
  • License
  • 仕事依頼

AppleScriptの穴

Useful & Practical AppleScript archive. Click '★Click Here to Open This Script' Link to download each AppleScript

タグ: Keynote

新発売:AppleScript基礎テクニック集(28)アプリケーションとの対話

Posted on 11月 23, 2022 by Takaaki Naganoya

Piyomaru Software Booksの66冊目。「AppleScript基礎テクニック集(28)アプリケーションとの対話」を発売しました。PDF 35ページ+サンプルScriptZipアーカイブ で構成されています。

→ 販売ページ

AppleScriptの文法をひととおり知っていて、実際に書くことができたとしても、それだけで何かをできるというものでもありません。各種GUIアプリケーションなりOSの機能を呼び出して、なにがしかの作業を自動化できなければ意味がありません。

ここで、いきなり「いつも行っている仕事をまるごと自動化しよう!」といった壮大な野望を目指しても失敗します。マウスやトラックパッドでGUIアプリケーションを操作するのと、AppleScriptで操作するのとでは「やりかた」や「方法」は若干異なります。そこには明確に「慣れ」が必要です。

その最初の第一歩が、アプリケーションとの間の「対話」です。対話してみて、様子を見て、それでアプリケーション操作の挙動を確認していきます。対話の仕方を知ることは、自動化を行うために必須の第一関門をクリアするためのノウハウなのです。

目次

■アプリケーションとの対話で書くAppleScript【初級編】

書く前にアプリケーションとの対話が欠かせない
対話の第一歩は、正確なアプリケーション名の指定から
参考資料:名前がローカライズされているアプリケーション
最初の会話「あなたの名前は?」
最初の会話「あなたの年齢は?」

■アプリケーションとの対話で書くAppleScript【日常会話編】

AppleScript用語辞書で会話できる言葉を調査
選択中のオブジェクトを示すselectionを調査
「selection」の意味を調べる
オブジェクト選択してselectionの動作を調査
「selection range」の意味を調べる
表を選択してselection rangeの動作を調査
選択中のオブジェクトが「何か」を尋ねる
選択中のオブジェクトが「どうか」を尋ねる

■アプリケーションとの対話で書くAppleScript【上級会話編】

書類上のオブジェクトを作成できないか?
audio clipを作成できないか?①
audio clipを作成できないか?②

■アプリケーションとの対話で書くAppleScript【未知との遭遇編】

対象オブジェクトに実行できるコマンドは?①
対象オブジェクトに実行できるコマンドは?②
対象オブジェクトに実行できるコマンドは?③
処理を組み立てるには「対話」が欠かせない

Posted in Books news | Tagged 13.0savvy Keynote | Leave a comment

iWork 12.2がリリースされた

Posted on 10月 26, 2022 by Takaaki Naganoya

macOS 13がリリースされた翌日に、iWork(Keynote、Pages、Numbers) v12.2がリリースされました。
本バージョンで、AppleScriptから新規iWork書類を作成して保存させられないバグは修正されていません。

Keynote v12.2:
フォントサイズ指定が整数値(integer)から実数値(real)が指定できるように変更された

Pages v12.2:
フォントサイズ指定が整数値(integer)から実数値(real)が指定できるように変更された
AppleScript用語辞書掲載サンプルScriptで、Word書類への書き出しで「.doc」の指定が削除された(.docxのみ掲載)
→ Pages 12.2+macOS 13.1betaで連続してPages書類をオープンしてPDFを書き出していたら、どうもPDF書き出しできない場合があるようで(再起動で回復)。オープン後に少しウェイトを入れてからPDF書き出しするなど、様子を見ているところです。ファイルオープン後にASで後続のコマンドを受け付けるまでにアプリケーション内/書類内の初期化が間に合っていないのでは? と疑っています。

Numbers v12.2:
フォントサイズ指定が整数値(integer)から実数値(real)が指定できるように変更された
AppleScript用語辞書掲載サンプルScriptで、Excel書類への書き出しで「.xls」の指定が削除された(.xlsxのみ掲載)

Posted in news | Tagged 13.0savvy Keynote Numbers Pages | Leave a comment

Keynoteでオープン中の書類をすべてデスクトップにPDF書き出しして最初のページをJPEG画像化

Posted on 10月 15, 2022 by Takaaki Naganoya

Keynoteでオープン中の書類すべてをPDF書き出しして、各PDFの最初のページをJPEG画像に書き出すAppleScriptです。書き出し先はデスクトップフォルダです。Keynote v12.1+macOS 12.6.1で動作確認しています。

それぞれ、PDF書き出しするScriptと、PDFをJPEGに変換するAppleScriptは個別に書いて使っていたのですが、処理数が増えるといちいち複数のScriptをかわるがわる実行するのも面倒に。

そこで、PDF書き出し→JPEG変換を行うものを作ってみました。作ったみたといっても、部品はすでに存在していたので繋ぎ合わせただけです。

AppleScript名:すべてデスクトップ上にPDF出力し、最初のページをJPEG出力.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/10/14
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

property NSString : a reference to current application’s NSString
property NSFileManager : a reference to current application’s NSFileManager
property NSOrderedSame : a reference to current application’s NSOrderedSame

set outPathList to {}

tell application "Keynote"
  set allDocs to every document
  
if allDocs = {} then return
  
  
repeat with i in allDocs
    set j to contents of i
    
set dRes to exportKeynoteDocToPDF(j) of me
    
set pdfPath to (POSIX path of dRes)
    
set pdfPath to chkExistPOSIXpathAndIncrementChildNumberFull(pdfPath) of me
    
set jRes to (my jpegFromPath:(pdfPath) compressFactor:1.0)
    
set the end of outPathList to jRes
  end repeat
end tell

return outPathList

–Keynote書類からPDF書き出し
on exportKeynoteDocToPDF(targKeynoteDoc)
  
  
tell application "Keynote"
    set dCount to count every document
    
if dCount = 0 then
      –オープン中のKeynote書類がない場合はリターン
      
return false
    end if
    
    
set aPath to file of targKeynoteDoc
  end tell
  
  
set tmpPath to (path to desktop) as string
  
set curPath to (NSString’s stringWithString:(POSIX path of aPath))’s lastPathComponent()’s stringByDeletingPathExtension()’s stringByAppendingString:".pdf"
  
set outPath to (tmpPath & curPath)
  
set outPath to chkExistPOSIXpathAndIncrementChildNumberFull(outPath) of me
  
–do shell script "touch " & quoted form of POSIX path of outPath –Error 6を回避するための記述
  
  
tell application "Keynote"
    –set anOpt to {class:export options, export style:IndividualSlides, all stages:false, skipped slides:true, PDF image quality:Good}
    
–set anOpt to {class:export options, export style:IndividualSlides, all stages:false, skipped slides:true, PDF image quality:Better}
    
set anOpt to {class:export options, export style:IndividualSlides, all stages:false, skipped slides:true, PDF image quality:Best}
    
export targKeynoteDoc to POSIX file outPath as PDF with properties anOpt
  end tell
  
  
return ((POSIX file outPath) as alias)
end exportKeynoteDocToPDF

on jpegFromPath:imagePath compressFactor:compFactor — 0.0 = max compression, 1.0 = none
  — build destination path
  
set pathNSString to current application’s NSString’s stringWithString:imagePath
  
set destPath to pathNSString’s stringByDeletingPathExtension()’s stringByAppendingPathExtension:"jpg"
  
  
— load the file as an NSImage
  
set theImage to current application’s NSImage’s alloc()’s initWithContentsOfFile:imagePath
  
if theImage = missing value then return false
  
  
set theData to theImage’s TIFFRepresentation()
  
set newRep to current application’s NSBitmapImageRep’s imageRepWithData:theData
  
set theData to (newRep’s representationUsingType:(current application’s NSJPEGFileType) |properties|:{NSImageCompressionFactor:compFactor, NSImageProgressive:false})
  
  
set theResult to (theData’s writeToFile:destPath atomically:true) as boolean
  
return destPath as string
end jpegFromPath:compressFactor:

–POSIX path stringを与えると、ファイル名の重複を検出して、ファイル名の名称回避を行って、ファイル名のみを返す
on chkExistPOSIXpathAndIncrementChildNumberFull(a)
  set aa to POSIX path of a
  
set aStr to NSString’s stringWithString:aa
  
set bStr to aStr’s lastPathComponent()
  
  
set cStr to (bStr’s pathExtension()) as string
  
set dStr to (bStr’s stringByDeletingPathExtension()) as string
  
set eStr to (aStr’s stringByDeletingLastPathComponent()) as string
  
  
set aManager to NSFileManager’s defaultManager()
  
set aRes to (aManager’s fileExistsAtPath:aStr) as boolean
  
if aRes = false then return aa
  
  
set hitF to false
  
repeat with i from 1 to 65535
    
    
set tmpPath to (eStr & "/" & dStr & "_" & (i as string) & "." & cStr)
    
set tmpStr to (NSString’s stringWithString:tmpPath)
    
set aRes to (aManager’s fileExistsAtPath:tmpStr) as boolean
    
set bRes to ((tmpStr’s caseInsensitiveCompare:eStr) is not equal to (NSOrderedSame)) as boolean
    
    
if {aRes, bRes} = {false, true} then
      set hitF to true
      
exit repeat
    end if
    
  end repeat
  
  
if hitF = false then return false
  
  
–ファイルパス(フルパス)を返す
  
return (tmpStr as string)
end chkExistPOSIXpathAndIncrementChildNumberFull

★Click Here to Open This Script 

Posted in Image PDF | Tagged 12.0savvy Keynote | Leave a comment

新発売:AppleScript実践的テクニック集(1)GUI Scripting

Posted on 10月 10, 2022 by Takaaki Naganoya

Piyomaru Software Booksの60冊目。GUIアプリケーションを強引に動かす「GUI Scripting」について動作原理から気をつけるべき点、実戦レベルのScriptで注意している点やサンプルなどをまとめた「AppleScript実践的テクニック集(1)GUI Scripting」を発売しました。本文283ページとなっています。

→ 販売ページ

「AppleScript実践的テクニック集」とは、従来の「基礎テクニック集」の枠組みでは収まりきらないテーマを扱う新シリーズです。基礎テクニック集は32ページ前後のコンパクトな構成にするために、いろいろ省略した部分もありましたが、この枠組みに入り切らないテーマを別枠でご紹介することにしたものです。

ページ数の上限をとくに設けず、徹底的に情報を入れる設計です。それでいて、「基礎テクニック集」ゆずりの図や表を多用した構成はそのままです。

使い所さえ間違えなければ強力な武器になるGUI Scriptingについて、動作原理からノウハウ、注意すべきポイントや実戦レベルのScriptで気をつけていること、さまざまな「ありがちな処理」のサンプルなどを紹介する1冊です。

■GUI Scripting (UI Element Scripting)とは?

AS用語辞書にすべての機能は掲載されていません①
AS用語辞書にすべての機能は掲載されていません②
AppleScript非対応機能を呼ぶGUI Scripting
GUI Scriptingとは?
GUI ScriptingはSystem Eventsごしに操作
操作対象のアプリケーション①
操作対象のアプリケーション②

■AppleScript非対応機能を操作する

KeynoteでASから利用できない機能を呼ぶ
GUIアプリケーションの挙動確認が欠かせません
メニュー項目操作の実例
実行結果のリストアップ①
実行結果のリストアップ②

■GUI Scriptingの実行を許可する

デフォルト状態だとGUI Scriptingは無効
AppleScript実行アプリケーションを登録
設定するとGUI Scriptingが有効に
スクリプトメニューも登録必須
資料:macOS上のAppleScript実行環境①
資料:macOS上のAppleScript実行環境②

■GUI部品への参照を求める方法

メニュー項目:メニューを頂点としたツリー
ウィンドウ上のオブジェクト:ウィンドウが基準
簡単なGUI部品の求め方

■GUI Scriptingでやりたい特徴的な操作

GUI Scriptingの有効チェック
属性値の取得(properties)
属性値の取得(AX-attributes)
GUI部品のクリック
指定座標のクリック
参考資料:GUI Scriptingの座標系
ポップアップメニューの項目選択
キー入力操作
項目選択
コンテクストメニューの表示
スクロール操作
ファイル保存/書き出し
自分で発生させたモーダルなダイアログのクリック
ドラッグ&ドロップ操作
日本語IMの文字入力モード取得/設定

■マウスカーソルの強制移動&強制クリック

マウスカーソルを移動させる必要性
マウスカーソルの強制移動とクリック

■実戦レベルのAppleScriptにおけるGUI Scripting解説

指定フォルダ以下のPagesなどをPDF出力して連結
実際のメインScript部分
generatePDFLibの当該箇所
本プログラムが環境の影響を受けた点
参考資料:デスクトップの表示/非表示切り替え

■Accessibility Inspectorの使い方

Xcodeに入っているGUI部品探索ツール
Accessibility Inspectorの画面構成①
Accessibility Inspectorの画面構成②
プロセス一覧から対象を選択してInspection
指定プロセスのGUI部品の追跡中の画面表示
GUI部品の追跡ポーズ中の画面表示

■OSやアプリケーションのアップデートに備える

OSアップデートごとにGUI構成は変わる
GUI Scripting処理部分だけをサブルーチンに分離
GUI Scripting処理部分をライブラリに分離
OSアップデートの影響を受けにくい構造に

■GUI Scriptingの信頼性は?

GUI Scriptingの信頼性は?
一般的な信頼性の計測方法
経験に基づく傾向と対策
GUI Scriptingで直面した問題とその解決策
指定した処理の終了前に次の処理が行われる
同じ名前のプロセスが存在していると名称衝突①
同じ名前のプロセスが存在していると名称衝突②

■GUI Scriptingサンプル集

指定のアプリケーションの全メニュータイトルを取得
選択中のテキストを取得
選択中のテキストを書き換え
Safariの最前面のウィンドウへの参照を得る
GUI部品への参照から所属するアプリケーション名を取得
Dockに登録されているアイコンの情報を取得
Keynoteで選択中のテキストを縦書きに
CotEditorで最前面のウィンドウを縦書きに

■GUI Scripting資料集

click【クリック】コマンド
key code【キーコード】コマンド
keystroke【キーストローク】コマンド
perform【パフォーム】コマンド
select【セレクト】コマンド
application【アプリケーション】クラス
action【アクション】クラス
application process【アプリケーションプロセス】クラス
attribute【アトリビュート】クラス
browser【ブラウザ】クラス
busy indicator【ビジーインディケータ】クラス
button【ボタン】クラス
checkbox【チェックボックス】クラス
color well【カラーウェル】クラス
column【カラム】クラス
combo box【コンボボックス】クラス
desk accessory process【デスクアクセサリプロセス】クラス
drawer【ドロワー】クラス
group【グループ】クラス
grow area【グローエリア】クラス
image【イメージ】クラス
incrementor【インクリメンタ】クラス
list【リスト】クラス
menu【メニュー】クラス
menu bar【メニューバー】クラス
menu bar item【メニューバーアイテム】クラス
menu button 【メニューボタン】クラス
menu item 【メニューアイテム】クラス
outline 【アウトライン】クラス
pop over 【ポップオーバー】クラス
pop up button 【ポップアップボタン】クラス
process 【プロセス】クラス
progress indicator 【プログレスインジケータ】クラス
radio button 【ラジオボタン】クラス
radio group【ラジオグループ】クラス
relevance indicator【レレベンスインジケータ】クラス
row【ロー】クラス
scroll area【スクロールエリア】クラス
scroll bar 【スクロールバー】クラス
sheet 【シート】クラス
slider【スライダ】クラス
splitter【スプリッタ】クラス
splitter group【スプリッタグループ】クラス
static text【スタティックテキスト】クラス
tab group【タブグループ】クラス
table【テーブル】クラス
text area【テキストエリア】クラス
text field【テキストフィールド】クラス
toolbar【ツールバー】クラス
UI element【ユーアイエレメント】クラス
value indicator【バリューインディケータ】クラス
window【ウインドウ】クラス

■AppleScript資料集

macOSバージョンとAppleScriptの動向
macOSとAppleScriptの要素技術史
各macOSごとのAppleScript解説
macOS内AppleScript補助ツールの歴史
System EventsのAppleScript用語辞書変更点
AppleScript 各ランタイム環境情報
AppleScript予約語一覧
AppleScriptのエラーコード
あとがき
奥付

Posted in Books GUI Scripting news PRODUCTS | Tagged 12.0savvy CotEditor Keynote System Events TextEdit | Leave a comment

Keynote書類のdefault title item部分に入った改行コードを除去する

Posted on 10月 9, 2022 by Takaaki Naganoya

Keynote v12.1書類の現在のスライドにあるdefault title itemに入っている改行コード(?)を除去するAppleScriptです。

結論から言うと、これが改行コード(LFとかCRとか)ではなく、Unicode特殊文字の「LINE SEPARATOR」(U+2028)であることが、データをhexdumpしてわかりました(AppleScript書いてるだけなのに、hexdumpのお世話になることの多いこと、多いこと)。なので、文字コードをUTF-16(AppleScript側の文字コード)で指定して置換を行なっています。

# AppleScriptのネイティブ文字コードはUTF-16BEです

Keynote書類の各Slideに存在しているdefault title itemから文字列(object text)を取得し、改行コードを除去する処理を行います。

AppleScript名:default title item部分に入った改行コードを除去する.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/10/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
    tell current slide
      set jj to object text of default title item
      
      
–https://www.fileformat.info/info/unicode/char/2028/index.htm
      
–Unicode Character ’LINE SEPARATOR’ (U+2028)
      
–UTF-16 (decimal)  8,232
      
set kk to repCharByID(jj, 8232, "") of me
      
log kk
      
    end tell
  end tell
end tell

–文字置換
on repCharByID(origText as string, targCharID as number, repChar as string)
  set targChar to string id targCharID
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to targChar
  
set tmpList to text items of origText
  
set AppleScript’s text item delimiters to repChar
  
set retText to tmpList as string
  
set AppleScript’s text item delimiters to curDelim
  
return retText
end repCharByID

★Click Here to Open This Script 

Posted in Text | Tagged 12.0savvy Keynote | Leave a comment

新発売:iWork Scripting Book with AppleScript

Posted on 9月 30, 2022 by Takaaki Naganoya

Piyomaru Software Booksの59冊目。Keynote、Pages、Numbersの3つのアプリケーションのScriptingについて、共通する部分に着目して3つとも解説するScripting本、「iWork Scripting Book with AppleScript」を発売しました。本文239ページ、資料編198ページの合計437ページの大ボリウムです。

→ 販売ページ

目次

スクリプトエディタを起動しよう
スクリプトエディタを起動しよう!
スクリプトエディタのヘルプ
色設定を変えてみよう!
スクリプトを入力してみよう
スクリプトを保存しよう
スクリプトを実行しよう(1/3)
スクリプトを実行しよう(2/3)
スクリプトを実行しよう(3/3)
セキュリティとプライバシー
セキュリティとプライバシー>プライバシー
iWork appsを起動しよう
Keynote/Pages/Numbersを指定
Keynote/Pages/Numbersを起動
Keynote/Pages/Numbersを終了
Mail.appのAppleScript用語辞書の調べ方
メニュー項目や画面強制操作の調べ方
各iWork appsの詳細仕様について
iWork appsの情報を取得しよう
アプリケーションの名前を取得
アプリケーションの情報を一括取得
アプリケーションのプロパティ項目と内容
新規書類の作成
新規書類の作成
テーマ/テンプレート名の取得
テーマ/テンプレートを指定しつつ新規書類作成①
テーマ/テンプレートを指定しつつ新規書類作成②
参考資料:テーマ/テンプレート名
Keynote:SD/HD、他のサイズの書類の指定
新規スライド/ページ/シートの作成
各iWork appsにおける新規ページの作成
Keynote:レイアウト名の取得とスライド追加
Pages:ページ追加
Numbers:シート追加
書類情報の取得
書類からの各種情報取得
書類名(name)はFinder設定と連動
書類のパスワード保護状態を取得
書類保存
書類を保存(保存ずみ書類に上書き保存)
書類を新規保存①
書類を新規保存(A.)
書類を新規保存(B.)
書類を新規保存(C.)
コラム「iWork appsが使用するパス表現」
書類へのパスワード
設定と解除
iWork書類へのパスワード設定
パスワード設定されたiWork書類のオープン
書類へのパスワード設定と解除
通常書類とパスワード保護された書類の比較

■中級

書類上の座標系
書類上の座標系
Pages書類の座標系
現在表示中のページ
書類上の現在表示中のページ番号を取得
選択中のアイテムの取得
selectionで取得できる選択中のオブジェクト
Numbersで取得できる表オブジェクト情報
デフォルトタイトル
アイテムへの文字設定(Keynote)
デフォルトタイトルアイテムのオブジェクト
デフォルトタイトルアイテムのテキストを取得
デフォルトタイトルアイテムにテキストを設定
Pagesの本文作成
書類タイプ別のPages本文の作り方
Pagesの文章の本文(body text)の操作
Pagesの文章の本文(body text)の色指定
Pagesの文章の本文(body text)のフォント指定
Pagesの文章の本文(body text)の単語にアクセス
Pagesの文章のページにアクセス(追加)
Pagesの文章のページにアクセス(削除①)
Pagesの文章のページにアクセス(削除②)
Pagesの文章のセクションにアクセス
Pagesの文章のセクションにアクセス
選択中の表からのデータ取得/設定
選択範囲(selection range)へのアクセス
選択範囲のセルの取得
選択範囲のセルのデータの取得
指定セルのデータの取得①
指定セルのデータの取得②
指定範囲のセルのデータの取得
カラム名の数値からの変換
指定範囲のセルのデータを2次元配列で取得①
指定範囲のセルのデータを2次元配列で取得②
指定範囲のセルのデータを2次元配列で取得③
指定セルにデータを設定①
指定セルにデータを設定②
指定範囲のセルへの配列データの設定
表にクリップボード経由で大量の2次元配列データを設定
テキストボックスの作成
テキストボックスのオブジェクト
テキストボックスの作成
表の作成
表の作成
表の作成+データ設定
表のソート、
セルの結合と分離
表の昇順(A→Z)ソート
表の降順(Z→A)ソート
表セルの結合
結合セルの解除
画像(image)の挿入
指定画像の挿入
Keynote:イメージスライドの作成
shape, lineの作成
shape/lineの分類
shapeの識別
shapeの作成
放射状にラインを引く(Keynote)
放射状にラインを引く(Pages)
放射状にラインを引く(Numbers)
audio clip, movieの作成
音声トラックのaudio clipの作成
ムービー(movie)の作成
プレースホルダへのデータさしこみ(Pages)
プレースホルダとは?
Pagesのテキストプレースホルダの作成①
Pagesのテキストプレースホルダの作成②
Pagesのテキストプレースホルダを利用
Pagesのメディアプレースホルダの作成
Keynoteのテキストプレースホルダ
グループへのアクセス
Keynote:グループ内のオブジェクトにアクセス
Pages:グループ内のオブジェクトにアクセス
Numbers:グループ内のオブジェクトにアクセス
Keynote:グループ内のオブジェクトの親にアクセス
シート処理(Numbers)
Numbers:シートの新規追加
Numbers:シートの削除、表示切り替え
Numbers:シートの名称変更
Numbers:現在表示中のシートのIDを返す
Numbers:シートの名称による検索
スライドの追加と順次ループ(Keynote)
Keynote:スライドの追加
Keynote:スライドの順次ループアクセス
Keynote:スライドの順次追加
スライド間の表示切り替えエフェクト指定(Keynote)
Keynote:スライド切り替え効果一覧
Keynote:スライド切り替えを設定
発表者ノート(Keynote)を記入
Keynote:発表者ノートとは?
Keynote:発表者ノートの操作
表への計算式の代入
iWork appsで共通して利用できる関数
表のセルに計算式を代入
表のセルの計算結果(値)を取得
表のセルの計算式を取得
グラフ作成(Keynote)
Keynoteで扱えるグラフの一覧
Keynote:2D横/縦棒グラフ
Keynote:3D横/縦棒グラフ
Keynote:2D/3D面グラフ
Keynote:2D/3D円グラフ
Keynote:2D散布図グラフ
Keynote:2D積み重ね縦/横棒グラフ
Keynote:3D積み重ね縦/横棒グラフ
Keynote:2D/3D階層グラフ
Keynote:2D/3D折れ線グラフ
データの書き出し(エクスポート)
各iWork appsが書き出し可能なフォーマット
書き出し用ファイルパスの組み立て
PDF書き出し
Microsoft Office書類として書き出し
Keynote:HTML書き出し
Keynote:QuickTimeムービー書き出し
Keynote:イメージ書き出し
Keynote:Keynote 09形式書き出し
Pages:EPUB形式書き出し
Pages:テキスト書き出し
Pages:Pages 09形式書き出し
Pages:リッチテキストフォーマットで書き出し
Numbers:Numbers 09形式で書き出し
Numbers:CSV形式で書き出し
印刷
iWork appsから印刷出力
AppleScriptによるプリントアウト
Keynote:印刷オプションの指定
Pages:印刷オプションの指定
Numbers:印刷オプションの指定

■上級

書式付きテキストへのアクセス
Keynoteでobject textの書式属性設定
Pagesでobject textの書式属性設定
Numbersでobject textの書式属性設定
Keynoteでobject textの文字色、フォント置換
Pagesでobject textの文字色、フォント置換
Numbersでobject textの文字色、フォント置換
書式付きテキストの幅に応じたtext item自体のリサイズ
Text itemの枠の幅を文字内容でリサイズ①
Text itemの枠の幅を文字内容でリサイズ②
Text itemの枠の幅を文字内容でリサイズ①
Text itemの枠の幅を文字内容でリサイズ②
Text itemの枠の幅を文字内容でリサイズ①
Text itemの枠の幅を文字内容でリサイズ②
text item内のテキストの使用言語の自動推定
Keynote:書類中のtext itemの使用言語を推定①
Keynote:書類中のtext itemの使用言語を推定②
Pages:書類中のtext itemの使用言語を推定①
Pages:書類中のtext itemの使用言語を推定②
Numbers:書類中のtext itemの使用言語を推定①
Numbers:書類中のtext itemの使用言語を推定②
指定行列ヘッダによる表セルへのアクセス
Keynote:指定行列ヘッダによる表セルへのアクセス
Keynote:指定行列ヘッダによる表セルへのアクセス
Pages:指定行列ヘッダによる表セルへのアクセス
Pages:指定行列ヘッダによる表セルへのアクセス
Numbers:指定行列ヘッダによる表セルへのアクセス
Numbers:指定行列ヘッダによる表セルへのアクセス
汎用オブジェクト(iWork item)によるアクセス
汎用クラスiWork itemで取得できるオブジェクト
Keynote:iWork itemでアクセス
Pages:iWork itemでアクセス
Numbers:iWork itemでアクセス
オブジェクトの重なり検出(Keynote)
Keynote:テキストとshapeの重なり検出①
Keynote:テキストとshapeの重なり検出②
書類内部データへのアクセス
iWork app書類の構造
通常書類とパスワード保護された書類の比較
Keynote固有のプレゼン系操作について
Keynote:プレゼン再生コントロール
Keynote書類のプレゼン関連情報
Keynote:プレゼン再生関連の属性値
Keynote:transitionサンプル書類作成&再生

Posted in Books news | Tagged 12.0savvy Keynote Numbers Pages | Leave a comment

Bundle IDで指定したアプリケーションのSDEFからXPathで指定したClassにアクセス v2

Posted on 8月 2, 2022 by Takaaki Naganoya

Bundle IDで指定したアプリケーションのSDEF(AppleScript定義辞書)を、Xincludeを考慮しつつparseして、XPathで指定したクラスにアクセスするAppleScriptです。

KeynoteのAppleScript用語辞書の「open」コマンド、

を指定して本Scriptでデータを取り出すと、

のような出力が得られます。まだちょっと、属性値を取り出すところまで行っていませんが、つまり…指定コマンドのパラメータや、指定クラスがどのようなコマンドに応答するかなど、プログラム側からわかるようになることでしょう(多分)。

AppleScript名:Bundle IDで指定したアプリケーションのSDEFからXPathで指定したClassにアクセス v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/08/2
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

set targAppBundleID to "com.apple.iWork.Keynote" –SDEFを取り出すターゲットのアプリケーションのBundle ID
–set commandXPath to "//class[@name=’application’]/property"
–set commandXPath to "//command[@name=’open’]/direct-parameter"
–set commandXPath to "//class[@name=’document’]/property"
–set commandXPath to "//class[@name=’document’]/responds-to"
–set commandXPath to "//command[@name=’open’]" –Open Command–Open コマンド
set commandXPath to "//command[@name=’open’]/direct-parameter/type" –Open Command–Open コマンド

set aRes to parseSDEFandRetXPathData(targAppBundleID, commandXPath) of me
return aRes

–SDEFをXincludeを考慮しつつ展開
on parseSDEFandRetXPathData(targAppBundleID, commandXPath)
  set thePath to POSIX path of (path to application id targAppBundleID)
  
  
set aSDEFname to retAppSdefNameFromBundleIPath(thePath, "OSAScriptingDefinition") of me
  
if aSDEFname = false then return
  
  
if aSDEFname does not end with ".sdef" then set aSDEFname to aSDEFname & ".sdef"
  
set sdefFullPath to thePath & "Contents/Resources/" & aSDEFname
  
set sdefAlias to (POSIX file sdefFullPath) as alias –sdefのフルパスを求める
  
  
–SDEF読み込み(Xincludeの展開が必要な状態)
  
tell current application
    set theXML to read sdefAlias as «class utf8»
  end tell
  
  
–NSXMLDocumentの生成、Xincludeを有効に
  
set {theXMLDoc, theError} to current application’s NSXMLDocument’s alloc()’s initWithXMLString:theXML options:(current application’s NSXMLDocumentXInclude) |error|:(reference)
  
  
–XMLを文字データ化
  
set aDocStr to (theXMLDoc’s XMLData)
  
set aDocStr2 to (current application’s NSString’s alloc()’s initWithData:(aDocStr) encoding:(current application’s NSUTF8StringEncoding)) as string
  
  
set dRes to my extractFrom:theXMLDoc matchingXPath:commandXPath
  
return dRes
end parseSDEFandRetXPathData

–指定のNSXMLDocumentから、指定のXPathでアクセスして内容を返す
on extractFrom:theNSXMLDocument matchingXPath:theQuery
  set attStrings to {} — where attributes will be stored
  
set theXMLOutput to current application’s NSXMLElement’s alloc()’s initWithName:"output" — found nodes added to this
  
  
set {theResults, theNSError} to (theNSXMLDocument’s nodesForXPath:theQuery |error|:(reference)) — query
  
  
if theResults is not missing value then
    repeat with anNSXMLNode in (theResults as list)
      anNSXMLNode’s detach() — need to detach first
      
if anNSXMLNode’s |kind|() as integer = current application’s NSXMLAttributeKind then — see if it’s an attribute or node
        set end of attStrings to (anNSXMLNode’s stringValue()) as {text, list, record}
      else
        (theXMLOutput’s addChild:anNSXMLNode) — add node
      end if
    end repeat
    
    
return (theXMLOutput’s XMLStringWithOptions:(current application’s NSXMLNodePrettyPrint)) as {text, list, record}
  else
    return missing value
  end if
end extractFrom:matchingXPath:

–指定パスからアプリケーションのInfo.plist中の属性値を返す
on retAppSdefNameFromBundleIPath(appPath as string, aKey as string)
  set aDict to (current application’s NSBundle’s bundleWithPath:appPath)’s infoDictionary()
  
set aRes to aDict’s valueForKey:(aKey)
  
if aRes = missing value then return false
  
set asRes to aRes as string
  
  
return asRes as string
end retAppSdefNameFromBundleIPath

★Click Here to Open This Script 

Posted in sdef System XML | Tagged 10.15savvy 11.0savvy 12.0savvy Keynote | 1 Comment

Keynoteの表で選択中のセルの文字列長さを一覧表で表示

Posted on 7月 4, 2022 by Takaaki Naganoya

Keynoteの最前面の書類で表示中のスライド中の表で、選択中の各セルの内容の文字列の長さを表インタフェースで一覧表示するAppleScriptです。

こんなKeynote書類上の表があったとして、その選択中の各セルに入っている文字列の長さを、AppleScriptライブラリ「display table by list」を用いて一覧表示します。実行には同ライブラリのインストールが必要です。

実行の前提として、Keynoteで書類をオープンしてあり、書類上の表の集計対象のセルを選択しておくことが必要です。

文字列長と元の文字列を一覧表示します。

AppleScript名:Keynoteの表で選択中のセルの文字列長さを一覧表で表示.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/07/04
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.5" — El Capitan (10.11) or later
use framework "Foundation"
use scripting additions
use easyTable : script "display table by list"

tell application "Keynote"
  tell front document
    tell current slide
      try
        set theTable to first table whose class of selection range is range
      on error
        display notification "Numbers: There is no selection"
        
return
      end try
      
      
tell theTable
        set aRes to value of cells of selection range
      end tell
    end tell
  end tell
end tell

set fLabels to {"文字列長", "文字列"}

set newList to {}
repeat with i in aRes
  set j to contents of i
  
if j is not equal to missing value then
    set aLen to length of j
    
set the end of newList to {aLen, j}
  end if
end repeat

tell current application
  set aRes to (display table by list newList main message "テキストの文字列長" sub message "Keynoteの表で選択中のテキストの各セルの文字列長" size {800, 400} labels fLabels icon "")
end tell

★Click Here to Open This Script 

Posted in list Text | Tagged 10.15savvy 11.0savvy 12.0savvy Keynote | 1 Comment

Keynoteの最前面の書類で表示中のスライドで選択中の表の指定行のテキストのセルの文字列長の分布を計算

Posted on 7月 4, 2022 by Takaaki Naganoya

Keynoteの最前面の書類で表示中のスライド(ページ)で選択中の表の、指定行のテキストのセルの文字列長の分布をグラフ出力するAppleScriptです。

# Blogの英訳本の企画を動かしていますが、たしかに日本語のタイトルを(日本人が)見てもけっこうわかりにくいのかも?
# タイトルをGoogle翻訳に突っ込むと、それなりに「そんな感じじゃね?」という英語が出てきますが、、、

こういう、電子書籍の紹介文を掲載しているページがあって、そこに書いてある紹介文の長さの分布を計算してみるために、ありものの部品を組み合わせて作ったものです。

「だいたい3行ぐらい」というふんわりとしたルールのもとに18冊分ほど書いてきましたが、本の冊数が増えてページを追加するにあたって、文字列長の分布を計算してみようと思い立ってScriptを書いてみました。

043 #
044 ##
045 
046 ###
047 
048 ##
049 ###
050 #
051 #
052 #
053 
054 #
055 
056 #
057 #
058 
059 
060 
061 
062 
063 
064 
065 
066 
067 
068 #

分布はわかりましたが、似たような処理を行うことが多いので、何か簡単なGUIをつけておいたほうがいいような気がするような、、、

AppleScript名:選択中の表のデータを取得して、特定の行のデータの文字列長を集計.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/07/04
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

property NSMutableArray : a reference to current application’s NSMutableArray

set aList to get2DListFromKeynoteTableSelection() of me
if aList = "" then return false

–取得した各セルの文字列長をすべて取得する
set aLen to length of aList
set aaLen to length of item 1 of aList

set nList to {}
repeat with i from 3 to (aLen) by 3
  repeat with ii from 1 to aaLen
    set the end of nList to length of (contents of item ii of item i of aList)
  end repeat
end repeat

–文字列長の度数分布を計算
set minRes to calcMin(nList) of me
set maxRes to calcMax(nList) of me

set itemCount to maxRes – minRes
set n2List to makeBlankListByItem(itemCount + 1, 0) of me

repeat with i in nList
  set j to contents of i
  
set tmpNum to contents of item (j – minRes + 1) of n2List
  
set tmpNum to tmpNum + 1
  
set item (j – minRes + 1) of n2List to tmpNum
end repeat

–文字列長の度数分布のグラフを文字出力
set tList to {}
set aCount to minRes

repeat with i in n2List
  set gText to returnRepeatedText(i, "#") of me
  
set tNumStr to makeFN(aCount, 3) of me
  
set totalText to tNumStr & " " & gText
  
set the end of tList to totalText
  
set aCount to aCount + 1
end repeat

return retArrowText(tList, return) of me

–リストを任意のデリミタ付きでテキストに
on retArrowText(aList, aDelim)
  set aText to ""
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retArrowText

on returnRepeatedText(aNum, aChar)
  set aText to ""
  
repeat aNum times
    set aText to aText & aChar
  end repeat
  
return aText
end returnRepeatedText

on makeBlankListByItem(itemNum, blankItem)
  set tmpList to {}
  
repeat itemNum times
    set the end of tmpList to blankItem
  end repeat
  
return tmpList
end makeBlankListByItem

on calcMin(aList as list)
  set tmpFItem to first item of aList
  
set aClass to class of tmpFItem
  
  
set nArray to (NSMutableArray’s arrayWithArray:aList)
  
if aClass = real then
    set maxRes to (nArray’s valueForKeyPath:"@min.self")’s doubeValue()
  else
    set maxRes to (nArray’s valueForKeyPath:"@min.self")’s intValue()
  end if
  
  
return maxRes
end calcMin

on calcMax(aList as list)
  set tmpFItem to first item of aList
  
set aClass to class of tmpFItem
  
  
set nArray to (NSMutableArray’s arrayWithArray:aList)
  
if aClass = real then
    set maxRes to (nArray’s valueForKeyPath:"@max.self")’s doubeValue()
  else
    set maxRes to (nArray’s valueForKeyPath:"@max.self")’s intValue()
  end if
  
  
return maxRes
end calcMax

on makeFN(aNum, aDigit)
  set aText to "00000000000" & (aNum as text)
  
set aLen to length of aText
  
set aRes to text (aLen – aDigit + 1) thru -1 of aText
  
return aRes
end makeFN

–Keynoteで選択中の表のすべてのセルのデータを2Dで返す
on get2DListFromKeynoteTableSelection()
  tell application "Keynote"
    tell front document
      tell current slide
        try
          set theTable to first table whose class of selection range is range
        on error
          return "" –何も選択されてなかった場合
        end try
        
        
tell theTable
          set selList to value of every cell –すべてののデータを取得
          
set selHeight to count every row
          
set selWidth to count every column
          
        end tell
      end tell
    end tell
  end tell
  
  
set aLen to length of selList
  
set aaLen to selHeight
  
  
set bList to {}
  
repeat with i from 1 to aaLen
    set aHoriList to {}
    
    
repeat with ii from 1 to selWidth
      set j1 to ii + (i – 1) * selWidth
      
set tmpCon to contents of item j1 of selList
      
      
set aClass to class of tmpCon
      
if aClass = number or aClass = integer or aClass = real then
        set tmpCon to tmpCon as integer
      end if
      
      
set the end of aHoriList to tmpCon
    end repeat
    
    
set the end of bList to aHoriList
  end repeat
  
  
return bList
end get2DListFromKeynoteTableSelection

–テキストを指定デリミタでリスト化
on parseByDelim(aData, aDelim)
  set aText to current application’s NSString’s stringWithString:aData
  
set aList to aText’s componentsSeparatedByString:aDelim
  
return aList as list
end parseByDelim

–1D/2D Listのユニーク化
on uniquifyList(aList as list)
  set aArray to current application’s NSArray’s arrayWithArray:aList
  
set bArray to aArray’s valueForKeyPath:"@distinctUnionOfObjects.self"
  
return bArray as list
end uniquifyList

★Click Here to Open This Script 

Posted in Text | Tagged 10.15savvy 11.0savvy 12.0savvy Keynote | Leave a comment

Keynote上でテキストアイテムとn重のシェープの重なりを検出 v2

Posted on 6月 25, 2022 by Takaaki Naganoya

Keynoteでオープン中の最前面の書類の現在のスライド(ページ)の上で3重のshapeオブジェクトを下に敷いているテキストアイテムを検出し、文字色を変更するAppleScriptです。

macOS 12.5beta+Keynote v12.1の組み合わせで作成・チェックしてみましたが、Keynote v12.xの固有の機能などは使っていないので、もっと古い環境でも動くはずです。

–> Watch Demo Movie


▲処理前


▲処理後 右側のテキストの色まで変わってしまっているのは意図しなかった処理(わかってたけど)

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

★Click Here to Open This Script 

Posted in bounds list Object control | Tagged 10.15savvy 11.0savvy 12.0savvy Keynote | Leave a comment

iWork Appsがv12.1にアップデート

Posted on 6月 22, 2022 by Takaaki Naganoya

v12で発生していた、新規書類をAppleScriptから保存できないバグは修正されていません。

Posted in Bug | Tagged 10.15savvy 11.0savvy 12.0savvy Keynote Numbers Pages | Leave a comment

Keynote書類中のスライドのトビラページを推測する

Posted on 6月 5, 2022 by Takaaki Naganoya

Keynote書類中の各スライド(ページ)のベースレイアウト(テンプレート)の名称から、トビラのページを推測するAppleScriptです。

まずは、なんでトビラのページを特定する必要があるのかといえば、TOC(Table Of Contents)つきでPDFに書き出す際に必要だからです。

トビラのページとは、

こういうものです。記事の開始ページに入っており、記事と記事の区切りをわかりやすくするために入れるものです。

そして、TOCはこういうものです。

目下、このTOCにおける階層をベースレイアウト名から推測するロジックをAppleScriptで組んでいますが、ざっくり言って「ベースレイアウト名」から推測している状態です。

もともと、Keynote書類からAppleScriptで各スライドの階層(Level)を取得できるとか、そもそもKeynote自体にTOCつきPDFを書き出す機能がついていれば、外部からScriptで操作しなくても済むわけですが、バージョンアップを繰り返してもそんな便利な機能がつく気配すらありません。Appleに機能追加のリクエストを出して、それが実装されるまで気長に待つよりも、今日すぐにでもScriptから実装したほうがよほど建設的です。また余計なことをされて機能不全を起こされても迷惑ですし。

なので、非常に遠回りな方法ではあるものの、ベースレイアウト(テンプレート)の名称からレベルを推測せざるを得ないというのが現状です。

ただ、これにも限界があります。「だいたい扉のページにはこのベースレイアウト(テンプレート)を使うよね」という「お約束」をベースに、処理を組み立てることになります。

扉のページにつかいがちなベースレイアウト(テンプレート)をあらかじめリストアップしておいて、該当するものを一律に「扉」とみなしてもいいはずです。

ただ、これもいまひとつ信用できないので、もう1手間かけておきたいところです。

Keynote書類のすべてのスライドからベースレイアウト(テンプレート)名を取得し、出現頻度やスライドの傾向から扉ページを特定したいところでもあります。

まずは、ベースレイアウト名一覧を取得し、ユニーク化(重複削除)。それぞれのベースレイアウト名でループして、書類中における出現頻度を求めます。

出現頻度については、1回ということはないでしょうし(規模によってはあるかもしれない)、全ページが該当するものでもないでしょう。また、表紙(最初のページ)、裏表紙(最後のページ)も異なります。

さらに、扉ページについていえば、ページ内に存在する文字アイテム(text item)が少ないことが期待されます。少なくとも自分が作るようなコンテンツではそうした傾向があります。

とりあえず、AppleScriptでKeynote書類からさまざまな情報を取得し、統計的なデータを取得(ページ上に存在するtext item数の標準偏差)するなどして、全体的な傾向を把握して検討するところでしょう。

あまりやりたくはないものの、完全な一括処理(ユーザーにどれが扉ページかを問い合わせない)を行うのではなく、ユーザー(自分)に扉ページのベーススライド名を確認する処理を追加することになるでしょうか。

--> {{baseLayoutName:"タイトルのみ", itemNumList:{10, 3, 3, 7, 14, 16, 10, 8, 6, 17, 9, 11, 16, 17, 11, 3, 3, 3, 15, 7, 16, 7, 3, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 12, 12, 10, 3, 3, 3, 13}, stdDev:4.939129779062}, {baseLayoutName:"タイトル(上)広告用", itemNumList:{56, 22}, stdDev:17.0}, {baseLayoutName:"セクション", itemNumList:{4, 3, 2, 2, 2, 2, 2}, stdDev:0.728431359085}}
AppleScript名:各ベースレイアウト出現頻度およびレイアウト上のアイテム数の分布から扉を推測するテスト.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/06/04
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

property NSExpression : a reference to current application’s NSExpression
property NSMutableArray : a reference to current application’s NSMutableArray

tell application "Keynote"
  tell front document
    set themeNames to name of base layout of every slide
    
set themeList to items 2 thru -2 of themeNames
    
–> {"タイトルのみ", "タイトル(上)_飾りなし", "タイトル(上)広告用", "タイトル(上)広告用", "セクション", "タイトルのみ", "タイトルのみ", "セクション", "タイトルのみ", "タイトルのみ", "セクション", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "セクション", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "セクション", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "セクション", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ", "セクション", "タイトルのみ", "タイトルのみ", "タイトルのみ", "タイトルのみ"}
    
    
set uniList to uniquify1DList(themeList) of me
    
–> {"タイトルのみ", "タイトル(上)_飾りなし", "タイトル(上)広告用", "セクション"}
    
    
set tobiraKouhoList to {}
    
    
repeat with i in uniList
      set j to contents of i
      
set tmpSList to (every slide whose name of base layout is equal to j)
      
      
if length of tmpSList ≥ 2 then
        set tRatioList to {}
        
        
repeat with ii in tmpSList
          set jj to contents of ii
          
tell jj
            set aList to (every iWork item)
            
set the end of tRatioList to length of aList
          end tell
        end repeat
        
set d1Res to calcStddev(tRatioList) of me
        
set the end of tobiraKouhoList to {baseLayoutName:j, itemNumList:tRatioList, stdDev:d1Res}
      end if
      
    end repeat
    
    
return tobiraKouhoList
    
–> {{baseLayoutName:"タイトルのみ", itemNumList:{10, 3, 3, 7, 14, 16, 10, 8, 6, 17, 9, 11, 16, 17, 11, 3, 3, 3, 15, 7, 16, 7, 3, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 12, 12, 10, 3, 3, 3, 13}, stdDev:4.939129779062}, {baseLayoutName:"タイトル(上)広告用", itemNumList:{56, 22}, stdDev:17.0}, {baseLayoutName:"セクション", itemNumList:{4, 3, 2, 2, 2, 2, 2}, stdDev:0.728431359085}}
  end tell
end tell

–標準偏差を計算する
on calcStddev(aList)
  –https://nshipster.com/nsexpression/
  
set anArray to NSMutableArray’s arrayWithArray:aList
  
set anExp to NSExpression’s expressionForFunction:"stddev:" arguments:{(NSExpression’s expressionForConstantValue:anArray)}
  
set valList to anExp’s expressionValueWithObject:(missing value) context:(missing value)
  
return valList as real
end calcStddev

on uniquify1DList(theList as list)
  set theSet to current application’s NSOrderedSet’s orderedSetWithArray:theList
  
return (theSet’s array()) as list
end uniquify1DList

★Click Here to Open This Script 

Posted in Object control | Tagged 10.15savvy 11.0savvy 12.0savvy Keynote | 1 Comment

RectangleBinPackを用いて2D Bin Packを解く v2.3

Posted on 5月 31, 2022 by Takaaki Naganoya

オープンソースの「RectangleBinPack」を用いて2D Bin Packagingを解き、Keynote上の汎用オブジェクト(iWork item)を指定矩形内に詰め込むAppleScriptです。

–> Watch Demo Movie

2D Bin Packは、指定のオブジェクトを面積で評価して、ターゲットの領域に「詰め込む」(オブジェクト回転あり)という処理で、ワードクラウドであるとか、記事レイアウト時の最適化配置といった用途に用いられます。

さまざまなアルゴリズムが提唱され、コンピュータの登場初期からどえらい先人たちが攻めまくった分野であるため、ありがたく、その成果をいただいているという用途でもあります。

よく、ゲームのテクスチャ画像を1枚の画像ファイルに詰め込む際に2D Bin Packの処理を用いている例を見かけます。なんでファイルごとに分けないのかはわかりませんけれども(ファイル容量の節約???)。

–> Download Script bundle with RectangleBinPack in its bundle + sample Keynote document

# This AppleScript requires RectangleBinPack executable in its bundle. So, download the whole AppleScript bundle archive from the link above (↑)

オープン中のKeynote書類の表示中のスライド(ページ)上にある矩形オブジェクト(Shape)を指定の矩形エリア内に2D Packingします。エリアの大きさが小さすぎると正常にPackingされなかったり、false(エラー)を返したりします。

変更履歴:

v2.1: BinPackTestをIntel x64とARM binaryのそれぞれのバイナリでビルドしてバンドルに入れた(Makeを書き換えて直接Universalバイナリに仕立てられるといいのに)
v2.2: BridgePlusがなくても動くように書き換えた(ないと動かないのはいろいろ運用上問題がある)
v2.3: shapeに対してBinPackしていたのを、Keynote上の汎用オブジェクトへのアクセス予約語iWork itemでアクセスするように変更した

AppleScript名:rectBinPack v2.3_Universal.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/05/31
—
–  Copyright © 2019-2022 Piyomaru Software, All Rights Reserved
—
— 2D Bin Packing by juj https://github.com/juj/RectangleBinPack
— v2.1: BinPackTestをIntel x64とARM binaryのそれぞれのバイナリでビルドしてバンドルに入れた(Universalバイナリに仕立てられるといいのに)
— v2.2: BridgePlusを外した(ないと動かないのはいろいろ運用上問題がある)
— v2.3: shapeに対してBinPackしていたのを、Keynote上の汎用オブジェクトへのアクセス予約語iWork itemでアクセスするように変更した

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

–Packaging Target Area
set binSizeX to 600
set binSizeY to 600

set packRes to packKeynoteObjectsOnCurrentSlide(binSizeX, binSizeY) of me

on packKeynoteObjectsOnCurrentSlide(binSizeX, binSizeY)
  set {tList, a0List} to retRectsFromKeynote() of me
  
  
set aList to sortList2DDecending(a0List, {"myWidth", "myHeight", "myArea"}) of me –Sorting key is Width(main) and Area(sub) and Height(sub)
  
  
set aRes to twoDBinPacking(binSizeX, binSizeY, aList) of me
  
if aRes = false then return false
  
  
tell application "Keynote"
    tell front document
      tell current slide
        repeat with i in aRes
          set {posX, posY} to myPos of i
          
set itemIndex to myID of i
          
set aDeg to myDegree of i
          
          
–sample data {itemCounter:5, myWidth:573, myHeight:52, myArea:29796}
          
set anObjID to itemCounter of (item itemIndex of aList)
          
          
set rotation of iWork item anObjID to aDeg
          
set position of iWork item anObjID to {posX, posY}
        end repeat
      end tell
    end tell
  end tell
  
  
return true
end packKeynoteObjectsOnCurrentSlide

on twoDBinPacking(binSizeX as integer, binSizeY as integer, boxList as list)
  set aParamList to {binSizeX, binSizeY}
  
  
repeat with i in boxList
    –copy i to {tmpID, tmpX, tmpY, tmpArea}
    
— {itemCounter:iCount, myWidth:aWidth, myHeight:aHeight, myArea:anArea}
    
set tmpID to itemCounter of i
    
set tmpX to myWidth of i
    
set tmpY to myHeight of i
    
set tmpArea to myArea of i
    
    
set aParamList to aParamList & tmpX
    
set aParamList to aParamList & tmpY
  end repeat
  
  
set aParam to retDelimitedText(aParamList, " ") of me
  
–> "800 800 340 243 340 73 340 73 155 240 147 125 147 125 147 125 147 125"
  
  
–Parameters for result parsing
  
set s1Str to "Packed to (x,y)=("
  
set s2Str to ")"
  
set s3Str to ","
  
  
set cpuRes to CPU type of (system info)
  
if cpuRes begins with "ARM" then
    set exName to "arm"
  else if cpuRes begins with "Intel" then
    set exName to "x86"
  end if
  
  
set binName to "BinPackTest_" & exName
  
set aPath to POSIX path of (path to resource binName)
  
  
try
    set aRes to do shell script quoted form of aPath & " " & aParam
  on error
    return false
  end try
  
  
if aRes does not end with "Done. All rectangles packed." then return false
  
  
set aList to paragraphs of aRes
  
  
set bList to {}
  
set aCount to 1
  
repeat with i in aList
    set j to contents of i
    
if j begins with "Packing rectangle of size " and j does not contain "Failed!" then
      set xyRes to pickUpFromToStrAndParse(j, s1Str, s2Str, s3Str) of me
      
      
–RectangleBinPackがオブジェクトの回転をサポートしているため、その対処
      
if xyRes is not equal to false then
        set s11Str to "(w,h)=("
        
set s12Str to ")"
        
set s13Str to ","
        
        
set whRes to pickUpFromToStrAndParse(j, s11Str, s12Str, s13Str) of me
        
set tmpBox to item aCount of boxList
        
        
— {itemCounter:5, myWidth:573, myHeight:52, myArea:29796}
        
–copy tmpBox to {tmpID, tmpX, tmpY, tmpArea}
        
set tmpID to itemCounter of tmpBox
        
set tmpX to myWidth of tmpBox
        
set tmpY to myHeight of tmpBox
        
set tmpArea to myArea of tmpBox
        
        
if whRes = {tmpX, tmpY} then
          set aDeg to 0
        else if whRes = {tmpY, tmpX} then
          set aDeg to 90
        else
          return false
        end if
        
        
set the end of bList to {myPos:xyRes, myID:aCount, myDegree:aDeg}
      end if
      
set aCount to aCount + 1
    end if
  end repeat
  
  
return bList
end twoDBinPacking

on pickUpFromToStrAndParse(aStr as string, s1Str as string, s2Str as string, s3Str as string)
  set a1Offset to offset of s1Str in aStr
  
if a1Offset = 0 then return false
  
set bStr to text (a1Offset + (length of s1Str)) thru -1 of aStr
  
  
set a2Offset to offset of s2Str in bStr
  
if a2Offset = 0 then return false
  
  
set cStr to text 1 thru (a2Offset – (length of s2Str)) of bStr
  
set {x, y} to parseByDelim(cStr, s3Str) of me
  
  
return {x as integer, y as integer}
end pickUpFromToStrAndParse

on parseByDelim(aData, aDelim)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set dList to text items of aData
  
set AppleScript’s text item delimiters to curDelim
  
return dList
end parseByDelim

–リストを指定デリミタでテキスト化
on retDelimitedText(aList, aNewDelim)
  set aText to ""
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aNewDelim
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retDelimitedText

on retRectsFromKeynote()
  tell application "Keynote"
    tell front document
      tell current slide
        set tList to every iWork item
        
set bList to {}
        
set iCount to 1
        
        
repeat with i in tList
          set aWidth to width of i
          
set aHeight to height of i
          
set {xPos, yPos} to position of i
          
set anArea to aWidth * aHeight
          
          
set the end of bList to {itemCounter:iCount, myWidth:aWidth, myHeight:aHeight, myArea:anArea}
          
set iCount to iCount + 1
        end repeat
        
        
return {tList, bList}
      end tell
    end tell
  end tell
end retRectsFromKeynote

–入れ子のリストを降順ソート
on sortList2DDecending(a, keyLabelList)
  set fLen to length of keyLabelList
  
set fList to {}
  
  
repeat fLen times
    set the end of fList to false
  end repeat
  
  
return cocoaSortListAscending(a, keyLabelList, fList) of me
end sortList2DDecending

–Cocoaで入れ子のリストをソート true:昇順、false:降順
on cocoaSortListAscending(theList as list, keyLabelList as list, ascendingF as list)
  set anArray to current application’s NSMutableArray’s arrayWithArray:(theList)
  
  
set sortDesc to {}
  
set dLen to length of keyLabelList
  
repeat with i from 1 to dLen
    set tmpKeyLabel to contents of item i of keyLabelList
    
set tmpSortF to contents of item i of ascendingF
    
set theDescriptor to (current application’s NSSortDescriptor’s sortDescriptorWithKey:(tmpKeyLabel) ascending:(tmpSortF))
    
set the end of sortDesc to theDescriptor
  end repeat
  
  
set sortedList to anArray’s sortedArrayUsingDescriptors:(sortDesc)
  
  
return sortedList as list
end cocoaSortListAscending

★Click Here to Open This Script 

Posted in 2D Bin Packing list Sort | Tagged 11.0savvy 12.0savvy Keynote | 1 Comment

Keynoteの現在の書類と同じ階層に没スライド入れを作成

Posted on 5月 29, 2022 by Takaaki Naganoya

Keynoteの最前面の書類(現在の書類)と同じ階層に没スライドを入れるゴミ箱用のスライドを、編集中の現在のスライドと同じサイズ(Normal/HD)で同じテーマで作成するAppleScriptです。

ふだん、Keynoteで作業をしているときに、不要になったスライド(ページ)を完全削除せず、別書類に移動させて復活させられるようにしているのですが、その作業が煩雑だったのでScriptで自動化したものです。

同階層にゴミ箱用のスライド書類が存在していたら、それをオープンします。存在していなければ、新規作成して指定ファイル名で保存….というところで、v12のバグに遭遇してしまったわけです。

AppleScript名:Keynoteの現在の書類と同じ階層に没スライド入れを作成.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/05/29
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

property newFileName : "没.key" —"trash.key"

tell application "Keynote"
  tell front document
    set dName to getCurThemeName() of me
    
set curFile to (file of it) as alias
    
set myHeight to height of it
    
set myWidth to width of it
  end tell
end tell

–書類の親フォルダを取得(POSIX path)
set parentFol to getParentFol(curFile) of me
set newKeynoteFile to parentFol & "/" & newFileName

–ファイルの存在確認
set exRes to chkFileExistence(newKeynoteFile) of me
if exRes = true then
  –すでに存在している場合はそれをオープン
  
set newKeynoteFileAlias to (POSIX file newKeynoteFile) as alias
  
tell application "Keynote"
    open newKeynoteFileAlias
  end tell
  
return
else
  –まだ存在していない場合、最前面の書類と同じテーマ、縦横比(SD、HD)の新規書類を作成する
  
set parentFolAlias to (POSIX file parentFol) as alias as string –POSIX path to HFS path string
  
set saveFilePathStr to (parentFolAlias as string) & newFileName
  
  
tell application "Keynote"
    set newDoc to make new document with properties {document theme:theme dName, width:myWidth, height:myHeight}
    
–save newDoc in file saveFilePathStr as Keynote–Keynote v12のバグに遭遇したため機能オフに
  end tell
end if

–ファイルの存在確認
on chkFileExistence(aFilePathStr)
  set fileManager to current application’s NSFileManager’s defaultManager()
  
set aRes to fileManager’s fileExistsAtPath:aFilePathStr
  
return aRes as boolean
end chkFileExistence

on getParentFol(anAlias)
  set aPath to POSIX path of anAlias
  
set pathString to current application’s NSString’s stringWithString:aPath
  
set newPath to pathString’s stringByDeletingLastPathComponent()
  
return newPath as string
end getParentFol

on getCurThemeName()
  tell application "Keynote"
    set dCount to count every document
    
if dCount = 0 then error "No Document"
    
    
tell front document
      set aTheme to document theme
      
set atThemeName to name of aTheme
    end tell
  end tell
end getCurThemeName

★Click Here to Open This Script 

Posted in File path | Tagged 10.15savvy 11.0savvy 12.0savvy Keynote | Leave a comment

Keynoteで選択中のスライドのすべての表のセル内文字色を黒にする

Posted on 5月 27, 2022 by Takaaki Naganoya

Keynote v12.0以降で、最前面の書類で選択中のスライド(複数可)にある表のすべての文字色を「黒」に変更するAppleScriptです。

–> Watch Demo Movie

Keynote v12.0で「selection」がまともに機能するようになったので、Keynote用Scriptの実用性がたいへんに高まっています。

# ファイル保存できないとかいうバグが一刻も早く治ることを希望しています。とくに、Pages!

もともと、複数ページにわたって掲載している「表」の中に赤字でマークした箇所があって、そのマークの意図とは別の赤字を入れたかったので、いったんすべて書式をリセットしたかったので書いたものです。

もうちょっと長いScriptを書かなければならないかと思っていたのですが、ことのほかシンプルに書けました。
もっとシンプルに書けるか(everyを使ってスライドごと指定するとか)も試してみたのですが、どうやらこのあたりが限界のようです。

Keynoteのselectionを活かしたScriptでいまいちばん活躍しているのは、Keynoteのテキストアイテム(text item)から内容を取得して、メモリ上でAppleScriptとしてコンパイルし、構文色分けを反映させたスタイル付きテキストを取得して、テキストアイテムに書式を反映させるものです。実に、Keynote上にテキストで書いておいたAppleScriptのリストを構文色分けを反映させた掲載リストに変換できるので便利です。

AppleScript名:Keynoteで選択中のスライドのすべての表のセル内文字色を黒にする.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/05/27
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—

tell application "Keynote"
  set aVer to version
  
  
considering numeric strings
    if aVer < 12.0 then return –Keynote v12.0より以前のバージョンでは実行できない
  end considering
  
  
tell front document
    set aaSel to selection
    
set selClass to class of contents of first item of aaSel
    
if selClass is not equal to slide then return –選択中のオブジェクトがslide(ページ)でなければ処理終了
    
    
repeat with i in aaSel
      set j to contents of i
      
      
tell j
        –現在のスライド上のすべての表のすべてのセルの文字色を黒 {0, 0, 0}に
        
set text color of every cell of every table to {0, 0, 0}
      end tell
      
    end repeat
    
  end tell
  
end tell

★Click Here to Open This Script 

Posted in list Object control | Tagged 10.15savvy 11.0savvy 12.0savvy Keynote | Leave a comment

iWorkアプリケーションv12に共通のバグ? 新規ファイルの保存ができない

Posted on 5月 23, 2022 by Takaaki Naganoya

Apple iWorkアプリケーション(Keynote、Pages、Numbers)の最新バージョンv12.0において、共通のバグがあるのではないか? と見ています。もちろん、見ているだけでなくAppleにバグレポートもしています。

症状は、新規作成した書類を「保存できない」というものです。

以前にも、PDFをexportできないという致命的なバグが発生していましたが、今回のも同様のメカニズムで発生しているものと見ています。つまり、「Appleが自社OSに設定したセキュリティ機能によって、自社アプリであるKeynote、Pages、Numbersが自家中毒を起こしている」という状態です。

自分の勘違いだとよいのですが….

あとは、Numbersのsaveコマンドをよく見てみると、書類フォーマットに「as Numbers」というenumがあるのですが、これはAppleScriptの処理系では「number」の複数形として認識されてしまうので、この予約語自体に無理があります。ここは、「as Numbers format」といった予約語に変えるべきです。

AppleScript名:Keynoteで新規書類作成して指定名称で新規保存.scpt
set dtPath to (path to documents folder) as string
set uuidStr to (do shell script "uuidgen") & ".key"
set savePath to dtPath & uuidStr

tell application "Keynote"
  set nDoc to make new document with properties {document theme:theme id "Application/21_BasicWhite/Standard", width:1024, height:768}
  
save nDoc in file savePath as Keynote
end tell

★Click Here to Open This Script 

AppleScript名:Pagesで新規書類を作成して指定名称で新規保存.scpt
set dtPath to (path to documents folder) as string
set uuidStr to (do shell script "uuidgen") & ".pages"
set savePath to dtPath & uuidStr

tell application "Pages"
  set nDoc to make new document with properties {document template:template id "Application/Blank/ISO"}
  
save nDoc in file savePath as Pages Format
end tell

★Click Here to Open This Script 

AppleScript名:Numbersで新規書類作成して指定名称で新規保存.scpt
set dtPath to (path to documents folder) as string
set uuidStr to (do shell script "uuidgen") & ".numbers"
set savePath to dtPath & uuidStr

tell application "Numbers"
  set nDoc to make new document
  
save nDoc in file savePath as numbers –change "Numbers" word into "numbers format" because "numbers" is alredy registered as "list of number" or "every number"
end tell

★Click Here to Open This Script 

Posted in Bug news | Tagged 10.15savvy 11.0savvy 12.0savvy Keynote Numbers Pages | Leave a comment

Keynoteで選択中のGroup内オブジェクトを座標でソートし、テキスト抜き出し

Posted on 5月 15, 2022 by Takaaki Naganoya

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

★Click Here to Open This Script 

Posted in list Sort | Tagged 12.0savvy Keynote | Leave a comment

Keynoteのタイトル内の強制改行コードを置換….できない?

Posted on 5月 3, 2022 by Takaaki Naganoya

Keynote v12のスライド(ページ)内のタイトル(default title item)内のテキスト(object text)の強制改行を置換(削除)できないという件についての試行錯誤です。

もともと、v12以前のバージョンのKeynoteでは、LF+LFを削除することで、タイトル内のテキストの改行削除は行えていました。

ただ、同様の処理では強制改行を削除し切れないようで….

--> {"AppleSript+NSImageでよく使う

基礎的な処理一覧", "画像ファイル
変換処理", "画像回転処理", "画像ファイルからの

情報取得処理", "画像リサイズ処理", "画像フィルタ処理"}

いまひとつすっきりしません。

Keynoteのタイトル文字列をコピーして、CotEditor(文字コードをAppleScriptと同じUTF16BEに変更)の書類上にペーストすると0Ahと表示するのですが、どうもKeynote上では異なるようで困ります。

AppleScript名:Keynote v12上の選択中のスライドのタイトルをテキスト化(改行削除)(未遂).scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/05/03
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"

set repTargList to {string id 10 & string id 10, string id 10, string id 11, string id 13} –LF,CR,VTab一括置換

tell application "Keynote"
  tell front document
    set aSel to selection
    
set aList to {}
    
    
repeat with i in aSel
      set tmpClass to class of i
      
if tmpClass = slide then
        set tmpStr0 to object text of default title item of i
        
set hexList to retHexDumpedStr(tmpStr0) of me
        
set tmpStr1 to (paragraphs of tmpStr0) –パラグラフごとにlistにしてみた
        
log tmpStr1
        
set tmpStr2 to replaceTextMultiple(tmpStr1 as string, repTargList, "") of me as string
        
set the end of aList to tmpStr2
      end if
    end repeat
  end tell
end tell

return aList

–文字列の前後の改行と空白文字を除去
on cleanUpText(someText)
  set theString to current application’s NSString’s stringWithString:someText
  
set theString to theString’s stringByReplacingOccurrencesOfString:" +" withString:" " options:(current application’s NSRegularExpressionSearch) range:{location:0, |length|:length of someText}
  
set theWhiteSet to current application’s NSCharacterSet’s whitespaceAndNewlineCharacterSet()
  
set theString to theString’s stringByTrimmingCharactersInSet:theWhiteSet
  
return theString as text
end cleanUpText

–指定文字列からCRLFを除去
on cleanUpCRLF(aStr)
  set aString to current application’s NSString’s stringWithString:aStr
  
set bString to aString’s stringByReplacingOccurrencesOfString:(string id 10) withString:"" –remove LF
  
set cString to bString’s stringByReplacingOccurrencesOfString:(string id 13) withString:"" –remove CR
  
set dString to cString as string
  
return dString
end cleanUpCRLF

–文字置換ルーチン
on repChar(origText as string, targStr as string, repStr as string)
  set {txdl, AppleScript’s text item delimiters} to {AppleScript’s text item delimiters, targStr}
  
set temp to text items of origText
  
set AppleScript’s text item delimiters to repStr
  
set res to temp as text
  
set AppleScript’s text item delimiters to txdl
  
return res
end repChar

–任意のデータから特定の文字列を複数パターン一括置換
on replaceTextMultiple(origData as string, origTexts as list, repText as string)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to origTexts
  
set origData to text items of origData
  
set AppleScript’s text item delimiters to {repText}
  
set origData to origData as text
  
set AppleScript’s text item delimiters to curDelim
  
return origData
end replaceTextMultiple

on hexDumpString(aStr as string)
  set theNSString to current application’s NSString’s stringWithString:aStr
  
set theNSData to theNSString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set theString to (theNSData’s |debugDescription|()’s uppercaseString())
  
  
–Remove "<" ">" characters in head and tail
  
set tLength to (theString’s |length|()) – 2
  
set aRange to current application’s NSMakeRange(1, tLength)
  
set theString2 to theString’s substringWithRange:aRange
  
  
–Replace Space Characters
  
set aString to current application’s NSString’s stringWithString:theString2
  
set bString to aString’s stringByReplacingOccurrencesOfString:" " withString:""
  
  
set aResList to splitString(bString, 2)
  
–> {​​​​​"E3", ​​​​​"81", ​​​​​"82", ​​​​​"E3", ​​​​​"81", ​​​​​"84", ​​​​​"E3", ​​​​​"81", ​​​​​"86", ​​​​​"E3", ​​​​​"81", ​​​​​"88", ​​​​​"E3", ​​​​​"81", ​​​​​"8A"​​​}
  
  
return aResList
end hexDumpString

–Split NSString in specified aNum characters
on splitString(aText, aNum)
  set aStr to current application’s NSString’s stringWithString:aText
  
if aStr’s |length|() ≤ aNum then return aText
  
  
set anArray to current application’s NSMutableArray’s new()
  
set mStr to current application’s NSMutableString’s stringWithString:aStr
  
  
set aRange to current application’s NSMakeRange(0, aNum)
  
  
repeat while (mStr’s |length|()) > 0
    if (mStr’s |length|()) < aNum then
      anArray’s addObject:(current application’s NSString’s stringWithString:mStr)
      
mStr’s deleteCharactersInRange:(current application’s NSMakeRange(0, mStr’s |length|()))
    else
      anArray’s addObject:(mStr’s substringWithRange:aRange)
      
mStr’s deleteCharactersInRange:aRange
    end if
  end repeat
  
  
return (current application’s NSArray’s arrayWithArray:anArray) as list
end splitString

–与えられたデータ内容をhexdumpして返す
on retHexDumpedStr(aStr)
  set aRes to do shell script "echo " & quoted form of aStr & " | hexdump -v "
  
return aRes
end retHexDumpedStr

★Click Here to Open This Script 

Posted in Object control Text | Tagged 10.15savvy 11.0savvy 12.0savvy Keynote | Leave a comment

Keynoteで選択中のtext itemとshapeをもとにtext itemを敷き詰める

Posted on 4月 15, 2022 by Takaaki Naganoya

Keynote v12で正常化した「selection」を用いて、選択中のshapeオブジェクトの範囲に、選択中のtext itemを指定数敷き詰めるAppleScriptです。

–> Watch Demo Movie

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

★Click Here to Open This Script 

Posted in list | Tagged 10.15savvy 11.0savvy 12.0savvy Keynote | Leave a comment

Keynoteで選択中のオブジェクトを取得して座標でソート

Posted on 4月 10, 2022 by Takaaki Naganoya

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がまともになったおかげです。

–> Watch Demo Movie

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

★Click Here to Open This Script 

Posted in list Sort | Tagged 11.0savvy 12.0savvy Keynote | Leave a comment

Post navigation

  • Older posts
  • Newer posts

電子書籍(PDF)をオンラインストアで販売中!

Google Search

Popular posts

  • 開発機としてM2 Mac miniが来たのでガチレビュー
  • macOS 15, Sequoia
  • 指定のWordファイルをPDFに書き出す
  • Pages本執筆中に、2つの書類モード切り替えに気がついた
  • Numbersで選択範囲のセルの前後の空白を削除
  • メキシカンハットの描画
  • Pixelmator Pro v3.6.4でAppleScriptからの操作時の挙動に違和感が
  • AdobeがInDesign v19.4からPOSIX pathを採用
  • Safariで「プロファイル」機能を使うとAppleScriptの処理に影響
  • AppleScriptによる並列処理
  • Cocoa Scripting Course 続刊計画
  • AppleScript入門③AppleScriptを使った「自動化」とは?
  • macOS 14.xでScript Menuの実行速度が大幅に下がるバグ
  • Keynote/Pagesで選択中の表カラムの幅を均等割
  • Keynote、Pages、Numbers Ver.14.0が登場
  • デフォルトインストールされたフォント名を取得するAppleScript
  • macOS 15 リモートApple Eventsにバグ?
  • AppleScript入門① AppleScriptってなんだろう?
  • macOS 15でも変化したText to Speech環境
  • Numbersで最前面の書類のすべてのシート上の表の行数を合計

Tags

10.11savvy (1101) 10.12savvy (1242) 10.13savvy (1391) 10.14savvy (587) 10.15savvy (438) 11.0savvy (283) 12.0savvy (212) 13.0savvy (194) 14.0savvy (147) 15.0savvy (131) CotEditor (66) Finder (51) iTunes (19) Keynote (117) NSAlert (61) NSArray (51) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (53) NSDictionary (28) NSFileManager (23) NSFont (21) NSImage (41) NSJSONSerialization (21) NSMutableArray (63) NSMutableDictionary (22) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (119) NSURL (98) NSURLRequest (23) NSUTF8StringEncoding (30) NSView (33) NSWorkspace (20) Numbers (76) Pages (55) Safari (44) Script Editor (27) WKUserContentController (21) WKUserScript (20) WKWebView (23) WKWebViewConfiguration (22)

カテゴリー

  • 2D Bin Packing
  • 3D
  • AirDrop
  • AirPlay
  • Animation
  • AppleScript Application on Xcode
  • Beginner
  • Benchmark
  • beta
  • Bluetooth
  • Books
  • boolean
  • bounds
  • Bug
  • Calendar
  • call by reference
  • check sum
  • Clipboard
  • Cocoa-AppleScript Applet
  • Code Sign
  • Color
  • Custom Class
  • date
  • dialog
  • diff
  • drive
  • Droplet
  • exif
  • file
  • File path
  • filter
  • folder
  • Font
  • Font
  • GAME
  • geolocation
  • GUI
  • GUI Scripting
  • Hex
  • History
  • How To
  • iCloud
  • Icon
  • Image
  • Input Method
  • Internet
  • iOS App
  • JavaScript
  • JSON
  • JXA
  • Keychain
  • Keychain
  • Language
  • Library
  • list
  • Locale
  • Localize
  • Machine Learning
  • Map
  • Markdown
  • Menu
  • Metadata
  • MIDI
  • MIME
  • Natural Language Processing
  • Network
  • news
  • Noification
  • Notarization
  • Number
  • Object control
  • OCR
  • OSA
  • parallel processing
  • PDF
  • Peripheral
  • PRODUCTS
  • QR Code
  • Raw AppleEvent Code
  • Record
  • rectangle
  • recursive call
  • regexp
  • Release
  • Remote Control
  • Require Control-Command-R to run
  • REST API
  • Review
  • RTF
  • Sandbox
  • Screen Saver
  • Script Libraries
  • sdef
  • search
  • Security
  • selection
  • shell script
  • Shortcuts Workflow
  • Sort
  • Sound
  • Spellchecker
  • Spotlight
  • SVG
  • System
  • Tag
  • Telephony
  • Text
  • Text to Speech
  • timezone
  • Tools
  • Update
  • URL
  • UTI
  • Web Contents Control
  • WiFi
  • XML
  • XML-RPC
  • イベント(Event)
  • 未分類

アーカイブ

  • 2025年4月
  • 2025年3月
  • 2025年2月
  • 2025年1月
  • 2024年12月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年6月
  • 2024年5月
  • 2024年4月
  • 2024年3月
  • 2024年2月
  • 2024年1月
  • 2023年12月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年6月
  • 2023年5月
  • 2023年4月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年12月
  • 2019年11月
  • 2019年10月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年5月
  • 2018年4月
  • 2018年3月
  • 2018年2月

https://piyomarusoft.booth.pm/items/301502

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org

Forum Posts

  • 人気のトピック
  • 返信がないトピック

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org
Proudly powered by WordPress
Theme: Flint by Star Verte LLC