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

月: 2019年4月

マウスカーソルを隠す→表示する

Posted on 4月 9, 2019 by Takaaki Naganoya

マウスカーソルを非表示、表示にするAppleScriptです。

マウスカーソルの変更はClassic Mac OSの時代にそういうOSAXを見かけた覚えがありますが、今日びCocoaの機能を用いて割と簡単に表示/非表示の切り替えができることに気づきました。

# カーソルのイメージを変更するのには失敗しました

長時間のバッチ(一括)処理中にユーザーに操作してほしくない場合には、デスクトップ機であればマウスを取り外しておく措置を講じたこともありますが、さらに念には念のためにこうしてマウスカーソルを非表示にしておくのもよいかもしれません。

MacBook Proなどのノートでバッチ処理を行いつつユーザーの操作により処理が妨げられることを防ぐためにカーソル非表示にするのも、(ユーザーが不安に感じなければ)案外いい手段でしょう。

AppleScript的には、意外と使い勝手がありそうです。

AppleScript名:マウスカーソルを隠す→表示する.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/04/09
—
–  Copyright © 2019 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 curCursor to current application’s NSCursor’s currentCursor()

current application’s NSCursor’s hide()

delay 5

current application’s NSCursor’s unhide()

★Click Here to Open This Script 

Posted in System | Tagged 10.12savvy 10.13savvy 10.14savvy NSCursor | Leave a comment

ASの実行結果をNumbersの表に出力する

Posted on 4月 5, 2019 by Takaaki Naganoya

文字列で与えたAppleScriptを実行し、その実行結果をテキストで取得したうえにラベルと値に分割してNumbersの「表」に組み立てるAppleScriptです。

仕様書の作成とかテストデータの評価とかそういう仕事を行うさいに、プログラムコード(AppleScriptが出力するrecordとかlistとか)が読めない人向けに確認してもらうために作成したものです。

Numbersに出力すること自体にはさほど意味はありませんが(ExcelでもREST API経由でGoogle Spread Sheetに出力したっていいわけで)、とりあえずプログラムの結果出力になじみのない方々に計算結果を見ていただくためのものです。

AppleScriptの実行結果をスクリプトエディタではなくOSAScriptControllerなどから受け取る部品などが揃ってきたので、こういう加工も割とすぐにできていい感じです。

ちなみに、Numbersの表のセルに対して直接AppleScriptからデータを突っ込んでいますが、これはあらかじめ出力するデータ数が少ないことが見込まれているためです。多い場合(100件前後がひとつの基準に)には、CSVファイルに書き出してNumbersにオープンさせることになるでしょう。

例によって、Numbersの表セルに対してデータを突っ込むさいには非同期モードで実行して速度を稼いでいます。

AppleScript名:ASの実行結果をNumbersの表に出力する
— Created 2019/04/05 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "OSAKit"
use framework "AppKit"
use bLus : script "BridgePlus"

property NSString : a reference to current application’s NSString
property NSThread : a reference to current application’s NSThread
property OSAScript : a reference to current application’s OSAScript
property NSTextView : a reference to current application’s NSTextView
property OSAScriptView : a reference to current application’s OSAScriptView
property OSAScriptController : a reference to current application’s OSAScriptController

property SMSForder : a reference to current application’s SMSForder

property theResult : "" –result

set origStr to "
tell application \"Numbers\"
  tell front document
    properties
  end tell
end tell
"

my performSelectorOnMainThread:"execASandReturnString:" withObject:origStr waitUntilDone:true
set aStr to (my theResult)

set aList to my getListFromText:aStr

makeNewNumbersDocumentAndTable(length of aList, 2) of me
fillCurrentTable(aList) of me

–リストに入れたレコードを、指定の属性ラベルの値で抽出
on filterRecListByLabel(aRecList as list, aPredicate as string)
  –ListからNSArrayへの型変換
  
set aArray to current application’s NSArray’s arrayWithArray:aRecList
  
  
–抽出
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat:aPredicate
  
set filteredArray to aArray’s filteredArrayUsingPredicate:aPredicate
  
  
–NSArrayからListに型変換して返す
  
set bList to filteredArray as list
  
return bList
end filterRecListByLabel

–リストに入れたレコードを、指定の属性ラベルの値で抽出。値が別途指定のリストの中に存在していることが条件
on filterRecList:(aRecList as list) byLabel:(aPredicate as string) andSublist:(aSubList as list)
  –ListからNSArrayへの型変換
  
set aArray to current application’s NSArray’s arrayWithArray:aRecList
  
set aSubArray to current application’s NSArray’s arrayWithArray:aSubList
  
  
–抽出
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat_(aPredicate, aSubArray)
  
set filteredArray to aArray’s filteredArrayUsingPredicate:aPredicate
  
  
–NSArrayからListに型変換して返す
  
set bList to filteredArray as list
  
return bList
end filterRecList:byLabel:andSublist:

–listの共通項を返す
on getSameItemsInLists:(aList as list) withList:(bList as list)
  
  
–ASオブジェクトをCocoaオブジェクトに変換
  
set aArray to current application’s NSArray’s arrayWithArray:aList
  
set bArray to current application’s NSArray’s arrayWithArray:bList
  
  
— まとめる
  
set allSet to current application’s NSMutableSet’s setWithArray:aArray
  
allSet’s addObjectsFromArray:bArray
  
  
–重複する要素のみ抜き出す
  
set duplicateSet to current application’s NSMutableSet’s setWithArray:aArray
  
duplicateSet’s intersectSet:(current application’s NSSet’s setWithArray:bArray)
  
  
–重複部分だけを返す
  
set resArray to duplicateSet’s allObjects()
  
  
set resList to resArray as list
  
  
return resList
end getSameItemsInLists:withList:

