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

タグ: 14.0savvy

macOS 14.xでAppleScriptのバグ

Posted on 5月 25, 2024 by Takaaki Naganoya

Hi @Apple,

just a quick note on a serious #Sonoma #bug.

get " " as integer
(this line crashes)

Can someone please address this at the right spot?

(@applescripter, @applescriptguru, @applescript, @AppleScriptive, @Applescrip52206, @AppleS31305, @AppleScript12, @AppleScripter_)

— Torben Johannson (@BunterLotentony) May 24, 2024

空白文字をintegerにcastすると、処理系ごとクラッシュするというバグです。macOS 13.xではエラーになります(通常の動作)。

macOS 14.5ではクラッシュ(スクリプトエディタ上で動かせばスクリプトエディタがクラッシュ)します。

ほかにもいろいろあるんですけど(ーー;;;;;

macOS 15.0での修正

macOS 15では、下記のScriptの実行結果が数値の0を返すようになりました。

AppleScript名:sonomacrasher.scpt
get " " as integer

★Click Here to Open This Script 

Posted in Bug | Tagged 14.0savvy | Leave a comment

Keynote上で選択中のテキストアイテムを、位置情報をもとにテキスト連結してクリップボードへ

Posted on 5月 13, 2024 by Takaaki Naganoya

Keynoteで作業がめんどくさくなったら、その場でAppleScriptを書いて使うシリーズ。Keynote v14で動かしていますが、別にバージョン依存している箇所はありません。もっと古いKeynoteでも動くと思います(KeynoteのAppleScript対応機能的には、slideのselectionができるようになったv12が実用下限だと思っています)。

Keynote書類の、章トビラに内容を個別のテキストアイテムで箇条書きしていたような場合に、

これを、全部結合して1つのテキストアイテムに入れたくなる時があります。

そこで、本ScriptのようなものをmacOS標準搭載のスクリプトメニューに入れて、

呼び出すために作ったものです。

実行すると、それぞれのテキストアイテムをY座標に着目してソートを行い、上→下の順番にならべかえて、テキストを取り出し、改行をはさみつつ連結します。

この後で、もとのテキストアイテムにこの連結したテキストを入れることになります。

一番上(positionのY座標が一番小さい)のテキストアイテムだけ残してあとは削除するわけですが、このあたりのオブジェクト操作もAppleScriptから操作してしまったほうがよさそうです。

ただし、Keynoteはテキストアイテム内の文字の上寄せ/下寄せの制御をAppleScriptからできないので(キーボードショートかメニューでも操作する?)そのあたりに「残念感」が残ってしまうかもしれません。

macOS標準搭載のスクリプトメニューに入れるAppleScriptで、絵文字を大量に入れるのは、大量のAppleScriptをメニューに入れるため文字だけだと視認性が低く、色付き文字を入れてそれぞれを識別しやすくするためです。

AppleScript名:🧭位置情報🧭をもとに🈴テキスト連結🈴して📎📎クリップボードへ📎📎.scpt
use AppleScript
use scripting additions
use framework "Foundation"

set outList to {}
set outStr to ""

tell application "Keynote"
  tell front document
    set aSel to selection
    
    
if length of aSel = 0 then
      display dialog "Keynote書類上で何も選択されていません。" with title "オブジェクト選択エラー" buttons {"OK"} default button 1 with icon 2
      
return
    else if length of aSel = 1 then
      display dialog "Keynote書類上で複数のオブジェクトが選択されていません。" with title "オブジェクト選択エラー" buttons {"OK"} default button 1 with icon 2
      
return
    else if (class of first item of aSel = slide) then
      display dialog "Keynote書類上でスライドが選択されてしまっています。" with title "オブジェクト選択エラー" buttons {"OK"} default button 1 with icon 2
      
return
    end if
    
    
repeat with i in aSel
      set j to contents of i
      
set aClass to class of j
      
if aClass = text item then
        set {aPosX, aPosY} to position of j
        
set aCon to object text of j
        
set the end of outList to {xPos:aPosX, yPos:aPosY, textCon:aCon}
      end if
    end repeat
    
  end tell
end tell

set bList to sortListAscending(outList, "yPos") of me

repeat with i in bList
  set j to contents of i
  
set aText to textCon of j
  
set outStr to outStr & aText & return
end repeat

set the clipboard to outStr
beep 1

–入れ子のリストを昇順ソート(AppleScriptObjC)
on sortListAscending(theList as list, keyLabel)
  set anArray to current application’s NSMutableArray’s arrayWithArray:(theList)
  
set theDescriptor to current application’s NSSortDescriptor’s sortDescriptorWithKey:(keyLabel) ascending:(true)
  
set sortedList to anArray’s sortedArrayUsingDescriptors:{theDescriptor}
  
return sortedList as list
end sortListAscending

★Click Here to Open This Script 

Posted in list Object control Record Sort | Tagged 12.0savvy 13.0savvy 14.0savvy Keynote | Leave a comment

Keynoteで2階層のスライドのタイトルをまとめてテキスト化

Posted on 5月 10, 2024 by Takaaki Naganoya

Keynoteでページ数の多い書類、この場合は電子書籍「Cocoa Scripting Course」の9巻「File Processing」で章ごとの目次を作ろうとしたときに、各ページのタイトルを記事のレベルを反映しつつ文字列化するのが大変なので、AppleScriptで半自動化しました。

実際には、機械的に全スライドのタイトルを取得してテキスト化するAppleScriptを作って使っていたのですが、機械的にタイトルを取り出したあとで、レベルを反映させるといった「手作業」が発生していたので、半自動処理に変更したほうがまだ作業量が少なくなるという見立てになりました。

Keynote書類をオープンして、最終階層のスライドを畳んだ状態で処理範囲(同一レベルのスライド)を選択しておいた状態で本Scriptを実行します。もともと、章トビラに掲載する内容をテキストで取り出すためのものなので、1つの章を構成する中トビラのみを選択した状態にしてから実行する必要があります。

Keynoteでは、ウィンドウ左端にナビゲータを表示させ、各スライドのレベルを変更し、アウトラインプロセッサのように下位スライドの表示を隠したり、表示させたりできます。つまり、ページ数の多いスライドの整理を行いやすくなっています。

本来、このスライドのインデントレベルを数値で取得できる必要があります。それでも、KeynoteのAppleScript用語辞書にその機能は実装されていません。ただ、ないものにないと文句を言っているだけでは前に進めません。

Keynoteのウィンドウ上で下位スライドを非表示状態にして選択すると、selection中の第1階層のスライドのみ選択された状態になるため、スライド番号を取得すると、selection中の第2階層のスライド番号が「抜けた」状態になります。この違いによってスライドの階層を識別できます。

スライド番号を取得できたselection中の第1階層のスライドと、スライド番号を取得できなかったselection中の第2階層のスライドで別々に処理(インデント文字=tab)することで、文字列で階層の違いも表現できます。

出力例:

◽️再帰処理によるファイル検索  –第1階層
  再帰によるファイルパスの取得  –第2階層
  再帰によるファイルパスの取得+拡張子による抽出  –第2階層
  ファイル名衝突回避つきリネーム  –第2階層

処理結果はクリップボードに転送されます。つまり、他のテキストエディタに内容をそのままペーストできます。

スライドのインデントレベルを取得できないことへの対処は、スライドのbase layoutにインデント情報を書いておくとか、種別で判定するやりかたもあります。出現確率をそれぞれのbase layoutについて計算し、登場頻度の低いものをより上位の章トビラとして認識するといったAppleScriptもありますが、完全自動よりも決定前にユーザーに確認を取るぐらいの作りになっているほうが実用性が高い感じです。

AppleScript名:選択中のスライドから、2段階の階層のタイトルを取得してクリップボードへ.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/05/04
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

use AppleScript
use framework "Foundation"
use scripting additions

property headerChar : "◽️" –1階層目のタイトルの行頭に入れる
property indentChar : tab –2階層目のタイトルの行頭に入れる

tell application "Keynote"
  tell front document
    set aSel to selection
    
set aFirst to class of first item of aSel
    
if aFirst is not equal to slide then
      display dialog "スライド単位で選択されていません(スライド内のオブジェクトが選ばれている)" buttons {"OK"} default button 1
      
return
    end if
    
    
–スライドの逆順選択が発生していた場合には、listを逆順に入れ替えて正順(開始ページ→終了ページ)に修正  
    
set fItem to slide number of first item of aSel
    
set lItem to slide number of last item of aSel
    
if fItem > lItem then set aSel to reverse of aSel
    
    
–スライド番号を選択部分から取り出す
    
set pNumList to {}
    
repeat with i in aSel
      set the end of pNumList to (slide number of i)
    end repeat
    
    
–選択中の最終スライドの次のスライドは説明部分とみなし、説明部分が続く(同じベースレイアウト)ブロックを検出
    
set totalCount to count every slide
    
set aMasterSlide to base layout of slide ((last item of pNumList) + 1)
    
set hitF to false
    
    
repeat with i from (last item of pNumList) + 2 to totalCount
      set tmpBase to base layout of slide i
      
if aMasterSlide is not equal to tmpBase then
        set hitF to true
        
exit repeat
      end if
    end repeat
    
    
if hitF = false then error "Page selection Error"
    
    
—末尾の情報を補う。そのため、本Scriptではスライド末尾までの選択が行えないが、実用上問題がないので無視している
    
copy i to lastThreadShould
    
copy pNumList to pNumList2
    
set the end of pNumList to i
    
    
    
–メインループ
    
set outList to {}
    
set aCount to 1
    
    
–1階層目のタイトル収集ループ
    
repeat with i in (pNumList2)
      
      
tell slide i
        try
          set tmpTitle1 to object text of default title item
        on error
          set tmpTitle1 to "" –タイトルが存在しないスライドなどの場合
        end try
      end tell
      
      
–オブジェクト内の強制改行文字を削除
      
set tmpTitle13 to repChar(tmpTitle1, string id 8232, "") of me
      
      
–出力用のリストに追加
      
set the end of outList to (return & headerChar & tmpTitle13)
      
      
–2階層目のタイトル収集ループ
      
repeat with ii from (i + 1) to ((item (aCount + 1) of pNumList) – 1)
        if ii ≥ (lastThreadShould) then exit repeat
        
        
tell slide ii
          try
            set tmpTitle2 to object text of default title item
          on error
            set tmpTitle2 to "" –タイトルが存在しないスライドなどの場合
          end try
        end tell
        
        
–オブジェクト内の強制改行文字を削除
        
set tmpTitle22 to repChar(tmpTitle2, string id 8232, "") of me
        
        
–出力用のリストに追加
        
set the end of outList to (indentChar & tmpTitle22)
      end repeat
      
      
set aCount to aCount + 1
      
    end repeat
    
    
–クリップボードに結果文字列を設定
    
set outStr to retListedText(outList, return) of me
    
set the clipboard to outStr
  end tell
end tell

–1D Listにデリミタ文字を入れつつテキスト化
on retListedText(aList, aSeparator)
  set aText to ""
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aSeparator
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retListedText

–文字置換ルーチン
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

★Click Here to Open This Script 

Posted in Object control | Tagged 13.0savvy 14.0savvy Keynote | Leave a comment

Keynoteでslideの逆順選択状態を解消する

Posted on 5月 9, 2024 by Takaaki Naganoya

Keynoteで日々さまざまな書類を作っており、Keynoteを使わない日はないと言って過言ではないほどです。

当然、Keynote関連の作業の効率化のためのAppleScriptを書くことが多くなります。そして、Keynote書類の連続したスライド(ページ)を選択し、それらのタイトルを加工するようなAppleScriptをよく使います。

たとえば、マル付き数字(例:①②③)の付け直し(リナンバー)AppleScriptはよく使いますが、

Keynote上で末尾ページから先頭ページに向かってページ選択できる、いわば「逆順選択状態」を画面上からの操作によって作り出せてしまうことに気づきました。

この状態でAppleScriptからselectionを取得すると、P-197、196、195、194、193、192、191と、意図しない順番でスライドオブジェクトを取得できてしまうことがわかりました。この逆順選択状態で、マル付き数字のリナンバーScriptを実行すると、末尾から番号が振られてしまいます。

この状態は、たとえば197ページを選択しておいて、SHIFTキーを押しながら、上向き矢印キーを押すことで選択範囲を拡張した場合に発生することがわかりました。この現象は、Keynote v14.0+macOS 13.6.7で発生を確認しています。

これは、バグではありません。ただ、意図しない状態を作り出せてしまうことについては、知っておく必要がある内容です。

selectionでアクセスできるSlideオブジェクトが、かならずしもページの先頭方向から順に末尾方向へと並んでいるわけではない、ということで対策が必要になりました。この手の、複数Slideを選択して実行するAppleScriptは割と多いので。

そこで、selctionから取得したSlideオブジェクトの先頭と末尾のSlide numberを取得し、先頭のSlide Numberが大きければ、selectionから取得したデータをその場で逆順に並べ替えるという対処を行いました。

AppleScript名:スライドの逆順選択状態を解消する.scpt
tell application "Keynote"
  tell front document
    set aaSel to selection
    
set fItem to class of first item of aaSel
    
if fItem is not equal to slide then
      display dialog "Slide内のオブジェクトが選択されています。Slide単位で選択してください。" buttons {"OK"} default button 1
      
return
    end if
    
    
set fItem to slide number of first item of aaSel
    
set lItem to slide number of last item of aaSel
    
    
–逆順選択が発生していた場合には、listを逆順に入れ替える
    
if fItem > lItem then
      set aaSel to reverse of aaSel
    end if
    
    
set fItem2 to slide number of first item of aaSel
    
set lItem2 to slide number of last item of aaSel
    
return {fItem2, lItem2}
  end tell
end tell

★Click Here to Open This Script 

Posted in Object control | Tagged 13.0savvy 14.0savvy Keynote | Leave a comment

Keynote/Pagesで選択中の表カラムの幅を均等割

Posted on 5月 5, 2024 by Takaaki Naganoya

Keynote/Pagesの書類上の「表」のうち、選択中のカラムについて「幅」を均等割する(等しい幅に設定する)AppleScriptです。Keynote/Pages v14.0で動作確認していますが、とくにバージョン固有の機能などに依存する部分はありません。


▲Keynote書類上の表のカラムを選択しておいてAppleScript実行


▲Keynote書類上で選択しておいた表カラムが均等幅に設定される


▲Pages書類上の表のカラムを選択しておいてAppleScript実行


▲Pages書類上で選択しておいた表カラムが均等幅に設定される

AppleScript名:選択中の表カラムの幅を均等割.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/05/05
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

tell application "Keynote"
  tell front document
    set aSel to selection
    
set fObj to class of first item of aSel
    
if fObj is not equal to table then
      display notification "tableが選択されていません"
      
return
    end if
    
    
tell current slide
      try
        set theTable to first table whose class of selection range is range
      on error
        display notification "table中のセル(カラム)が選択されていません"
        
return –何も選択されてなかった場合
      end try
      
      
tell theTable
        
        
set vList to address of column of every cell of selection range
        
set vUList to uniquify1DList(vList) of uniquifyKit of me
        
        
–均等割したカラム幅を計算
        
set totalW to 0
        
repeat with i in vUList
          tell column i
            set tmpW to width
            
set totalW to totalW + tmpW
          end tell
        end repeat
        
        
–選択カラム幅に均等割した幅を設定
        
set aColW to totalW / (length of vUList)
        
repeat with i in vUList
          tell column i
            set width to aColW
          end tell
        end repeat
        
      end tell
    end tell
    
  end tell
end tell

script uniquifyKit
  use scripting additions
  
use framework "Foundation"
  
property parent : AppleScript
  
  
on uniquify1DList(theList as list)
    set theSet to current application’s NSOrderedSet’s orderedSetWithArray:theList
    
return (theSet’s array()) as list
  end uniquify1DList
end script

★Click Here to Open This Script 

AppleScript名:選択中のカラムの幅を均等割.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/05/05
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

tell application "Pages"
  tell front document
    set aSel to selection
    
set fObj to class of first item of aSel
    
if fObj is not equal to table then
      display notification "tableが選択されていません"
      
return
    end if
    
    
try
      set theTable to first table whose class of selection range is range
    on error
      display notification "table中のセル(カラム)が選択されていません"
      
return –何も選択されてなかった場合
    end try
    
    
tell theTable
      
      
set vList to address of column of every cell of selection range
      
set vUList to uniquify1DList(vList) of uniquifyKit of me
      
      
–均等割したカラム幅を計算
      
set totalW to 0
      
repeat with i in vUList
        tell column i
          set tmpW to width
          
set totalW to totalW + tmpW
        end tell
      end repeat
      
      
–選択カラム幅に均等割した幅を設定
      
set aColW to totalW / (length of vUList)
      
repeat with i in vUList
        tell column i
          set width to aColW
        end tell
      end repeat
      
    end tell
    
  end tell
end tell

script uniquifyKit
  use scripting additions
  
use framework "Foundation"
  
property parent : AppleScript
  
  
on uniquify1DList(theList as list)
    set theSet to current application’s NSOrderedSet’s orderedSetWithArray:theList
    
return (theSet’s array()) as list
  end uniquify1DList
end script

★Click Here to Open This Script 

Posted in Object control | Tagged 12.0savvy 13.0savvy 14.0savvy Keynote Pages | Leave a comment

指定のWordファイルをPDFに書き出す

Posted on 5月 4, 2024 by Takaaki Naganoya

ほとんど書き捨てレベルのAppleScriptですが、Microsoft Office用のAppleScriptの動作状況(ランタイム環境を変更すると動かなくなるなど)に興味があったので、書いてみました。

初回実行時にWord書類が入っているフォルダへのアクセス許可を求めるダイアログが出ますが、2回目以降はとくに聞かれません。

また、PowerPoint用のAppleScriptで、スクリプトメニューから実行すると実行がブロックされるという「Microsoft、正気か?」という仕様になっていましたが、いまMicrosoft Word用の本AppleScriptをスクリプトメニューに入れて呼び出しても実行できることを確認しています(macOS 13.6.7+Word バージョン 16.84 (24041420))。

AppleScript名:指定のWordファイルをPDFに書き出す.scpt
set aFile to choose file
automatorRun({aFile}, missing value) of me

on automatorRun(input, parameters)
  repeat with i in input
    set ipath to i as text
    
    
tell application "System Events"
      set o to name of i
    end tell
    
    
set o to repChars(ipath, ".docx", ".pdf") of me
    
    
tell application "Microsoft Word"
      close every document without saving
      
open i
      
save as document 1 file name o file format (format PDF)
      
close every document without saving
    end tell
  end repeat
  
  
return ""
end automatorRun

on repChars(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 repChars

★Click Here to Open This Script 

本Scriptを書くことになったreddit上の投稿への回答となるScriptはこちら。

AppleScript名:指定のWordファイルをPDFに書き出す(For Automator Action).scpt

on run {input, parameters}
  repeat with i in input
    set ipath to i as text
    
    
tell application "System Events"
      set o to name of i
    end tell
    
    
set o to repChars(ipath, ".docx", ".pdf") of me
    
    
tell application "Microsoft Word"
      close every document without saving
      
open i
      
save as document 1 file name o file format (format PDF)
      
close every document without saving
    end tell
  end repeat
  
  
return ""
end run

on repChars(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 repChars

★Click Here to Open This Script 

Posted in Object control PDF | Tagged 12.0savvy 13.0savvy 14.0savvy Word | Leave a comment

macOS 14.xでScript Menuの実行速度が大幅に下がるバグ

Posted on 4月 27, 2024 by Takaaki Naganoya

Late Nigt Softwareのフォーラムで、macOS 14.4.1上のスクリプトメニューから連絡先.app(住所録)を操作するAppleScriptを動かしたら、Script Debugger上の実行速度の27倍も時間がかかったという報告がありました。

基礎的なテストを行うために、コンスタントに時間がかかる処理でおなじみのPermutation(1次元配列の順列組み合わせ計算)をためしてみたところ、外部のアプリを操作しない処理内容にもかかわらず、この段階で8倍程度の時間がかかりました。外部アプリの操作を行うと、より一層時間がかかるもようです。

これは、macOS 11上でAppleScriptをM1のEコアで実行して、大幅にAppleScriptの実行速度が低下したバグを想起させるものです。

また、スクリプトメニューはAppleScript環境における「最終防衛ライン」です。このライン内にAppleによる妨害が行われると環境全体の有用性が大幅に下がってしまいます(もうそろそろ、Appleをあてにせずに自分でスクリプトメニューを作ることも考えてもいいのかも?)。

SED=スクリプトエディタ、MEN=スクリプトメニュー

6 digits
SED: 0.099387049675 seconds
MEN: 0.515756964684 seconds

7 digits
SED: 0.501626014709 seconds
MEN: 3.565899968147 seconds

8 digits
SED: 33.727347016335 seconds
MEN: 263.738371968269 seconds

これが、バグなのかAppleのエンジニアによる嫌がらせなのか、セキュリティ向上の美名のもとに行われている破壊活動なのかは不明ですが、こんなに処理速度を落とすことに正当な意味があるとは思えません。

また、「おまえんとこの最新鋭機種、10年前のへっぽこ最底辺マシンの10倍以上遅い処理があるぞ」とかバグレポートに書かれないと直さないんでしょうか? バグレポートに書く罵倒文句にもいい加減、在庫が尽きてしまいそうなのですが、、、

本件、AppleScriptランタイムに「osascript」を用いているものは、一律に遅くなっている可能性があるので注意が必要です、

Posted in Bug | Tagged 14.0savvy | Leave a comment

Cocoa Scripting Course #8, File path Processingを刊行

Posted on 4月 26, 2024 by Takaaki Naganoya

電子書籍「Cocoa Scripting Course」の第8巻、File path Processingを刊行しました。PDF 446ページです。

→ 販売ページ

本書は、Cocoa Scripting本の第8弾。ファイルパスの処理を基礎から応用まで幅広く扱っています。Cocoaの機能を使って圧倒的に高度なファイル処理を行いたいScripterには必携の1冊です。8巻と9巻は続巻になっており、並行して同時に企画しています(ファイル処理は9巻で扱います)。

「Cocoa経由で高速にファイル操作を行いたい」と思っても、意外なほど参考文献が少ないことに気づきます。単独で成立しているものは皆無でしょう。

以前は、AppleScriptでファイルパスの処理を行う際に、いろいろ困らされる話がありました。さまざまな注意すべきポイントはありつつも、Cocoaの機能を用いてファイルパスの処理を行えることは、FinderやSystem Eventsだけでファイル処理を行なっていた時代を思えば、隔世の感があります。

なんといっても、UTI系の演算が行えて、指定のUTIに所属するファイルだけを抽出するといった(拡張子だとJPEGとJPGの両方を指定)、スマートな処理ができるのは素晴らしいことです。高度な処理をお手軽に。圧倒的に高速に。

目次

1章 入門編

2章 実践編

3章 ファイルパス操作編

 ファイルパスの基礎知識
 ファイルパス操作の基礎
 ファイルパス計算
 ファイル名の操作
 ファイル名の抽出
 ファイル/フォルダのローカライズ名を取得
 指定パスの種別チェック
 特定のフォルダへのパスを求める
 ファイルパスの高度な処理

4章 ファイル情報操作編

 ファイルそのものの情報+メタ情報について
 ファイル情報の取得
 Spotlightメタデータ情報の取得
 xattr拡張ファイル情報の操作
 EXIF情報の取得
 MIME情報の取得
 Finderで選択中のファイルの取得/設定

5章 UTIによるファイルアクセス編

 拡張子/UTI/MIMEの位置付けについての基礎知識
 UTIについての基礎知識
 UTI同士の計算
 UTI利用サンプル
 Dynamic UTIについて
 UTIについての資料

6章 ドライブ情報編

 ドライブ情報を取得
 ドライブのマウント/アンマウント

添付サンプルScript紹介

資料編
 Cocoa Scripting関連のAppleScript命令
 Cocoa ScriptingとScript Object
 AppleScript Droplet
 サードパーティ製FrameworkやAppleScript Librariesを呼ぶ
 AppleScript mini reference
 AppleScript 各種ランタイム環境および関連ツール
 AppleScript予約語一覧
 エラーコード表

理解度確認テスト
あとがき、奥付

Posted in Books File path news | Tagged 12.0savvy 13.0savvy 14.0savvy | Leave a comment

Numbersで最前面の書類のすべてのシート上の表の行数を合計

Posted on 4月 5, 2024 by Takaaki Naganoya

Numbersの最前面の書類で、全シート上のすべての表の行数を合計して返すAppleScriptです。

大量のシートを持つ書類上のすべての表の行数をカウントします。それぞれの表からは、ヘッダー行の分はカウントしていません。

Numbersは、Pagesのように「表示範囲にないページ上のオブジェクトからの情報取得ができない(その割に指定ページを表示状態にするための機能もない)」といった動作はしないので、カウント対象のシートをいちいち表示状態にして切り替えるという必要はありません。

AppleScript名:全シート上のtableの行数を合計.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/04/05
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

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

set totalC to 0

tell application "Numbers"
  tell front document
    set nList to name of every sheet
    
repeat with i in nList
      set j to contents of i
      
      
tell sheet j
        set tCount to count every table
        
        
repeat with ii from 1 to tCount
          tell table ii
            set hCnt to header row count
            
            
set tmpCount to count every row
            
set totalC to totalC + tmpCount – hCnt
          end tell
        end repeat
      end tell
      
    end repeat
  end tell
end tell

return totalC

★Click Here to Open This Script 

Posted in Object control | Tagged 13.0savvy 14.0savvy Numbers | Leave a comment

Keynote、Pages、Numbers Ver.14.0が登場

Posted on 4月 3, 2024 by Takaaki Naganoya

Keynote、Pages、NumbersのiWorkアプリがバージョン14にアップデートされました。

本バージョンはmacOS 13以降に対応しています。

各アプリのAppleScript用語辞書に変更はありません。Pagesで見られている、ウィンドウで表示されていないページ上のオブジェクトからの情報取得ができない(正確にいえば、表示中の見開き+2見開き分まで取得可能)という挙動は変わっていません。どうも処理速度向上のための仕様のようなので、この部分はこのままだと思います。

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

Natural Language frameworkで英語で文章同士の距離を測る

Posted on 3月 13, 2024 by Takaaki Naganoya

NaturalLanguage.frameworkを用いて、英語の文章の意味的な距離を測るAppleScriptです。

単語単位の意味的な距離を計算する機能はいまひとつ使い道が限定される感じですが、文単位での意味的な距離の計算には期待してしまうところです。

実際にやってみました。

やってはみたものの、なにかピンと来ないというか、このAPIは1つの文章だけで距離を測るためのものなのか、それとも複数の文の塊で計算するものなのか、、、、

文章のかたまりでも計算できているようです。いろいろサンプル文章をひろってみて距離を計測してみましたが、「なんとなくそんな感じ」の結果が返ってくるだけです。

これは別にAppleが悪いということではなくて、自然言語処理ってこんな感じです。相対的な違いでしかないので、その結果をもって「いい」「わるい」という評価が行えるわけではなく「なんとなくこっち」という判断をするだけです。ただ、間違うこともあるので、その点をあらかじめ知っておくことが重要です。

AppleScript名:英語で文章同士の距離を測る_English.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/03/13
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.8" — Monterey (12.0) or later
use framework "Foundation"
use framework "NaturalLanguage"
use scripting additions

set targLang to current application’s NLLanguageEnglish
set aEmb to current application’s NLEmbedding’s sentenceEmbeddingForLanguage:(targLang)
if aEmb = missing value then return –NLLanguageJapanese is not available here in macOS 13

set aSent to "This is my book."
set bSent to "We the People of the United States, in Order to form a more perfect Union, establish Justice, insure domestic Tranquility, provide for the common defence, promote the general Welfare, and secure the Blessings of Liberty to ourselves and our Posterity, do ordain and establish this Constitution for the United States of America."
set cSent to "Thanks for updating Takaaki! You have almost completed updating AdRotate to version 5.12.9!
To complete the update click the button on the right. This may take a few seconds to complete!
For an overview of what has changed take a look at the development page and usually there is an article on the blog with more information as well."

set dSent to "He says that he like to read something with iPad."

set aDist to (aEmb’s distanceBetweenString:aSent andString:bSent distanceType:(current application’s NLDistanceTypeCosine))
–> 1.350924730301

set bDist to (aEmb’s distanceBetweenString:aSent andString:cSent distanceType:(current application’s NLDistanceTypeCosine))
–> 1.374191045761

set cDist to (aEmb’s distanceBetweenString:aSent andString:dSent distanceType:(current application’s NLDistanceTypeCosine))
–> 1.168848276138

★Click Here to Open This Script 

Posted in Natural Language Processing | Tagged 13.0savvy 14.0savvy | Leave a comment

NaturalLanguage.frameworkでNLEmbeddingの処理が可能な言語をチェック

Posted on 3月 13, 2024 by Takaaki Naganoya

NaturalLanguage.frameworkには各種言語の定義を行なった定数が57ほど定義されているようです。ただし、これらの定義がすべて利用できるわけがありません(Appleのやることなので、必ずミスやもれがあります)。

とりあえず、本当にどのぐらいの言語が使えるのか、チェックしておくことが必要です。

結論からいえば、Appleが何を考えているのかよくわかりません。macOS 13では7言語ほど使えるという結果になりましたが、macOS 14では英語しか使えないという結果になっています。OSがバージョンアップするとOSの機能が低下するという理解不能な挙動を示しています。バグ、、、なのかも????

Appleが用意した新機能は、ひととおり「本当に使えるのか」をチェックする必要があります。だいたいは搭載されて1発目はバグだらけで、OSのメジャーアップデートを経て良くなったり、よくならなかったりします。

この機能はどちらなんでしょう? Shortcutみたいに「救いようがない」のもありますが……

AppleScript名:指定言語でNLEmbeddingを処理できるかチェック_13_14.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/03/13
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.8"
use framework "Foundation"
use framework "NaturalLanguage"
use scripting additions

–The result is on macOS 13.6.5 / 14.4
set aRes to testNLLanguage("NLLanguageEnglish") of me –> true
set aRes to testNLLanguage("NLLanguageFrench") of me –> true–>false (macOS 14)
set aRes to testNLLanguage("NLLanguageGerman") of me –> true–>false (macOS 14)
set aRes to testNLLanguage("NLLanguageItalian") of me –> true–>false (macOS 14)
set aRes to testNLLanguage("NLLanguagePortuguese") of me –> true–>false (macOS 14)
set aRes to testNLLanguage("NLLanguageSimplifiedChinese") of me –> true–>false (macOS 14)
set aRes to testNLLanguage("NLLanguageSpanish") of me –> true–>false (macOS 14)

set aRes to testNLLanguage("NLLanguageUndetermined") of me –> true –Natural Language framework doesn’t recognize.

set aRes to testNLLanguage("NLLanguageAmharic") of me –> false
set aRes to testNLLanguage("NLLanguageArabic") of me –> false
set aRes to testNLLanguage("NLLanguageArmenian") of me –> false
set aRes to testNLLanguage("NLLanguageBengali") of me –> false
set aRes to testNLLanguage("NLLanguageBulgarian") of me –> false
set aRes to testNLLanguage("NLLanguageBurmese") of me –> false
set aRes to testNLLanguage("NLLanguageCatalan") of me –> false
set aRes to testNLLanguage("NLLanguageCherokee") of me –> false
set aRes to testNLLanguage("NLLanguageCroatian") of me –> false
set aRes to testNLLanguage("NLLanguageCzech") of me –> false
set aRes to testNLLanguage("NLLanguageDanish") of me –> false
set aRes to testNLLanguage("NLLanguageDutch") of me –> false
set aRes to testNLLanguage("NLLanguageFinnish") of me –> false
set aRes to testNLLanguage("NLLanguageGeorgian") of me –> false
set aRes to testNLLanguage("NLLanguageGreek") of me –> false
set aRes to testNLLanguage("NLLanguageGujarati") of me –> false
set aRes to testNLLanguage("NLLanguageHebrew") of me –> false
set aRes to testNLLanguage("NLLanguageHindi") of me –> false
set aRes to testNLLanguage("NLLanguageHungarian") of me –> false
set aRes to testNLLanguage("NLLanguageIcelandic") of me –> false
set aRes to testNLLanguage("NLLanguageIndonesian") of me –> false
set aRes to testNLLanguage("NLLanguageJapanese") of me –> false
set aRes to testNLLanguage("NLLanguageKannada") of me –> false
set aRes to testNLLanguage("NLLanguageKazakh") of me –> false
set aRes to testNLLanguage("NLLanguageKhmer") of me –> false
set aRes to testNLLanguage("NLLanguageKorean") of me –> false
set aRes to testNLLanguage("NLLanguageLao") of me –> false
set aRes to testNLLanguage("NLLanguageMalay") of me –> false
set aRes to testNLLanguage("NLLanguageMalayalam") of me –> false
set aRes to testNLLanguage("NLLanguageMarathi") of me –> false
set aRes to testNLLanguage("NLLanguageMongolian") of me –> false
set aRes to testNLLanguage("NLLanguageNorwegian") of me –> false
set aRes to testNLLanguage("NLLanguageOriya") of me –> false
set aRes to testNLLanguage("NLLanguagePersian") of me –> false
set aRes to testNLLanguage("NLLanguagePolish") of me –> false
set aRes to testNLLanguage("NLLanguagePunjabi") of me –> false
set aRes to testNLLanguage("NLLanguageRomanian") of me –> false
set aRes to testNLLanguage("NLLanguageRussian") of me –> false
set aRes to testNLLanguage("NLLanguageSinhalese") of me –> false
set aRes to testNLLanguage("NLLanguageSlovak") of me –> false
set aRes to testNLLanguage("NLLanguageSwedish") of me –> false
set aRes to testNLLanguage("NLLanguageTamil") of me –> false
set aRes to testNLLanguage("NLLanguageTelugu") of me –> false
set aRes to testNLLanguage("NLLanguageThai") of me –> false
set aRes to testNLLanguage("NLLanguageTibetan") of me –> false
set aRes to testNLLanguage("NLLanguageTraditionalChinese") of me –> false
set aRes to testNLLanguage("NLLanguageTurkish") of me –> false
set aRes to testNLLanguage("NLLanguageUkrainian") of me –> false
set aRes to testNLLanguage("NLLanguageUrdu") of me –> false
set aRes to testNLLanguage("NLLanguageVietnamese") of me –> false

on testNLLanguage(aLangName)
  set aText to "use AppleScript
use framework \"Foundation\"
use framework \"NaturalLanguage\"

  set targLang to (current application’s " & aLangName & ")
  set aEmb to current application’s NLEmbedding’s wordEmbeddingForLanguage:(targLang)
  if aEmb = missing value then return false
  return true
  "

  
return run script aText
end testNLLanguage

★Click Here to Open This Script 

Posted in Natural Language Processing Text | Tagged 13.0savvy 14.0savvy | Leave a comment

NaturalLanguage frameworkを使って類語語展開+意味的な距離を計測してソート

Posted on 3月 13, 2024 by Takaaki Naganoya

NaturalLanguage frameworkといえば、macOS 10.14で追加されたものですが、自然言語テキストが「何語」であるかを推測するなどの使い方をAppleScriptから行なってきました。正直、その程度しか「役に立つ機能がない」という認識でした。

日本語のサポートはまだまだですが、日本語でなければ意外と使えることがわかりました。

試しに、NaturalLanguage.frameworkの機能を用いて指定の英単語の類義語を生成して、それぞれの元の単語との意味的な距離を計算してみました。

自然言語処理的にわかりやすい言葉でいえば、類語語のリストをword2vecでベクトル化してコサイン距離を計算する、というところでしょうか。

類義語展開であれば、日本語WordNetを利用して検索するAppleScriptを4年ぐらい前に試作ずみなので、このOS側の類義語展開機能がなくても別に構わないのですが、word2vecやsentence2vecで単語や文章をベクトル化して意味的な距離を計測する演算については、利用したいところです。

ただ、OSの機能が向上するどころか退化しているようなので、この分野ではmacOSの進歩は期待できないのかもしれません。

AppleScript名:指定単語の類義語を展開して元の単語との距離を測る.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/03/12
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

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

set targLang to current application’s NLLanguageEnglish
set aEmb to current application’s NLEmbedding’s wordEmbeddingForLanguage:(targLang)
if aEmb = missing value then return –NLLanguageJapanese is not available here in macOS 13

–類義語展開(Max.50)
set aWord to "computer"
set aSym to (aEmb’s neighborsForString:aWord maximumCount:20 distanceType:(current application’s NLDistanceTypeCosine)) as list

–コサイン距離を計測(0.0〜2.0)数字が小さいと近いはず。ちょっとでも意味が遠いと2.0になるという悪癖を持つ
set distList to {}
repeat with i in aSym
  set j to contents of i
  
set aDist to (aEmb’s distanceBetweenString:aWord andString:j distanceType:(current application’s NLDistanceTypeCosine))
  
set the end of distList to {wordName:j, wordDistance:aDist as real}
end repeat

–昇順ソート
set bList to sortRecListByLabel(distList, "wordDistance", true) of me
–> {{wordDistance:0.837697923183, wordName:"workstation"}, {wordDistance:0.875068962574, wordName:"mainframe"}, {wordDistance:0.886509418488, wordName:"laptop"}, {wordDistance:0.901307225227, wordName:"software"}, {wordDistance:0.901674091816, wordName:"computing"}, {wordDistance:0.904342055321, wordName:"palmtop"}, {wordDistance:0.951638877392, wordName:"desktop"}, {wordDistance:0.954249441624, wordName:"intranet"}, {wordDistance:0.958346903324, wordName:"keystroke"}, {wordDistance:0.961381614208, wordName:"notebook"}, {wordDistance:0.964299142361, wordName:"server"}, {wordDistance:0.970234155655, wordName:"hardware"}, {wordDistance:0.974493980408, wordName:"pager"}, {wordDistance:0.981385648251, wordName:"electronic"}, {wordDistance:0.984282553196, wordName:"peripheral"}, {wordDistance:0.993325233459, wordName:"machine"}, {wordDistance:0.996084809303, wordName:"diskette"}, {wordDistance:0.999181330204, wordName:"portable"}, {wordDistance:1.001676082611, wordName:"compatible"}, {wordDistance:1.00532245636, wordName:"programmer"}}

–リストに入れたレコードを、指定の属性ラベルの値でソート
on sortRecListByLabel(aRecList as list, aLabelStr as string, ascendF as boolean)
  set aArray to current application’s NSArray’s arrayWithArray:aRecList
  
set sortDesc to current application’s NSSortDescriptor’s alloc()’s initWithKey:aLabelStr ascending:ascendF
  
set sortedArray to aArray’s sortedArrayUsingDescriptors:{sortDesc}
  
set bList to (sortedArray) as anything
  
return bList
end sortRecListByLabel

★Click Here to Open This Script 

本当は単語ではなく「文章」の距離を計測できないと実用性が低いところです。word2vecではなくsentence2vecの演算を行いたいところ。

自作のAppleScriptによるアイデアプロセッサ「Kamenoko」も、当初から自然言語処理の機能を盛り込むことを企画していました。sentence2vecぐらいの演算を行なって、各ノードに書いてある文章同士の距離を計測して、距離に応じて色を変えるといった機能も検討していました。

ただ、そうした機能を実装するのに割とデータ量が多くなるとか、アプリとしてパッケージングするのに無理があるとか、もういっそWebサーバー側で処理したほうがいいんじゃないの? 的な話になって見送った経緯があります。

このNaturalLanguage.frameworkがもっと使えるように、なったらいいのに。簡体字の中国語に対応しているぐらいなので、日本語への対応も期待したいところですが……macOS 14では対応言語が英語だけになるなど、展開の仕方が謎であります。

Posted in list Natural Language Processing Record | Tagged 13.0savvy 14.0savvy | Leave a comment

CotEditorで2つの書類の行単位での差分検出

Posted on 3月 12, 2024 by Takaaki Naganoya

CotEditorで2つの書類をオープンしておき、行単位での差分を検出し、新規書類に結果を出力するAppleScriptです。

もともと、macOS搭載のFramework名一覧の差分を検出する資料を作成する必要があり、これを片付けるために作成しました。

本AppleScriptを実行すると……

のように、結果を出力します。それほど巨大なデータを想定して作ってはいないので、ほどほどの規模に抑えて利用してください。

AppleScript名:左右のドキュメントを比較.scpt
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

script spd
  property aList : {}
  
property bList : {}
end script

set (aList of spd) to {}
set (bList of spd) to {}

tell application "CotEditor"
  set dCount to count every document
  
if dCount is not equal to 2 then
    display notification "Error: This script needs only 2 documents"
    
return –Document number Error
  end if
  
  
tell window 1
    set w1Bounds to bounds
    
copy w1Bounds to {w1X1, w1Y1, w1X2, w1Y2}
    
set w1Doc to document of it
  end tell
  
  
tell window 2
    set w2Bounds to bounds
    
copy w2Bounds to {w2X1, w2Y1, w2X2, w2Y2}
    
set w2Doc to document of it
  end tell
  
  
if w1X1 > w2X1 then
    set {w1, w2} to {2, 1}
  else
    set {w1, w2} to {1, 2}
  end if
  
  
tell document w1 –左ウィンドウ
    set (aList of spd) to paragraphs of contents
  end tell
  
  
tell document w2 –右ウィンドウ
    set (bList of spd) to paragraphs of contents
  end tell
  
end tell

–ゴミ掃除
set (aList of spd) to cleanUp1DList((aList of spd), {"
"
}) of me

set (bList of spd) to cleanUp1DList((bList of spd), {"
"
}) of me

–差分計算
set (cList of spd) to getDiffBetweenLists((aList of spd), (bList of spd)) of me

–結果出力テキスト組み立て
set aRes to listToTextUsingDelim(addItems of (cList of spd), "")
set bRes to listToTextUsingDelim(minusItems of (cList of spd), "")

–結果の新規書類への出力
set d3 to makeNewCotEditorDoc("左→右で追加された項目" & return & return & aRes) of me
set d4 to makeNewCotEditorDoc("左→右で削除された項目" & return & return & bRes) of me

on getDiffBetweenLists(aArray as list, bArray as list)
  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)
  
  
–重複部分を削除する
  
allSet’s minusSet:duplicateSet
  
set resArray to (allSet’s allObjects()) as list
  
  
set aSet to current application’s NSMutableSet’s setWithArray:aArray
  
set bSet to current application’s NSMutableSet’s setWithArray:resArray
  
aSet’s intersectSet:bSet –積集合
  
set addRes to aSet’s allObjects() as list
  
  
set cSet to current application’s NSMutableSet’s setWithArray:bArray
  
cSet’s intersectSet:bSet –積集合
  
set minusRes to cSet’s allObjects() as list
  
  
return {addItems:minusRes, minusItems:addRes}
end getDiffBetweenLists

on cleanUp1DList(aList as list, cleanUpItems as list)
  set bList to {}
  
repeat with i in aList
    set j to contents of i
    
if j is not in cleanUpItems then
      set the end of bList to j
    end if
  end repeat
  
return bList
end cleanUp1DList

–デリミタ文字を指定してリストを文字列化
on listToTextUsingDelim(aList, aDelim)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set outText to every text item of aList
  
set outText to outText as string
  
set AppleScript’s text item delimiters to curDelim
  
return outText
end listToTextUsingDelim

–指定テキストでCotEditorの新規書類を作成
on makeNewCotEditorDoc(aCon)
  tell application "CotEditor"
    activate
    
set newDoc to make new document
    
tell newDoc
      set contents to aCon
    end tell
  end tell
end makeNewCotEditorDoc

★Click Here to Open This Script 

Posted in diff list Text | Tagged 13.0savvy 14.0savvy CotEditor | Leave a comment

Pagesで、現在表示中のページから離れたページのオブジェクト情報を取得できない

Posted on 3月 10, 2024 by Takaaki Naganoya

Pagesのいつかのバージョンから現在表示中のページから離れたページのオブジェクト情報取得および操作ができなくなっていました。バージョン13.xではすでにそうなっていました。12.xからそうだったかもしれません。

2024/4/3追記:Pages v14.0で確認したところ、同じ挙動でした

1〜2ページを表示中に、3〜4ページのオブジェクト情報取得および操作は行えるものの、7〜8ページ以降のオブジェクト情報は取得できないという状況です。自分が確認したのはtableオブジェクトのposition情報。

25%の縮小表示を行った場合には、

問題なく、すべてのページのtable(ツメ)のpositionを取得できますが、

拡大表示すると……

7ページ以降のtableのpositionを取得できていません。

この現象は、全ページに対してツメ(Dictionary index)を付加して統一操作を行うAppleScriptにおいて問題になっていました。実際に、ファイル名に「章番号」を書いておくと、それをピックアップして、ツメの見た目を変更するというAppleScriptを作成して運用しています。このScriptは、ツメの塗りの状態を自動検知して当該章の塗り方を自動で反映するようになっています。

このような高機能Scriptを実用化したものの、最近になっておかしな挙動が確認されていました。

・現在表示中のページのオブジェクト操作は行える
・表示中から離れたページのオブジェクト操作/情報取得が行えない

なんじゃこら????

Pages書類のツメ操作で、いろいろ問題に。

そこで、実験のために表示ページを移動しながらオブジェクト情報を取得してみたら、問題なく情報取得できました。

Pagesには表示対象ページの変更機能はないので、GUI Scriptingで「次のページ」コマンドを強引に実行。あるいは、実行前にPagesの書類表示ズーム倍率を、25%に変更しておく……というほうが「楽」かもしれません。

これをバグとして報告すべきなのか、アプリケーションの挙動として「知っておくべき情報」なのかは判断できません。処理速度向上のための「改善」の結果としてこのような状況が生まれてしまったのかもしれないためです。

ただ、特定のページを表示状態にする機能がないのに、表示範囲外(現在の見開きから+2見開きを超える範囲)のオブジェクトの情報を取得できないのは、片手落ちの状態でしょう。

Posted in Object control | Tagged 13.0savvy 14.0savvy Pages | Leave a comment

与えられた文字列の1D Listのすべての順列組み合わせパターン文字列を返す v3(ベンチマーク用)

Posted on 2月 18, 2024 by Takaaki Naganoya

Macの処理速度を測るのにちょうど手頃な内容のプログラムです。与えた配列要素の、順列組み合わせ計算を行います。

M2 MacBook Air@macOS 15.1の環境の実行結果は、

–> {{4, 0.004417896271}, {5, 0.009887933731}, {6, 0.063844919205}, {7, 0.450636982918}, {8, 3.521628022194}, {9, 31.777850985527}}

なので、ほとんどM1 Mac miniと変わりません(少し遅いぐらい)。

AppleScript名:与えられた文字列の1D Listのすべての順列組み合わせパターン文字列を返す v3_for benchmark.scptd
— 2014-10-06 Original By Nigel Garvey@macscripter.net
— 2019-06-19 Modified By Takaaki Naganoya
— 2024-02-18 Modified By Takaaki Naganoya
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

script spdPerm
  property permutations : missing value
  
property allRes : {}
end script

on run
  set allList to {{"A", "T", "G", "C"}, {"A", "T", "G", "C", "1"}, {"A", "T", "G", "C", "1", "2"}, {"A", "T", "G", "C", "1", "2", "3"}, {"A", "T", "G", "C", "1", "2", "3", "4"}, {"A", "T", "G", "C", "1", "2", "3", "4", "5"}}
  
  
repeat with i in allList
    set theList to contents of i
    
    
set a1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
    
set aRes to permute(theList) of me
    
set b1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
    
set c1Dat to (b1Dat – a1Dat)
    
set the end of (allRes of spdPerm) to {length of theList, c1Dat}
    
  end repeat
  
  
return (allRes of spdPerm)
  
— MacBook Pro 2012 Retina Core i7 2.6GHz@macOS 10.14.6 の実行結果
  
–> {{4, 0.01 }, {5, 0.010347008705}, {6, 0.05}, {7, 1.44}, {8, 11.54}, {9, 107.271}}
  
  
–M1 Mac mini@macOS 13.6.5 の実行結果
  
–> {{4, 0.005248069763}, {5, 0.01240503788}, {6, 0.063866019249}, {7, 0.434872984886}, {8, 3.519423961639}, {9, 31.62052500248}}
end run

on permute(theList as list)
  set theArray to current application’s NSMutableArray’s arrayWithArray:theList
  
set (permutations of spdPerm) to current application’s NSMutableArray’s array()
  
prmt(theArray, 0, (count theList) – 1)
  
  
–Return AppleScript string list
  
set aFinishArray to current application’s NSMutableArray’s new()
  
set anEnum to (permutations of spdPerm)’s objectEnumerator()
  
repeat
    set aValue to anEnum’s nextObject()
    
if aValue = missing value then exit repeat
    
set aStr to aValue’s componentsJoinedByString:""
    (
aFinishArray’s addObject:aStr)
  end repeat
  
  
return aFinishArray as list
end permute

on prmt(theArray, theStart as number, theEnd as number)
  if (theStart = theEnd) then
    (permutations of spdPerm)’s addObject:theArray
  else
    repeat with x from theStart to theEnd
      set theCopy to theArray’s mutableCopy()
      
–swap
      
if (x > theStart) then (theCopy’s exchangeObjectAtIndex:theStart withObjectAtIndex:x)
      
prmt(theCopy, theStart + 1, theEnd)
    end repeat
  end if
end prmt

★Click Here to Open This Script 

Posted in list | Tagged 13.0savvy 14.0savvy | Leave a comment

2023年に書いた価値あるAppleScript

Posted on 1月 29, 2024 by Takaaki Naganoya

2023年に使用していたmacOS:macOS 13

毎年行なっている、Piyomaru Softwareが書いたAppleScriptの1年を振り返る記事の2023年版です。10年ほど続けてきた旧「AppleScriptの穴」Blogが2018年の年初にホスティング会社との行き違いでシャットダウンされ、再構築したのがこの現行の「AppleScriptの穴」Blogです。

→ 2018年に書いた価値あるAppleScript
→ 2019年に書いた価値あるAppleScript
→ 2020年に書いた価値あるAppleScript
→ 2021年に書いた価値あるAppleScript
→ 2022年に書いた価値あるAppleScript

旧「AppleScriptの穴」Blogの内容については、データベースから抜き出したデータをもとに再構成した「Blogアーカイブ本」にまとめています。

AppleScriptの穴Blogアーカイブvol.1
AppleScriptの穴Blogアーカイブvol.2
AppleScriptの穴Blogアーカイブvol.3
AppleScriptの穴Blogアーカイブvol.4
AppleScriptの穴Blogアーカイブvol.5
AppleScriptの穴Blogアーカイブvol.6

本Blogは、機械翻訳で翻訳しやすいように、平易な日本語で記述してある点がチャームポイントです。それはもう、小学生の日記ぐらいの難易度で。もともとは、2000年代初頭に開発していた「人工知能インタフェース Newt On」のソースコード部品バラバラにして掲載し、用いた部品を個別にメンテナンスすることを「隠れた目的」としていました。また、Scripter間のノウハウの共有を推進することも目的としています。

AppleScript以外の一般的なテーマの記事については、こちらにいろいろ投稿しています。

https://note.com/140software/

2023年的な状況といいますか、昨今のMac環境をとりまく状況として新バージョンのmacOSとしてmacOS 14がありつつも、Appleがマイナーアップデートで新たなバグを盛り込んでくるため、macOS 14に付き合うこと自体がリスクです。β版で確認を行なっても、Release版で安定度が激下がりして、その後にバグ改修と新機能追加が行われるため、つねにどこかにド派手な不具合を抱えているという状況です。

2023年にはそれほど発表できるようなAppleScriptを書いていない(=自分の作業を効率化するものしか書いていないので外部に発表のしようがない)のと、それほど技術レベルや解決策のレベルが上がったような内容のものはありません。

さまざまな技術的な内容をまとめた記事については、電子書籍に掲載したり、付録Scriptとして添付しています。年間19冊出しています。

ポケコンサークル「LL」会誌Vol.19復刻版(282ページ)

AppleScript基礎テクニック集(29)セキュリティ機能解除(36ページ)

AppleScript+Xcodeで作るMacアプリ(484ページ)

ChatGPTにAppleScriptを書かせてみた!(76ページ)

AppleScript基礎テクニック(30)コンテクストメニューScriptの作り方(41ページ)

AppleScript基礎テクニック(30)コンテクストメニューScriptの作り方 英語版(41ページ)

AppleScript基礎テクニック(31)スクリプトバンドルの活用(34ページ)

AppleScript 7つの宝珠(3)(35ページ)

Cocoa Scripting Course #5 NSImage(473ページ)

ゆっくりAppleScript解説(1)(45ページ)

ゆっくりAppleScript解説(2)(45ページ)

つたわる資料のつくりかた(66ページ)

Keynote Scripting Book With AppleScript(434ページ)

Cocoa Scripting Course #6 PDFKit(560ページ)

ゆっくりAppleScript解説(3)(42ページ)

AppleScript最新リファレンス v2.8(1008ページ)

AppleScript最新リファレンス v2.8英語版(223ページ)

戦場の絆〜僕らの15年戦争〜v2(394ページ)

Piyomaru Software電子書籍カタログ 2024冬(100ページ)

2023年に書いた記事の中で注目すべきもの

2023年に書いたものは、例年どおりの「価値あるAppleScript」と言うほどのものではなく、「2023年に書いた記事の中で注目すべきもの」をリストアップするという程度の内容になりそうです。

geoCodingLibで住所ジオコーディング

geoCodingLibで逆住所ジオコーディング

住所ジオコーディング(住所→緯度経度情報)/逆住所ジオコーディング(緯度経度情報→住所)は、AppleScriptで普通に実行できてほしい処理のひとつです。こうしてObjective-C/Swiftで書いたプログラムをFrameworkとして呼び出せるようにして呼び出すとか、いろいろ方法があるわけで……少なくとも、ローカルで処理が完結する解決策は用意しておきたいところです。

ChatGPTでchatに対する応答文を取得

AppleScriptからのChatGPTのREST API呼び出しは、かなり早期からできていました。処理したい内容のScriptをChatGPTに書かせて実行するといった「なげやり」な方法であれば、こうしたScriptの延長線上で可能ですが、あらかじめきちんと動くことを保証したScriptのパラメータ部分だけをLLMから取得するとか、複数のScriptを組み合わせて処理を実行させるといった内容を実現する方法を見つけたいところです。

Keynote,Pages,Numbers v13.0がリリースされる

Keynoteはいいアプリケーションだと思うものの、あまりバージョンアップしても機能が追加されないというか、実際に使っている人間からのフィードバックがさっぱりないというか、ユーザーと開発現場の距離が離れてしまっている感じがします。

他形式の3DデータをUSDZデータに変換するあたりのツールが充実する必要があるというか、Keynote側の読み込み機能がもう少し強化されてもよさそうな気もします。

出るか?「AppleScript最新リファレンス」のバージョン2.8対応版

この本は、発行するのに30冊以上も本を出す必要があり、数年かけて計画を実行して、ようやくアップデートにこぎつけました。最初の「AppleScript最新リファレンス」から7年が経過していることに驚かされます。

Excelの書類上に置かれているpictureが置かれているセルのアドレスを推定する v2

Microsoft Excelは依然としてAppleScript用語辞書が大きなアプリケーションではあるのですが、Excelの機能が強力すぎる(表現力が豊かすぎる)ために、目的の処理を行うためにはなかなか一筋縄では行かないようです。

PowerPointを操作するAppleScriptをScript Menuに入れて実行すると動作が完結しない問題

PowerPointにかぎらず、Microsoft OfficeアプリのAppleScript用語辞書が、より詳細な記述を行なっているところに懸念をおぼえます。こんなに細かく書かないとダメなのだろうかと。敷居が高くなりすぎていないかと。あと、Script MenuにPowerPointを操作するAppleScriptを入れて実行すると動かないというのは、ランタイム環境が強く限定され、こんにちのmacOS環境の中で標準レベルといえるScript Menuで動かないのは、よくないと考えます。

Cocoa-AppleScript Appletランタイムが動かない?

macOS 12.xのマイナーバージョンアップ時に機能が損なわれた箇所です。そして、Appleにバグレポートしても治らない。こんな根本的な部分で不具合を起こされても困るのですが……。

macOS 14の変更がmacOS 13にも反映

「システム環境設定」が「システム設定」に変わったときに、各設定Paneを表示するためのAppleScript用語辞書が機能しない、空白の期間が発生していました。macOS 14βで本機能が復旧されたのと同じタイミングで、macOS 13.xにもさかのぼって同じ機能が実装されました。

ただ、システム設定の各Paneへの表示切り替えが行えるだけで、たとえばオーディオ入出力デバイスの切り替え機能が提供されているわけではないため、それについては別途実装したものを呼び出すという解決方法が必要になります。

Posted in news | Tagged 13.0savvy 14.0savvy | Leave a comment

アプリケーション操作の次の段階へ

Posted on 1月 28, 2024 by Takaaki Naganoya

GUIアプリケーションの操作において、若干の不満を覚えつつもmacOS上のGUIアプリケーションの操作を行えてきました。

ただ、「次」の段階が見えているのに、GUIアプリケーション側の機能がそれに追いついていなかったり、未実装の部分があったりで、GUIアプリケーション側が足を引っ張っているように見える今日このごろです。

たとえばKeynoteにおいて、特定のグラフィックだけを削除したい(会社ロゴなど)という場合に、メニューに「この部品に近似する部品を削除」といった機能が実装されていてもよさそうな昨今ですが、それはありません。「類似画像を削除」「類似部品を削除」といった処理はやりたくなる部分だと(勝手に)考えるものです。だいたい、OS内の機能を見ても容易に実装できそうに見えます。

Keynote書類にはimageオブジェクトが用意されており、さまざまなプロパティを取得できるようになっていますが、file nameは取得できても、

file属性を取得できない状態です。

AppleScript名:画像からfile属性を取得(できない).scpt
tell application "Keynote"
  tell front document
    set aSel to selection
    
set aaSel to first item of aSel
    
    
set aFile to file of aaSel
    
–> error "Keynoteでエラーが起きました: AppleEventのハンドラで誤りが起きました。" number -10000
  end tell
end tell

★Click Here to Open This Script 

iCloud上に存在するKeynote書類の内部ファイルに対してのパスを表現しづらい、といった理由は理解できるかもしれませんが、用語辞書にfile属性が取れると明記してある以上、file属性は(ローカルに書類が存在するなどの条件下では)取得できるべきだと考えます。

そして、file属性(おそらく、file pathをalias形式で取得できる)を取れれば、画像の「内容」にもアクセスして、「指定の画像に近似するものを削除」といった処理はできるはずです(画像のハッシュ値を計算する処理は別途する必要はあるわけですが)。

このあたりの処理が、そろそろできてもいいんですが、いろいろ邪魔が入ってできないのが残念な感じがします。

Posted in Image | Tagged 13.0savvy 14.0savvy Keynote | Leave a comment

スクリプトエディタで記入した「説明」欄の内容が消えるバグ

Posted on 1月 9, 2024 by Takaaki Naganoya

macOS 13.6.4+スクリプトエディタ バージョン2.11 (229)の組み合わせで、AppleScript書類の「説明」欄に記入した内容が「消える」トラブルが発生しています。macOS 14上でも発生していることを確認しました。


▲スクリプトエディタ上で新規書類を作成して、AppleScript本文と「説明」欄の内容を書き込んでみた


▲スクリプトエディタで名称を指定して保存(.scpt形式)した状態


▲保存していったんクローズして、再度オープンしてみたところ。「説明」欄の内容が見えない


▲「説明」欄の内容を選択したところ。白い色の文字が存在していることがわかる

「消える」というよりは、「見えなくなる」というのが正しい状況と思われますが、macOSのマイナーアップデートでこうした変更が加わる(正確にいえば、APIなどの変更が行われた一方で、スクリプトエディタの修正が行われずに動作がおかしくなる)というのは納得できません。

なお、バンドル形式のAppleScript(.scptd形式)であれば、「説明」欄の内容が白く表示されることはないようです。

Posted in Bug | Tagged 13.0savvy 14.0savvy Script Editor | 1 Comment

可変次元のベクトルに対応したコサイン類似度計算

Posted on 11月 23, 2023 by Takaaki Naganoya

ChatGPTに書かせたAppleScriptを微修正したものです。ベクトルの内積、外積の計算を経てコサイン類似度計算のAppleScriptを書かせました。

もともとは、ChatGPTのAPIを利用して自然言語テキストをベクトル化し、それらの類似度を計算させるための準備で用意しました。自分が試したときには、ChatGPTのREST APIは1536次元のベクトルを返してきました。残念ながら、いま試してみると(全然REST API呼び出しをしていないのに)Quota Exceedのエラーが出てしまって目的の処理はできませんでした。

このあたり、実際にChatGPTのコンソールから利用履歴を確認してみても、全然呼び出していないことが確認できたので、自分の記憶違いではありません。

もともと、日本語テキストを複数の機械翻訳APIを利用して英訳し、再度日本語訳したのちに文章をベクトル化。これらの複数の機械翻訳APIの結果を比較して、もともとの日本語の文章と類似度が高いものを「正確に英訳された文章」として採用してみるといいんじゃないかと思っていました。翻訳文の質を疑似的に評価してみようと思ったわけです。

ChatGPTに出力させたAppleScriptは、「間違ってはいないんだけど、正しくないし、微妙にムカつく(resultを使って計算したりする)」内容で、よくわかっている人間にとっては簡単に修正できるものですが、基礎がわかっていないとどこが間違っているか指摘しにくいし、そもそも間違っているかどうかも指摘しにくいので……より正確な知識が要求されます。

AppleScript名:可変次元のベクトルに対応したコサイン類似度計算.scpt
— ベクトルの例
set vectorA to {1, 2, 3, 4}
set vectorB to {4, 5, 6, 7}

— コサイン類似度を計算
set similarityResult to cosineSimilarity(vectorA, vectorB)

— 結果を表示
return similarityResult
–> 0.975900072949

— ベクトルのノルムを計算する関数
on vectorNorm(aVec)
  set sumSquares to 0
  
repeat with i from 1 to (count of aVec)
    set sumSquares to sumSquares + (item i of aVec) ^ 2
  end repeat
  
return (sumSquares) ^ 0.5
end vectorNorm

— ベクトルのコサイン類似度を計算する関数
on cosineSimilarity(vector1, vector2)
  set dimension1 to count of vector1
  
set dimension2 to count of vector2
  
  
if dimension1 = dimension2 then
    set dotProductResult to dotProduct(vector1, vector2)
    
set norm1 to vectorNorm(vector1)
    
set norm2 to vectorNorm(vector2)
    
set similarity to dotProductResult / (norm1 * norm2)
    
return similarity
  else
    error "ベクトルの次元数が一致していません。"
  end if
end cosineSimilarity

— ベクトルの内積を計算する関数
on dotProduct(vector1, vector2)
  set dimension1 to count of vector1
  
set dimension2 to count of vector2
  
  
if dimension1 = dimension2 then
    set sRes to 0
    
repeat with i from 1 to dimension1
      set sRes to sRes + ((item i of vector1) * (item i of vector2))
    end repeat
    
return sRes
  else
    error "ベクトルの次元数が一致していません。"
  end if
end dotProduct

★Click Here to Open This Script 

Posted in list Natural Language Processing | Tagged 13.0savvy 14.0savvy | Leave a comment

Post navigation

  • Older posts
  • Newer posts

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

Google Search

Popular posts

  • Numbersで選択範囲のセルの前後の空白を削除
  • macOS 15でも変化したText to Speech環境
  • デフォルトインストールされたフォント名を取得するAppleScript
  • AppleScript入門③AppleScriptを使った「自動化」とは?
  • 【続報】macOS 15.5で特定ファイル名パターンのfileをaliasにcastすると100%クラッシュするバグ
  • Script Debuggerの開発と販売が2025年に終了
  • macOS 14で変更になったOSバージョン取得APIの返り値
  • macOS 15 リモートApple Eventsにバグ?
  • AppleScript入門① AppleScriptってなんだろう?
  • KagiのWebブラウザ、Orion
  • macOS 26, Tahoe
  • 2024年に書いた価値あるAppleScript
  • macOS 15:スクリプトエディタのAppleScript用語辞書を確認できない
  • NSObjectのクラス名を取得 v2.1
  • 有害ではなくなっていたSpaces
  • Pixelmator Proがv3.6.8でHDR画像をサポート
  • Xcode上のAppleScriptObjCのプログラムから、Xcodeのログ欄へのメッセージ出力を実行
  • AVSpeechSynthesizerで読み上げテスト
  • (確認中)AppleScript Dropletのバグっぽい動作が解消?
  • AppleScript Dropletのバグっぽい動作が「復活」(macOS 15.5β)

Tags

10.11savvy (1101) 10.12savvy (1242) 10.13savvy (1391) 10.14savvy (587) 10.15savvy (438) 11.0savvy (283) 12.0savvy (212) 13.0savvy (199) 14.0savvy (154) 15.0savvy (143) CotEditor (66) Finder (52) Keynote (119) 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) Pixelmator Pro (20) 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
  • process
  • 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年8月
  • 2025年7月
  • 2025年6月
  • 2025年5月
  • 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