最前面のKeynote書類の文字色を置換するAppleScriptです。
# 初出時にはmacOS 10.13であったため、スクリプトエディタ上からも野良Framework呼び出しができましたが、macOS 10.14以降ではSIPを解除するかScript Debugger上で実行する必要があります
Keynoteは文字色の置換をする機能が実装されていないので、個別に手で色を変更するか、あるいはスタイルを編集して一括で修正するやり方になります。
そこで、AppleScriptで色置換を行う処理を書いてみました。表の背景色を置換する処理を書いたときの部品を大幅に使いまわしています。
文字色の取得や判定は、テキストアイテムの1文字目の情報で判断しています。途中で色を変更しているような場合にはうまく検出できません(処理スピードを重視したことと、自分の利用方法の範囲ではそういう文字ごとに異なる色を指定するところまではサポートしなくてよいと考えたためです。仕事ならもうちょっと真面目に作り込むかもしれませんが、、、、)。
ポップアップメニュー中の色名の動的な推定に、オープンソースの「DBColorNames」をフレームワーク化した
「dbColNamesKit.framework」を利用しています。
–> dbColNamesKit.framework (To ~/Library/Frameworks)
▲左上の時刻部分の色を置換したい
▲本Scriptを実行した直後。最前面のKeynote書類のすべてのテキストを走査して文字色を取得する
▲取得した文字色リスト。この中から置換対象を選択する。色データから色名を動的に生成し、色IDとともに名称で個別に指定したり識別したりできる
▲変更後の色をカラーピッカーで選択
▲Keynote書類上の文字色を変更してみた
AppleScript名:Keynote書類の現在のテキスト色を置換.scptd |
— – Created by: Takaaki Naganoya – Created on: 2019/06/08 — – Copyright © 2019 Piyomaru Software, All Rights Reserved — use AppleScript version "2.5" — Yosemite (10.11) or later use framework "Foundation" use framework "AppKit" use framework "dbColNamesKit" –https://github.com/daniel-beard/DBColorNames/ use scripting additions property NSView : a reference to current application’s NSView property NSAlert : a reference to current application’s NSAlert property NSColor : a reference to current application’s NSColor property NSMenu : a reference to current application’s NSMenu property NSImage : a reference to current application’s NSImage property NSIndexSet : a reference to current application’s NSIndexSet property NSTextField : a reference to current application’s NSTextField property NSColorWell : a reference to current application’s NSColorWell property NSMenuItem : a reference to current application’s NSMenuItem property NSBezierPath : a reference to current application’s NSBezierPath property NSPopUpButton : a reference to current application’s NSPopUpButton property NSMutableArray : a reference to current application’s NSMutableArray property NSRunningApplication : a reference to current application’s NSRunningApplication property returnCode : 0 property pop1ind : 0 –スライド枚数をカウント tell application "Keynote" tell front document set sCount to count every slide end tell end tell –すべてのテキストアイテム、タイトルから色情報を取得する set cList to {} repeat with sNum from 1 to sCount set cList to cList & getEveryTextColorOfSlide(sNum) of me end repeat –文字色のユニーク化 set dList to makeUniqueListOf(cList) of me set paramObj to {mainDat:dList, myTitle:"テキスト色置換", mySubTitle:"Keynoteのテキストアイテム、デフォルトアイテム(タイトル)の文字色置換", myColorRangeMax:65535} my getPopupValues:paramObj if pop1ind = false then return –timed out set fromCol to (contents of item pop1ind of dList) –カラーピッカーで置換色選択 set tCol to choose color default color fromCol –Keynote書類中のテキストの文字色を置換 repeat with sNum from 1 to sCount set cList to cList & repEveryTextColorOfSlide(sNum, fromCol, tCol) of me end repeat –カラーポップアップメニューをウィンドウ表示 on getPopupValues:paramObj set ap1List to (mainDat of (paramObj as record)) as list set winTitle to (myTitle of (paramObj as record)) as string set subTitle to (mySubTitle of (paramObj as record)) as string set aColMax to (myColorRangeMax of (paramObj as record)) as list –Viewをつくる set aView to NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, 360, 80)) –Labelをつくる set a1TF to NSTextField’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 40, 80, 20)) a1TF’s setEditable:false a1TF’s setStringValue:"From Color:" a1TF’s setDrawsBackground:false a1TF’s setBordered:false –Ppopup Buttonをつくる set a1Button to NSPopUpButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(80, 40, 200, 20)) pullsDown:false a1Button’s removeAllItems() set a1Menu to NSMenu’s alloc()’s init() set aCDB to current application’s DBColorNames’s alloc()’s init() –Popup Menuをつくる set iCount to 1 repeat with i in ap1List copy i to {r1, g1, b1} set nsCol to makeNSColorFromRGBAval(r1, g1, b1, aColMax, aColMax) of me set anImage to makeRoundedNSImageWithFilledWithColor(64, 64, nsCol, 4) of me –色名をRGB値から動的に生成(あらかじめdbNamesが持っているカラーパレットの近似色の色名を返す) set aTitle to "#" & (iCount as string) & " " & (aCDB’s nameForColor:nsCol) as string –Menu Itemを作成する set aMenuItem to (NSMenuItem’s alloc()’s initWithTitle:aTitle action:"actionHandler:" keyEquivalent:"") (aMenuItem’s setImage:anImage) (aMenuItem’s setEnabled:true) (aMenuItem’s setTarget:me) (a1Menu’s addItem:aMenuItem) set iCount to iCount + 1 end repeat –Popup ButtonにPopup Menuを設定する a1Button’s setMenu:a1Menu –ViewにPopup Buttonとテキストラベルを入れる aView’s addSubview:a1TF aView’s addSubview:a1Button aView’s setNeedsDisplay:true — set up alert set theAlert to NSAlert’s alloc()’s init() tell theAlert its setMessageText:winTitle its setInformativeText:subTitle its addButtonWithTitle:"OK" its addButtonWithTitle:"Cancel" its setAccessoryView:aView end tell — show alert in modal loop NSRunningApplication’s currentApplication()’s activateWithOptions:0 my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true if (my returnCode as number) = 1001 then error number -128 set s1Val to ((a1Button’s indexOfSelectedItem() as number) + 1) copy s1Val to my pop1ind end getPopupValues: on doModal:aParam set (my returnCode) to aParam’s runModal() end doModal: –Popup Action Handler on actionHandler:sender set aTag to tag of sender as integer set aTitle to title of sender as string end actionHandler: –aMaxValを最大値とする数値でNSColorを作成して返す on makeNSColorFromRGBAval(redValue as integer, greenValue as integer, blueValue as integer, alphaValue as integer, aMaxVal as integer) set aRedCocoa to (redValue / aMaxVal) as real set aGreenCocoa to (greenValue / aMaxVal) as real set aBlueCocoa to (blueValue / aMaxVal) as real set aAlphaCocoa to (alphaValue / aMaxVal) as real set aColor to NSColor’s colorWithCalibratedRed:aRedCocoa green:aGreenCocoa blue:aBlueCocoa alpha:aAlphaCocoa return aColor end makeNSColorFromRGBAval –指定サイズのNSImageを作成し、指定色で塗ってNSImageで返す on makeNSImageWithFilledWithColor(aWidth as integer, aHeight as integer, fillColor) set anImage to NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight)) anImage’s lockFocus() — set theRect to {{x:0, y:0}, {height:aHeight, width:aWidth}} set theNSBezierPath to NSBezierPath’s bezierPath theNSBezierPath’s appendBezierPathWithRect:theRect — fillColor’s |set|() –色設定 theNSBezierPath’s fill() –ぬりつぶし — anImage’s unlockFocus() — return anImage end makeNSImageWithFilledWithColor –指定サイズのNSImageを作成し、指定色で塗ってNSImageで返す、anRadiusの半径の角丸で on makeRoundedNSImageWithFilledWithColor(aWidth as integer, aHeight as integer, fillColor, anRadius as real) set anImage to NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight)) anImage’s lockFocus() — set theRect to {{x:0, y:0}, {height:aHeight, width:aWidth}} set theNSBezierPath to NSBezierPath’s bezierPathWithRoundedRect:theRect xRadius:anRadius yRadius:anRadius — fillColor’s |set|() –色設定 theNSBezierPath’s fill() –ぬりつぶし — anImage’s unlockFocus() return anImage end makeRoundedNSImageWithFilledWithColor –最前面のKeynote書類のすべてのスライドから、テキストアイテムとタイトルアイテムの文字色を取得 on getEveryTextColorOfSlide(sNum) set cList to {} tell application "Keynote" tell front document set sMax to count every slide if sMax < sNum then return false tell slide sNum –すべての文字アイテムの先頭の文字の色情報を取得 try set tCount to count every text item repeat with i from 1 to tCount set s1List to color of character 1 of object text of text item i set the end of cList to s1List end repeat on error –set s1List to {} end try –タイトルの先頭の文字の色情報を取得 try set s2List to color of character 1 of object text of default title item set the end of cList to s2List on error set s2List to {} end try end tell end tell end tell return cList end getEveryTextColorOfSlide –最前面のKeynote書類の指定番号のスライドで、テキストアイテムとタイトルアイテムの文字色を置換 on repEveryTextColorOfSlide(sNum, fromCol, toCol) tell application "Keynote" tell front document set sMax to count every slide if sMax < sNum then return false tell slide sNum –すべての文字アイテムの先頭の文字の色情報を置換 try set tCount to count every text item repeat with i from 1 to tCount set s1List to color of character 1 of object text of text item i if s1List = fromCol then ignoring application responses set color of every character of object text of text item i to toCol end ignoring end if end repeat on error — end try –タイトルの先頭の文字の色情報を置換 try set s2List to color of character 1 of object text of default title item if s2List = fromCol then ignoring application responses set color of every character of object text of default title item to toCol end ignoring end if on error set s2List to {} end try end tell end tell end tell end repEveryTextColorOfSlide –Listのユニーク化 on makeUniqueListOf(theList) set theSet to current application’s NSOrderedSet’s orderedSetWithArray:theList return (theSet’s array()) as list end makeUniqueListOf |