–スクリプトエディタのresult欄に返ってきたテキストをリストに変える
on getListFromText:aText
  
  
script getListFromTextO
    property aaText : ""
    
property gList : {}
    
property outList : {}
    
property aG : ""
    
property valList : {}
  end script
  
  
copy aText to (aaText of getListFromTextO)
  
  
set (gList of getListFromTextO) to {}
  
set (outList of getListFromTextO) to {}
  
set (aG of getListFromTextO) to ""
  
set (valList of getListFromTextO) to {}
  
  
if (aaText of getListFromTextO) does not start with "{" and (aaText of getListFromTextO) does not end with "}" then
    return {}
  end if
  
  
set aLen to length of (aaText of getListFromTextO)
  
set (aG of getListFromTextO) to text 2 thru -2 of (aaText of getListFromTextO)
  
set (gList of getListFromTextO) to characters of (aG of getListFromTextO)
  
  
  
set sPos to 2 –1文字目は\"{\"なので2文字目からスキャンを開始する
  
set ePos to 2
  
  
set imdF to false –Immediate Data Flag(文字列中を示すダブルクォート内の場合にはtrueになる)
  
set listF to 0 –stacking段数が入る
  
  
set attrF to true –属性ラベルスキャン時にtrue、データ末尾スキャン時にfalse
  
  
  
repeat with i in (gList of getListFromTextO)
    
    
set j to contents of i
    
    
if attrF = true and imdF = false and listF = 0 then
      
      
–属性値部分の末尾検出
      
if j = ":" then
        if text sPos thru sPos of (aaText of getListFromTextO) = " " then
          set sPos to sPos + 1
        end if
        
set anOut to text sPos thru ePos of (aaText of getListFromTextO)
        
set sPos to ePos + 1
        
set the end of (valList of getListFromTextO) to anOut
        
set attrF to false –データのスキャンを開始する
        
set imdF to false
        
set listF to 0
      end if
      
    else if imdF = false and listF = 0 and j = "," then
      
      
–データ部分の末尾検出
      
set anOut to text sPos thru (ePos – 1) of (aaText of getListFromTextO)
      
set sPos to ePos + 1
      
set the end of (valList of getListFromTextO) to anOut
      
set the end of (outList of getListFromTextO) to (valList of getListFromTextO)
      
set (valList of getListFromTextO) to {}
      
      
set attrF to true –次が属性値ラベルであることを宣言
      
set imdF to false
      
set listF to 0
      
    else if j = "{" then
      if imdF = false then
        set listF to listF + 1 –1段スタックにpush
      end if
    else if j = "}" then
      if imdF = false then
        set listF to listF – 1 –1段スタックからpop
      end if
    else if j = "\"" then
      if imdF = true then
        set imdF to false
      else
        set imdF to true
      end if
    end if
    
    
set ePos to ePos + 1
    
  end repeat
  
  
–ラストのデータ部分を出力
  
try
    set the end of (valList of getListFromTextO) to text sPos thru (ePos – 1) of (aaText of getListFromTextO)
    
set the end of (outList of getListFromTextO) to (valList of getListFromTextO)
  on error
    return false
  end try
  
  
return contents of (outList of getListFromTextO)
end getListFromText:

on execASandReturnString:(srcStr as string)
  
  
set targX to 500 –View Width
  
set targY to 200 –View Height
  
  
  
if srcStr = missing value or srcStr = "" then
    –Error
    
display dialog "Error in reading script source…." buttons {"OK"} default button 1 with icon 1
    
return
  end if
  
  
–Make AppleScript Controller & Script Editor View
  
set osaCon to OSAScriptController’s alloc()’s init()
  
set osaView to OSAScriptView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, targX, targY))
  
  
–Make Result View
  
set resView to NSTextView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, targX, targY))
  
resView’s setRichText:true
  
resView’s useAllLigatures:true
  
  
–Connect OSAScriptController to Editor View & Result View
  
osaCon’s setScriptView:osaView
  
osaCon’s setResultView:resView
  
  
–Set AppleScript Source to Editor View & Execute it
  
osaView’s setString:srcStr
  
osaCon’s runScript:(missing value)
  
  
–Get AppleScript’s Result as string
  
set aRes to resView’s |string|() as list of string or string –as anything
  
  
set my theResult to aRes –Return the result as string
  
end execASandReturnString:

on fillCurrentTable(aList)
  set aLen to length of aList
  
set aWidth to length of first item of aList
  
  
tell application "Numbers"
    tell front document
      tell active sheet
        tell table 1
          repeat with i from 1 to aLen
            tell row (i + 1)
              set aRowList to contents of item i of aList
              
repeat with ii from 1 to aWidth
                tell cell ii
                  set aTmpData to contents of item ii of aRowList
                  
ignoring application responses
                    set value to aTmpData
                  end ignoring
                end tell
              end repeat
            end tell
          end repeat
        end tell
      end tell
    end tell
  end tell
end fillCurrentTable

on makeNewNumbersDocumentAndTable(aHeight, aWidth)
  tell application "Numbers"
    make new document
    
    
tell front document
      tell active sheet
        delete every table
      end tell
    end tell
    
    
tell front document
      tell active sheet
        set tRes to make new table with properties {row count:aHeight, column count:aWidth}
        
return tRes
      end tell
    end tell
  end tell
end makeNewNumbersDocumentAndTable

★Click Here to Open This Script 

Posted in OSA Record | Tagged 10.12savvy 10.13savvy 10.14savvy NSString NSTextView NSThread Numbers OSAScript OSAScriptController OSAScriptView | Leave a comment

Keynoteのテキストアイテム内の文字の実際の幅でリサイズ

Posted on 4月 5, 2019 by Takaaki Naganoya

Keynote書類上のテキストアイテムを、内容の文字の実際の幅でリサイズするAppleScriptです。


▲テキストアイテム中のテキストをコピー(Command-C)


▲リサイズ前のテキストアイテム。文字に対してフレームサイズが大きい


▲本Scriptによりリサイズした後のテキストアイテム。文字の内容に対してフレームサイズがフィットしている


▲本Scriptにより順次複数のテキストアイテムを文字幅にリサイズしたところ。selectionがまともに動作していれば、複数のテキストアイテムを選択した状態でScriptを走らせて一度にリサイズできる(はず)だが、selectionが動作していないので複数のオブジェクトに対して同じ回数の操作が必要

Keynoteにはversion 9.0で「selection」の予約語が追加されましたが、これは一般に期待されるような「表示中のスライド上で選択中のオブジェクトへの参照が取得できる」というものではありません。

つまり、選択中のオブジェクトへの参照をKeynoteに対して問い合わせることは、(現時点では)不可能です。

そこで、テキストアイテム内の内容(object text)をコピー(Command-C)してクリップボードに格納し、その内容をキーにして現在表示中のスライド内のテキストアイテムを抽出してみたところ、うまくいきました(なんでこんなことさせられてるんだろ?)。早くselectionがKeynote上でもまともに使えるようになってほしいものです(Pages上ではけっこういい感じに使えるのに)。

テキストアイテムの特定ができるようになったので、入っているobject textのサイズに合わせてテキストアイテムをリサイズする処理を書いてみました。

クリップボードの内容をNSAttributedStringとして取得し、その画面上の描画サイズを取得するサブルーチンは毎日さんざん使っているので(掲載リストのproperty宣言部をソートするのに使っています)信頼性があります。

とりあえず、擬似的に現在選択中のオブジェクトを特定する実験コードにちょっとだけ機能をつけたものですが、操作1に対して結果1というのは普通「自動化」とか言わないので、実用性は皆無です(めんどくさい操作ステップを省けるぐらいしか)。

AppleScript名:Keynoteのテキストアイテム内の文字の実際の幅でリサイズ
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/04/05
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use BPlus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html

property NSFont : a reference to current application’s NSFont
property NSColor : a reference to current application’s NSColor
property NSPasteboard : a reference to current application’s NSPasteboard
property NSAttributedString : a reference to current application’s NSAttributedString
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

load framework

–クリップボードの内容をテキストとして取得し、現在のKeynote書類中のtext itemのうちコピーしたテキストに該当するものを抽出
set targString to (the clipboard) as string

tell application "Keynote"
  tell document 1
    tell current slide
      set tList to every text item whose object text is targString
      
if tList = {} then return
      
set targObject to first item of tList
    end tell
  end tell
end tell

–クリップボードの内容をNSAttributedStringに
set anAttr to my getClipboardASStyledText()

–Split Attributed Strings into lines
set attrList to splitAttributedStringByLines(anAttr) of me

–Sort Attributed String list by its width in descending (large–> small)
set aResList to shellSortListDecending(attrList, 1) of me
set {targObjWidth, targAttrStrObj} to first item of aResList

–Resize Text item objet’s frame by its drawing width on screen
tell application "Keynote"
  tell document 1
    tell current slide
      tell targObject
        set width to ((targObjWidth as number) + 10) –resize it !
      end tell
    end tell
  end tell
end tell

–入れ子のリストを昇順ソート
on shellSortListAscending(a, keyItem)
  return sort2DList(a, keyItem, {true}) of me
end shellSortListAscending

–入れ子のリストを降順ソート
on shellSortListDecending(a, keyItem)
  return sort2DList(a, keyItem, {false}) of me
end shellSortListDecending

–2D Listをソート
on sort2DList(aList as list, sortIndexes as list, sortOrders as list)
  
  
–index値をAS流(アイテムが1はじまり)からCocoa流(アイテムが0はじまり)に変換
  
set newIndex to {}
  
repeat with i in sortIndexes
    set j to contents of i
    
set j to j – 1
    
set the end of newIndex to j
  end repeat
  
  
–Sort TypeのListを作成(あえて外部から指定する内容でもない)
  
set sortTypes to {}
  
repeat (length of sortIndexes) times
    set the end of sortTypes to "compare:"
  end repeat
  
  
–Sort
  
set resList to (current application’s SMSForder’s subarraysIn:(aList) sortedByIndexes:newIndex ascending:sortOrders sortTypes:sortTypes |error|:(missing value)) as list
  
  
return resList
end sort2DList

— クリップボードの内容をNSAttributedStringとして取り出して返す
on getClipboardASStyledText()
  try
    set theNSPasteboard to NSPasteboard’s generalPasteboard()
    
set theAttributedStringNSArray to theNSPasteboard’s readObjectsForClasses:({NSAttributedString}) options:(missing value)
    
set theNSAttributedString to theAttributedStringNSArray’s objectAtIndex:0
    
return theNSAttributedString
  on error
    return missing value
  end try
end getClipboardASStyledText

on splitAttributedStringByLines(theStyledText)
  set outList to {}
  
set outAttr to NSMutableAttributedString’s alloc()’s initWithString:""
  
  
set thePureString to theStyledText’s |string|() –pure string from theStyledText
  
set theLength to theStyledText’s |length|()
  
set startIndex to 0
  
  
repeat until (startIndex = theLength)
    set {theAtts, theRange} to theStyledText’s attributesAtIndex:startIndex longestEffectiveRange:(reference) inRange:{startIndex, theLength – startIndex}
    
set aText to (thePureString’s substringWithRange:theRange) as string –String
    
    
set aColor to (theAtts’s valueForKeyPath:"NSColor") –Color
    
set aFont to (theAtts’s valueForKeyPath:"NSFont") –Font
    
if aFont is equal to missing value then error "Not font name and size are specified" –Font Name error
    
set aDFontName to aFont’s displayName() –Font Name
    
set aDFontSize to aFont’s pointSize() –Font Size
    
    
set tmpAttrStr to generateAttributedString(aText, aDFontName, aDFontSize, aColor) of me
    
outAttr’s appendAttributedString:tmpAttrStr
    
    
if (aText contains return) or (aText contains string id 10) then –CR or LF
      set tmpSize to outAttr’s |size|()
      
set tmpWidth to retWidthFromSize(tmpSize) of me
      
      
set the end of outList to {tmpWidth, outAttr}
      
set outAttr to NSMutableAttributedString’s alloc()’s initWithString:""
    end if
    
    
set startIndex to current application’s NSMaxRange(theRange)
  end repeat
  
  
set tmpSize to outAttr’s |size|()
  
set tmpWidth to retWidthFromSize(tmpSize) of me
  
set the end of outList to {tmpWidth, outAttr}
  
  
return outList
end splitAttributedStringByLines

on retWidthFromSize(tmpSize)
  if class of tmpSize = record then
    –macOS 10.10, 10.11, 10.12
    
set tmpWidth to width of tmpSize
  else
    –macOS 10.13, 10.14
    
set tmpWidth to first item of tmpSize
  end if
  
return tmpWidth
end retWidthFromSize

on generateAttributedString(aStr, aFontPSName, aFontSize, aColor)
  set tmpAttr to NSMutableAttributedString’s alloc()’s initWithString:aStr
  
set aRange to current application’s NSMakeRange(0, tmpAttr’s |length|())
  
set aVal1 to NSFont’s fontWithName:aFontPSName |size|:aFontSize
  
tmpAttr’s beginEditing()
  
tmpAttr’s addAttribute:(NSFontAttributeName) value:aVal1 range:aRange
  
tmpAttr’s addAttribute:(NSForegroundColorAttributeName) value:aColor range:aRange
  
tmpAttr’s endEditing()
  
return tmpAttr
end generateAttributedString

★Click Here to Open This Script 

Posted in Clipboard list Record RTF Sort | Tagged 10.12savvy 10.13savvy 10.14savvy Keynote NSAttributedString NSColor NSFont NSFontAttributeName NSForegroundColorAttributeName NSMutableAttributedString NSPasteboard | Leave a comment

as anything

Posted on 4月 3, 2019 by Takaaki Naganoya

as anythingについてまとまった情報がなかったので、まとめておきました。結論めいたものはとくになく、ただ、手持ちの情報を並べてみただけの内容なのでご容赦ください。「これはこうあるべき!」とかいう提言とかは一切ありません。

割と最近なas anythingとの遭遇

つい最近まで、ながらく存在自体を知らなかったのが、このanythingという予約語です。

AppleScriptの用語辞書をASObjC Explorer 4で書いて試していたとき、パラメータの型に「any」というものが存在していることには気づいていましたが、それでも「anything」という予約語があることには気づきませんでした。

本格的に知ったのは、applescript-stdlibを漁っていたときです。

同ライブラリはトリッキーなScriptの記述方法の見本市みたいになっていて、内容自体の完全理解についてはサジを投げた状態でしたが、見たことのない記述にいろいろ行き当たりました(もっと読みやすく書いてほしかった ^ー^;;)。

delegateの呼び出し先にscriptオブジェクト内部のハンドラを指定したりと、「そんな書き方できるんだ。やらんけど」と、まるで古文書をひもとくような感覚(これを見ていると、こーゆー風にblocks構文をAppleScriptでも記述できればいいのに、と思います)。

そこで見つけた「as anything」表記。これは一体なんなんでしょう?

いい加減に使えてとても便利なas anything

実際に動かしてみたところ、「あーー、この機能昔から欲しかったわー」という内容でした。anonymous classとでもいうのでしょうか。castするときにclass名を指定しないワイルドカードなclassと理解しました。

「as anything」でAppleScriptのデータ型はそのまま、AppleScriptのデータ型にcast可能なCocoaのデータはAppleScriptのデータ型に変換。変換不能なCocoaのデータ型についてはそのまま、という処理をしてくれます。

# ただし要素数が1つのNSArrayをas anythingでAppleScript Objetに変換すると、listではなく中身のデータが取り出されてしまう(型が合わなくなる)ので、注意が必要とのこと(Thanks Shane!)
# なので、あらかじめNSArrayが返ってくることがわかっている場合には、as list。NSArrayか他のデータ(missing valueとか)が返ってくる場合には、as {missing value, list} などとするとよいでしょう

BridgePlus的にいえば、「ASify without BridgePlus」といったところでしょうか。CocoaとAppleScriptの間でデータをやりとりするのにえっらく都合がよかったのです。かくして、「as anything」を愛用しまくるスタイルが確立。

ただ、anythingは言語仕様のはざまで埋もれかけていた「枝葉末節」の中の一番の「枝葉」ともいうべき、言語仕様の極北。AppleScript Language Guideにも記載されていないほどの枝葉仕様。

AppleScriptObjCのプログラム中に書くと、予約語が用意されていないためか「as anything」が「as list of string or string」などと解釈されてしまいます(動作自体はanythingと同じ)。

anythingについては、Apple側がわりとぞんざいに仕様を放置していたきらいがあります。問題が起こらないかぎり放っておこう、と。as «class isot»のようにある日突然(Mac OS X 10.5で)消えてなくなったりしないかちょっと不安に感じたこともありましたが、一応まがりなりにも予約語が割り振られているので(生Apple Eventを記述させられないので)、そんなに簡単に消えないとは思います。

主要開発環境で足並みそろわず

雑に放置していたAppleに対して、この問題に正面から向き合っていた集団が存在します。それが、Script DebuggerのメーカーであるLate Night Softwareです。

macOS 10.12や10.13上ではあいかわらずASOCのプログラムでは「as anything」が「as list of string or string」と解釈されますが、macOS 10.14で対応に差が出ました。

Script Debugger上では「anything」が「any」と解釈され、スクリプトエディタ上では「anything」と解釈されます。

macOS 10.14上でのスクリプトエディタで「as anything」が「as list of string or string」のように化けないのはいいと思います。ただ、Script DebuggerのメーカーであるLate Night Software側ではこれに「any」という別の予約語を割り振ったようで、、、、足並みがそろっていません。

一応、macOS 10.14上のスクリプトエディタv2.11上で「as anything」と記述したScriptを、同じくmacOS 10.14上のScript Debuggerに持っていくと「as any」と表示されます。いったん中間コードにコンパイルされたものは問題がないようです。

問題になるのは、Blogなどに掲載されている文字の状態のAppleScriptで、anythingについてはコンパイル(構文確認)時に気をつける必要がありそうです(メイン環境が10.14に移行していないのでちょっとまだ他人事)。

困ったときの古文書だより

一応、現代AppleScriptのルーツの資料とされている「AppleScriptLanguageGuide 1.3.7」(1999/5/5)のPDFを確認してみると、けっこう悩ましい内容が記述されています。

自分はanythingをclassか何かだと思っていたのですが、そこには定数(constants)だと書かれています。AppleScript version 1.3.7のころには、missing value(不定値)みたいな運用が行われていたようです。

AppleのEngineering Teamの見解は?

匿名希望の方がApple Engineering Teamに問い合わせしたところ「そんなマイナーな予約語は使うな」という返答であったとか。その一方でmacOS 10.14で「anything」の「list or list of string」への解釈化けが抑止されたりしているわけで、いまひとつわかりにくいというのが現状です。

Posted in OSA | Tagged 10.12savvy 10.13savvy 10.14savvy Script Debugger Script Editor | Leave a comment

MP3ファイルからMP3タグの情報を取得

Posted on 4月 1, 2019 by Takaaki Naganoya

MP3ファイルからMP3タグの情報を取得するAppleScriptです。

とりあえず「取り出せることを確認した」というレベルの実装で、取り出したデータをタグに応じた加工を行うといった処理はほとんど書いてありません。各自よろしくお取り扱いください(投げやり)。

正直、Musicフォルダ以外に転がっている野良MP3ファイルから直接MP3タグ情報を読まなくても、iTunes.appにインポートしておいて、iTunes.appやらiTunesLibrary.framework経由で楽曲ファイルにアクセスしたほうが(データ形式のゆらぎを吸収してもらえるため)安全で楽です。

AppleScript名:MP3ファイルからMP3タグの情報を取得.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/04/01
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
— 参照先:http://d.hatena.ne.jp/terazzo/20120107/1325967445
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use framework "AVFoundation"
use scripting additions

property |NSURL| : a reference to current application’s |NSURL|
property NSImage : a reference to current application’s NSImage
property AVURLAsset : a reference to current application’s AVURLAsset
property AVMetadataFormatID3Metadata : a reference to current application’s AVMetadataFormatID3Metadata
property AVMetadataCommonKeyAlbumName : a reference to current application’s AVMetadataCommonKeyAlbumName

set aPath to POSIX path of (choose file of type {"public.mp3"})
set aMP3Info to getMP3TagsFromFile(aPath) of me

on getMP3TagsFromFile(aPath)
  set aURL to |NSURL|’s fileURLWithPath:aPath
  
set anAsset to AVURLAsset’s assetWithURL:aURL
  
  
set aRes to (anAsset’s availableMetadataFormats()’s containsObject:(AVMetadataFormatID3Metadata)) as boolean
  
if aRes = false then return false
  
  
set origMetadata to (anAsset’s metadataForFormat:(AVMetadataFormatID3Metadata)) as list
  
set outList to {}
  
  
repeat with i in origMetadata
    set aKey to (i’s |key|()) as list of string or string –as anything
    
set bKey to i’s commonKey() as list of string or string –as anything
    
    
if aKey = "PIC" or aKey = "APIC" then
      set aVal to (i’s value())
      
set aVal to (NSImage’s alloc()’s initWithData:aVal)
    else
      set aVal to (i’s value()) as list of string or string –as anything
    end if
    
set the end of outList to {aKey, bKey, aVal}
  end repeat
  
  
return outList
end getMP3TagsFromFile

★Click Here to Open This Script 

Posted in file | Tagged 10.12savvy 10.13savvy 10.14savvy AVURLAsset NSImage NSURL | Leave a comment

Blogアーカイブ本の作成時に利用するAppleScript

Posted on 4月 1, 2019 by Takaaki Naganoya

「AppleScriptの穴」Blogアーカイブ本の作成作業には、大量のAppleScriptが使用されています。編集や執筆といった地味で地道な作業には、自動化のテクノロジーを投下しないととてもやっていられません。

「生きた事例」としてそれらをどのように使っているかをご紹介します。

・指定フォルダ以下にあるMDとPagesをソートしてPDFに書き出して連結 v4(連続複数出力可能、末尾空白ページ削除)

MarkdownによるPDF書籍の作成時にはなくてはならないScriptです。指定フォルダ以下のMarkdownとPages書類をすべてSpotlightで取得し、順次デスクトップにPDFで書き出しを行い、それらを連結します。PDFは記事単位で生成され、明示的な空白ページ(1ページの空白書類)以外の連結時には最終ページが空白であるかのチェックを行い、空白時には削除したうえで連結します。

「連続複数出力可能」というのは、複数の書籍の順次出力をサポートしているという意味です。Book1こと「AppleScript最新リファレンス」とBook2こと「最新事情がわかるAppleScript 10大最新技術」を同時に作成したので(作成期間が実質1か月ちょっとでしぬかと思いました)、その時に両方とも同時に全記事のPDF出力を行えるよう開発。複数の書籍のフォルダを指定して順次出力を行います。さすがにこれはBlogに載せていません。

電子書籍の執筆中は執筆しながら体裁を確認し、出力用のツールScriptも開発して「筆者」「編集者」「デザイナー」「開発者」という1人で何役もこなして目が回っていましたが、ツール類は一度作れば作業効率を大幅に上げたまま別の仕事(Blogアーカイブ本、とか)に使用できるのでたいへんに役立っています。自分が「原稿を書くだけの人」だったら、バイトを雇ったりしないととてもやっていられません。

また、これにInDesignの書類やPDF原稿を含めるように機能追加してもいいわけで、非常に拡張しやすく、システム化のためのベースとして活用したいところです。

・Skimのcurrent page indexをNumbers上のセルに転送してカーソル移動

PDFのTOCのデータをNumbers書類上に作成するさいに使用しています。Skimで現在表示中のページ番号をNumbersの表中の選択中のセルに文字列で転送し、Numbers上のカーソルを下方向に1つ移動させます。いいかげんTOCのデータ作成も全自動化したいところですが、PDF上で確認しつつ半自動で作成しています。それでも、すべて手作業で行うよりははるかに労力を削減できています。

・Numbersの最前面の書類からデータを取り出して指定PDFのTOCを作成する v2.scptd

Numbers上に作成したTOC(PDFしおり)データから実際に指定のPDFに階層構造つきTOCを作成するAppleScriptです。「TOCなしの数百ページのPDFなんか読みたくない」「TOCつけろ」という読者の方のありがたいアドバイスにより実戦投入。いまのバージョンはNumbersの表中の選択中のセルからデータを取得しているので、選択しなくても大丈夫なように、、、、書き換えておきます。こうして、作業上問題が発生しそうな箇所はつねにアップデートしています。

・現在表示中のページをJPEG画像で書き出す

Skim用のAppleScriptです。販売サイトに掲載する表紙などの紹介画像を作成するさいに、Skimで表示中のPDFから表示中のページの内容をJPEG画像としてデスクトップに生成します。このあたりを自動化していないと、サンプルページの掲載だけでも相当手間がかかります。

・PDFから指定ページ以降を削除

販売物を掲載したあとに、「お試し版」PDFを作成する段階で使用します。指定PDFから指定ページ以降をすべて削除するものです。これでおおよそ削除しておいてから、Adobe Acrobatで編集してTOCのうちページが存在しないものを削除したり、こまかいページの削除を行なっています。

Posted in How To PDF | Leave a comment

Blogアーカイブ本 vol.4を販売開始

Posted on 4月 1, 2019 by Takaaki Naganoya

知り合いの本Blog愛読者の方々から「アーカイブ本まだ?」と言っていただいて幾星霜。ちょっと手が空いてしまったので、Blogアーカイブ本に着手しました。ここに、Blogアーカイブ本のVol.4(2011〜2012年)の発売をお知らせいたします。

→ オンライン販売ページ
→ お試し版ダウンロードページ

本Blog「AppleScriptの穴」は、開設10年目を迎える直前の2018年1月末に、格安ホスティングサービス「Xserver」との間の手違いでDBがシャットダウンされ、そのままの形で公開し続けることができなくなってしまいました。

そこで、AppleScriptのプログラムによるFinder上のAppleScriptの自動HTML化、AppleScriptによるXML-RPC経由でのWordPressへの自動記事投入といったさまざまなソリューションを投下して、現在の登録記事数に復旧。自動記事投入による復旧を行なったために、当時の作業環境でオープンできない(OSバージョン依存、アプリケーション依存)Scriptについては掲載を見送っています。

 旧AppleScriptの穴:2008〜2018年 Mac OS X 10.4〜10.5の時代に開設
 現AppleScriptの穴:2018年〜   Cocoa APIを呼びまくる現在のスタイルが定着

自動投入可能なコンテンツを優先して掲載したため、旧Blogと現Blogでは掲載内容が大幅に変わっています。別物といってよいでしょう。

そのため、Cocoa APIを使用しない「オールドスタイルのAppleScript」については再掲載が難しく、このBlogアーカイブ本シリーズにしか情報をまとめていません。

旧Blogアーカイブ本シリーズも、1年ごとに区切って記事をPDF化して4冊目。この頃の記事投稿数が少なかったので、Vol.4は2011年1〜2012年12月の2年分の内容をまとめています。全450ページ、2,000円。ファイル形式はPDFで、キーワードによる全文検索や印刷が行えます。

また、OS X 10.8のAppleScriptに巨大なバグが存在しているため、巻頭にてその内容や回避策についての解説を行なっています。

もちろん、各プログラムリスト末尾にURLリンクをそなえ、ワンクリックでプログラム内容をスクリプトエディタに転送可能です。

ほとんどの掲載プログラムについてコメントを行い、現時点(2019年時点)で評価してどうか、ということを追記しています。

AppleScriptの穴Blogアーカイブvol.4

リスト同士のdiffをとる
日本の月呼称を返す
指定の月を1月分リスト化
指定日がその月の中で何週目かを求める
指定日がその月の中で何週目かを求めて、週リストを取得する
与えられたリストに、値がヌルの要素が入っているか判定し、フラグ、ブランク開始終了位置を返す v2
iCalで選択中のイベントのカレンダー情報を取得する
画面の解像度を取得するv3
画面の解像度を取得するv4
シェルソートでリストをソート
Numbersでtableの縦サイズをふやす
リストで与えられたデータの変動ベクトル方向を取得する
Photoshopでオープンしている画像から、選択部分のサイズをもとに画像分割を行う
フォルダ内の画像ファイルを順次Numbersのセルに貼り付ける
2行に別れているデータを1行分にまとめる
指定年のすべての日付をdateオブジェクトで取得する
指定のテキストをAppleScriptとしてコンパイルし、実行可能なアプレットとして出力する
サウンド入力元、出力先の名称をリストで取得する
サウンド入力元、出力先を設定する
サウンド入出力の選択中の項目名を取得
InDesign CS3でBookを作成するテスト
Mail.appでメールの送信(プレーンテキストへの変換つき)
分布リスト作成 v1
入れ子のリストをタブ区切りのテキストに
コードのチェック
数値リストを連続部分に分解する(アイテム番号を返す)
数値リストを連続部分に分解する(データを返す)
AppleScriptによる並列処理 v2
AppleScriptによる並列処理 v2〜実際に使ってみての評価
スリープ復帰日時を設定する
ファイルのファイル名を求める
AppleScriptによる並列処理v3a
QuickTimeムービーの縦横ドット数を取得する
iTunes 10.3β AppleScript用語辞書に変更なし
リスト中の値が連続する箇所をアイテム番号のリストで返す
FileMaker Proで書き出したTab区切りテキストファイルをExcelで読み込む
リスト中の値が連続する箇所をアイテム番号のリストで返す v2
Keynoteの各slideのtitleで、同じものが続く箇所に連番を振り直す
指定のデジカメ画像のExif情報から指定のプロパティを取得する
SIGMA Raw画像からメーカーと機種名を取り出す v2
子番号を考慮しつつ、新しいファイル名を返す
文字列末尾からスペースを削る
指定アイテム以降は指定アイテム目に改行で区切って連結する
指定矩形内に含まれるデータをアイテム番号で返す
数字の文字が入っているかどうかをテストする
文字列の先頭と末尾に指定文字が存在した場合にはトリミングして返す
Photoshopで指定座標のカラー値をRGB値で返す
Safari 5.1でWeb検索
OS X 10.7, Lionへの移行について
リスト同士の引き算、足し算
印刷可能なプリンタ一覧から選択してプリント実行 10.4〜10.7
1〜指定数までの乱数を返す、ただし別途指定の数(aException)を除く
指定フォルダ内のPDFの1ページ目のみ取り出して別フォルダに保存 v2
TextWranglerで連続置換を指定フォルダ内のhtmlファイルに対してすべて実行
Mail.appで添付ファイルを指定してメール送信
文字列中に指定文字が何個入っているかカウントする v2
Safari 5.1.1、iPhoto 9.2が登場。AppleScript用語辞書に変更なし
指定アプリの指定タグの文字列をアプリ内のLocalizableStringsから取得する
指定アプリの指定タグの文字列をアプリ内のLocalizableStringsから取得する v3
投稿も受け付けています
Excel 2011で表示中のワークブック内のすべてのシートの表示状態を変更する v2
XcodeのAppleScript用語辞書の変遷
Xcode 4.2.1、iTunes 10.5.1登場。AS用語辞書に変更なし
OmniGraffleで指定書類からURLつきの画像の情報を集める
OmniGraffleで指定文字を名前に含むドキュメントをオープンしているかチェック
指定名称のOmniGraffle書類中に、urlListで示した名称のCanvasが存在するかを取得する
指定名称のOmniGraffle書類中に、urlListで示した名称のCanvasが存在するかを取得する v2
与えられたリスト中のfalseの項目番号をリストで返す
OmniGraffleで指定ドキュメントのWindowを求める v2
OmniGraffleで表示中のCanvasを切り替えてループし、各Canvasの表示倍率を取得する
OmniGraffleで表示中のCanvasを切り替えてループし、各Canvasの表示倍率を設定する
OmniGraffleでcanvas名一覧を取得する
OmniGraffleで画面設計図のCanvas名称をクリーニングする
OmniGraffleで指定名称の書類の現在表示中のCanvas上から、URLつきの画像(Solid)の情報を集める
OmniGraffleで選択中のグラフィックのサイズを50%にする
Safari 5.1.2、AppleScript用語辞書に変更なし
OmniGraffleで各ページに用意したtitleから、目次を作成する
リストから指定のアイテムを削除する(1項目)
Canvasの大きさを取得(Pointで返る)
リンクつき目次を作成する v1
現在表示中のCanvasに存在しているラインのうち青いものに影を付ける
通常版のOmniGraffleでProfessional版でしか作れない「表」を作る
最前面のドキュメントの全Canvas上のグラフィックがそれぞれグループ化されていないかチェック。されていなければグループ化
Numbersで選択中のデータをもとにOmniGraffleの選択中のグラフィックのサイズで表作成
「A x B = C」の数の組み合わせを求める
「YxX」の形式の文字列を、{Y,X}のように数字のリストにして返す
miで選択中の内容をファイルに書き出してperlのプログラムとしてterminalで実行
与えられたテキストをPhotoshopでRGBデータと評価してCMYK値を返す
ファイル選択ダイアログを表示して、パスを取得する(Perl中へのAppleScript埋め込み)
AppleScriptObjCのメモリー浪費現象を解決?!
近似式によるRGB→CMYK/CMYK→RGB変換
PhotoshopでRGB→CMYK、CMYK→RGB変換
Excel 2011で現在オープン中の書類の選択中のシートをCSV書き出し
Mac App Store公開アプリのSandbox対応義務化 期限が6/1に延期
Excel 2011ですべてのタブのデータを取得して1つにまとめる v3
自然言語による相対日付指定v13
AppleScriptで正規表現(regexp)を
tellブロックの書き方いろいろ
Excel 2011で現在表示中のウィンドウのすべてのタブのズーム倍率を変更する
curlでダウンロードv2
100倍速いシェルソートでリストをソート
Excelの表中のデータを拾ってセルに色を付ける
InDesign CS3で指定のオプジェクトを、JPEG書き出ししてiPhoneへ
NSTextViewからのテキストデータ取得、テキスト設定サンプル
インストールされているアプリのAS辞書を書き出すv2
AppleScriptレコードのラベルのリストを作成
iPhoto, iTunes, Safariアップデートについて
QuickTime 7で録画して任意のファイル名で保存
Microsoft Office v2011 14.2.1アップデートで辞書に変更なし
ASObjC Runner〜ASOCの機能にAppleScript的な記法を
指定文字列から、指定ペア文字で囲まれる部分を削除。前方からスキャンして削除実行
offset ofの高速実行
指定ハードウェアポートのデバイス名を取得する v1.1
無線LANの電源のONOFF
無線LANネットワークを指定して接続する
簡易マクロ展開つきのコードチェック v1
日本語数値表現エンコードされた数値のparseテスト v2
EPSファイルの破損チェック(高速版)
インターネットのサービスを利用して日本国内の天気予報を取得する
WWDC2012のビデオが公開に
任意の桁数の2進数文字列を10進数に戻す
16進数文字列を10進数数値に変換する
HTMLコードのRGB 16進数コードを数値リストに変換
Numbersで指定範囲を高速に埋める
TidBitsがMountain Lion上のAppleScriptのルール変更について解説
iPhoneアプリをAppleScriptからコントロール
指定フォルダ内のPDFの空白ページ以外を個別に取り出して別フォルダに保存 v3
通知センター経由でTwitter投稿(10.8用)v2
Mail 4.0->6.0の移行でAppleScript関連機能の変更が発生
Skimでオープン中のPDFの現在のページの内容をOmniGraffleにペースト
OS X v10.8.2 追加アップデート 1.0がMail.appのAppleScript系のバグを修正
FTPソフトウェア「Transmit」の基礎的なスクリプティング(1)
Safari 6で指定のURLをオープンする
Transmitで指定のファイルを指定のお気に入りサーバーにアップロード
PhotoshopでJavaScript経由でEPS/PDFをオープン
指定フォルダが共有されているかチェック

Posted in Release | Leave a comment

Post navigation

  • Newer posts

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

Google Search

Popular posts

  • macOS 13, Ventura(継続更新)
  • アラートダイアログ上にWebViewで3Dコンテンツを表示(WebGL+three.js)v3
  • Xcode 14.2でAppleScript App Templateを復活させる
  • UI Browserがgithub上でソース公開され、オープンソースに
  • macOS 13 TTS Voice環境に変更
  • 2022年に書いた価値あるAppleScript
  • ChatGPTで文章のベクトル化(Embedding)
  • 新発売:AppleScriptからSiriを呼び出そう!
  • iWork 12.2がリリースされた
  • 従来と異なるmacOS 13の性格?
  • 新発売:CotEditor Scripting Book with AppleScript
  • macOS 13対応アップデート:AppleScript実践的テクニック集(1)GUI Scripting
  • AS関連データの取り扱いを容易にする(はずの)privateDataTypeLib
  • macOS 13でNSNotFoundバグふたたび
  • macOS 12.5.1、11.6.8でFinderのselectionでスクリーンショット画像をopenできない問題
  • 新発売:iWork Scripting Book with AppleScript
  • ChatGPTでchatに対する応答文を取得
  • Finderの隠し命令openVirtualLocationが発見される
  • macOS 13.1アップデートでスクリプトエディタの挙動がようやくまともに
  • あのコン過去ログビューワー(暫定版)

Tags

10.11savvy (1101) 10.12savvy (1242) 10.13savvy (1390) 10.14savvy (586) 10.15savvy (434) 11.0savvy (277) 12.0savvy (186) 13.0savvy (59) CotEditor (60) Finder (47) iTunes (19) Keynote (99) NSAlert (60) NSArray (51) NSBezierPath (18) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (51) NSDictionary (27) NSFileManager (23) NSFont (18) NSImage (41) NSJSONSerialization (21) NSMutableArray (62) NSMutableDictionary (21) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (117) NSURL (97) NSURLRequest (23) NSUTF8StringEncoding (30) NSView (33) NSWorkspace (20) Numbers (57) Pages (38) Safari (41) Script Editor (20) WKUserContentController (21) WKUserScript (20) WKUserScriptInjectionTimeAtDocumentEnd (18) WKWebView (23) WKWebViewConfiguration (22)

カテゴリー

  • 2D Bin Packing
  • 3D
  • AirDrop
  • AirPlay
  • Animation
  • AppleScript Application on Xcode
  • beta
  • Bluetooth
  • Books
  • boolean
  • bounds
  • Bug
  • Calendar
  • call by reference
  • Clipboard
  • Code Sign
  • Color
  • Custom Class
  • dialog
  • drive
  • 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
  • Machine Learning
  • Map
  • Markdown
  • Menu
  • Metadata
  • MIDI
  • MIME
  • Natural Language Processing
  • Network
  • news
  • Noification
  • Notarization
  • Number
  • Object control
  • OCR
  • OSA
  • 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)
  • 未分類

アーカイブ

  • 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