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

タグ: 15.0savvy

複数の重複検出ルーチンを順次速度計測

Posted on 2月 6 by Takaaki Naganoya

1D List(1次元配列)の重複項目検出を、複数の方式で速度計測するAppleScriptです。

List(Array)中の重複項目の抽出は、かなりよく出てくる処理です。自分が使っていたルーチンよりも他の人が使っているルーチンのほうが速かったので、ひととおり調べておくべきだと考え、10万項目の乱数データに対して処理してみることに。

テストScriptを書いて実行してみたら、本件では高速化ずみのVanilla ASのハンドラが一番速いという結果が出ました。意外です。

AppleScript名:複数の重複検出ルーチンを順次速度計測.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/02/05
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

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

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

–Mesurement data gen.
set (aList of spd) to {}
repeat with i from 1 to 100000
  set the end of (aList of spd) to (random number from 1 to 10000)
end repeat

–Benchmark Code
set hList to {"returnDuplicatesOnly1:", "returnDuplicatesOnly2:", "returnDuplicatesOnly3:"}
set resList to {}

repeat with i in hList
  set nameOfTargetHandler to contents of i
  
  
–Check Handler existence
  
set existsHandler to (me’s respondsToSelector:nameOfTargetHandler) as boolean
  
if existsHandler = true then
    –Call handler
    
set a1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
    
    
set aRes to (my performSelector:nameOfTargetHandler withObject:(aList of spd))
    
    
set b1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
    
set c1Dat to b1Dat – a1Dat
  else
    error "Handler does not exists"
  end if
  
  
set the end of resList to {nameOfTargetHandler, c1Dat}
end repeat

return resList
–> {{"returnDuplicatesOnly1:", 0.065470099449}, {"returnDuplicatesOnly2:", 2.39611697197}, {"returnDuplicatesOnly3:", 0.038006067276}}

–Cocoa Scripting最速?
on returnDuplicatesOnly1:aList
  set arrayOne to current application’s NSArray’s arrayWithArray:aList
  
set setOne to current application’s NSCountedSet’s alloc()’s initWithArray:(arrayOne)
  
set arrayTwo to (arrayOne’s valueForKeyPath:"@distinctUnionOfObjects.self")
  
set setTwo to current application’s NSCountedSet’s alloc()’s initWithArray:(arrayTwo)
  
setOne’s minusSet:setTwo
  
return setOne’s allObjects() as list –>{3, 6, 4}
end returnDuplicatesOnly1:

–1より遅い
on returnDuplicatesOnly2:(aList as list)
  set aSet to current application’s NSCountedSet’s alloc()’s initWithArray:aList
  
set bList to (aSet’s allObjects()) as list
  
  
set dupList to {}
  
repeat with i in bList
    set aRes to (aSet’s countForObject:i)
    
if aRes > 1 then
      set the end of dupList to (contents of i)
    end if
  end repeat
  
  
return dupList
end returnDuplicatesOnly2:

–リスト中から重複項目をリストアップする(Vanilla AS高速化版)
on returnDuplicatesOnly3:(aList)
  script spd
    property aList : {}
    
property dList : {}
  end script
  
  
copy aList to (aList of spd)
  
set aCount to length of (aList of spd)
  
  
set (dList of spd) to {}
  
  
repeat aCount times
    set anItem to contents of (first item of (aList of spd))
    
set (aList of spd) to rest of (aList of spd)
    
    
if {anItem} is in (aList of spd) then
      if {anItem} is not in (dList of spd) then –ここを追加した (v3)
        set the end of (dList of spd) to anItem
      end if
    end if
    
  end repeat
  
  
return (dList of spd)
end returnDuplicatesOnly3:

★Click Here to Open This Script 

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

BridgePlusを使わずに1D–>2D list変換 v2

Posted on 2月 5 by Takaaki Naganoya

BridgePlus AppleScript Libraryを使わずに、1D Listを2D Listに変換するAppleScriptの改修版です。

指定アイテム数で1D Listを2D化する処理において、対象listが指定アイテム数の倍数になっていなかった場合にギャップ項目を追加する処理を追加しました。10万項目の1D Listを2D化するのに0.5秒程度で処理できました(M2 MacBook Air)。実用レベルにはあると思われます。

動作OSバージョンには、とくに制限はありません。

AppleScript名:BridgePlusを使わずに1D–>2D list_v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/02/03
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

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

set dList to {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}

set aRes to my subarraysFrom:(dList) groupedBy:6 gapFilledBy:0
–> {{1, 2, 3, 4, 5, 6}, {7, 8, 9, 10, 11, 12}, {13, 14, 15, 16, 0, 0}}

set bRes to my subarraysFrom:(dList) groupedBy:4 gapFilledBy:0
–> {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}

set cRes to my subarraysFrom:(dList) groupedBy:3 gapFilledBy:0
–> {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}, {13, 14, 15}, {16, 0, 0}}

–1D Listの2D LIst化
on subarraysFrom:aList groupedBy:colCount gapFilledBy:gapItem
  script spd
    property aList : {}
    
property bList : {}
    
property cList : {}
  end script
  
  
copy aList to (aList of spd) –deep copy (Important !!!)
  
  
set (bList of spd) to {}
  
set (cList of spd) to {}
  
  
set aLen to length of (aList of spd)
  
set aMod to aLen mod colCount
  
  
–あらかじめ指定数(groupedBy)の倍数になっていない場合にはgap itemを末尾に足しておく
  
if aMod is not equal to 0 then
    repeat (colCount – aMod) times
      set the end of (aList of spd) to gapItem
    end repeat
    
set aLen to length of (aList of spd)
  end if
  
  
–通常処理
  
repeat with i from 1 to aLen by colCount
    set (bList of spd) to items i thru (i + colCount – 1) of (aList of spd)
    
set the end of (cList of spd) to (bList of spd)
  end repeat
  
  
return (cList of spd)
end subarraysFrom:groupedBy:gapFilledBy:

★Click Here to Open This Script 

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

BridgePlusを使わずに1D–>2D list変換

Posted on 2月 4 by Takaaki Naganoya

BridgePlus AppleScript Libraryを使わずに、1D Listを2D Listに変換するAppleScriptです。

Script Debuggerの開発が終了したため、Frameworkを内蔵したBridgePlusの運用についても、今後は「Script Debuggerをダウンロードして動かしてほしい」といったお願いができなくなるかもしれません。

BridgePlus AppleScriptライブラリは有用ですが、Frameworkを含んでいるため実行できる環境が限られるかもしれません(ASObjC Explorerが復活しないかなー)。そのための「準備」です。

AppleScript名:BridgePlusを使わずに1D–>2D list.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/02/03
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

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

set dList to {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
set aRes to my subarraysFrom:dList groupedBy:3
–> {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}, {13, 14, 15}}

set aRes to my subarraysFrom:dList groupedBy:5
–> {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}}

–1D Listの2D LIst化
on subarraysFrom:aList groupedBy:colCount
  script spd
    property aList : {}
    
property bList : {}
    
property cList : {}
  end script
  
  
set (aList of spd) to aList
  
set (bList of spd) to {}
  
set (cList of spd) to {}
  
  
set aLen to length of (aList of spd)
  
  
set aMod to aLen mod colCount
  
if aMod is not equal to 0 then error "Item number does not match paramaters"
  
  
repeat with i from 1 to aLen by colCount
    set (bList of spd) to items i thru (i + colCount – 1) of (aList of spd)
    
set the end of (cList of spd) to (bList of spd)
  end repeat
  
  
return (cList of spd)
end subarraysFrom:groupedBy:

★Click Here to Open This Script 

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

電子書籍を2冊刊行

Posted on 2月 1 by Takaaki Naganoya

相次いで、AppleScriptに関する電子書籍を2冊刊行しました。

AppleScript最新リファレンス v2.8対応 v2.0

「AppleScript最新リファレンス OS X 10.11対応」から最新環境の情報を反映させ、さらにmacOS 15の情報を反映させた最新アップデート版です。最新のAppleScript v2.8環境を対象としています。

→ 販売ページ

macOS搭載のApple純正GUIアプリケーション操作用スクリプト言語「AppleScript」について、スクリプトの書き方、基本的な文法から高度なノウハウまで紹介する最新のリファレンス! macOS 12/13/14/15対応

90ページの記事を追加しました。すでに購入された方は、再ダウンロードにより無料で最新版を入手できます。

本書および「スクリプトエディタScripting Book with AppleScript」には、お待たせの(?)Piyomaru Script Assistant最新版を添付しています。

PDF 1,098ページ+付録Zipアーカイブ

スクリプトエディタScripting Book with AppleScript

macOS上のスクリプティング言語「AppleScript」によって、macOS標準装備のAppleScript記述用アプリ「スクリプトエディタ」を操作するノウハウについて基礎から応用までを詳細にまとめた電子書籍です。

→ 販売ページ

AppleScriptの中でも、超高レベルな内容であり、この内容が苦もなく理解できたら達人と言って問題ないでしょう。ただし、基礎から詳細に解説を行なっているため、難しい内容については読み飛ばしていただいてもけっこうです。それでも、日々のMac生活の中で役立つ超絶テクニックを感じることができるでしょう。 PDF 570ページ、Zipアーカイブ添付

これまであまり外部に出してこなかった、AppleScriptでAppleScriptを解析して処理する内容や、AppleScript用語辞書を解析して処理する内容、スクリプトアシスタントの書き方などの「秘伝のタレ」的な内容を多く含んでいます。

とくに、AppleScript構文色分け設定から実際のAppleScriptの各構文要素を特定して処理(変数のみの置換など)する内容は、Mac OS X 10.4の時代から続いてきた手法から最新の手法まで詳細にご紹介しています。

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

Frameworkを任意のパスからloadして実行するじっけん

Posted on 1月 29 by Takaaki Naganoya

オープンソースのCocoa Frameworkをgithubなどからダウンロードしてビルドし、AppleScriptから実行することは日常的に行なっています。

ただし、これはmacOS 10.14で~/Library/Frameworksから読み込んで実行することが、スクリプトエディタ上では禁止、Script Debuggerでのみ可能という状況です。

macOS標準添付のFrameworkの多くは、/System/Library/Frameworks以下に(若干の例外はあれど)配置されていることが期待されます。

スクリプトエディタ上で実行するScriptについては、macOSデフォルトインストールされているAppleのFrameworkしか呼び出せない状況です。

そこで、/Library/Frameworksあたりに入れたFrameworkを強制的に呼び出せないかと実験してみたものが、これです。

choose fileで指定したFrameworkを強制的に読み込んで実行するテストを行なってみました。結果からいえば、Script Debugger上では実行できるのですが、スクリプトエディタではloadが行えず、エラーになりました。

結論:残念!

もともと、ホームディレクトリ以下のバイナリを呼び出すことをSIPで禁止したいというセキュリティ上のポリシーによって、macOS 10.14以降ではmacOS標準装備のスクリプトエディタが影響を受けました。

Script Debuggerでこの点は補われていたわけですが、AppleScriptから/Library/FrameworkにインストールしたFrameworkを呼び出すことを許可していただきたいところです。/Library/Frameworkなら、ホームディレクトリ以下ではないし、管理者権限がないとFrameworkのインストールもできないため、サードパーティのFrameworkのインストール先としては妥当です。何らかの悪意をもったソフトウェアがFrameworkを勝手にインストールする危険性も低いことでしょう。

AppleScript名:Framerokを任意のパスからloadして実行するじっけん.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/01/29
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

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

set fPath to POSIX path of (choose file)

loadAndExecuteFramework(fPath, "SFPSDWriter") of me

on loadAndExecuteFramework(frameworkPath, functionName)
  — Frameworkのパスをチェック
  
(*
  if frameworkPath does not start with "/Library/" then
    display dialog "Error: Framework path must be inside /Library/"
    return
  end if
  *)

  
  
— Frameworkをロード
  
set frameworkNSURL to current application’s NSURL’s fileURLWithPath:frameworkPath
  
set bundle to current application’s NSBundle’s bundleWithURL:frameworkNSURL
  
  
if bundle is missing value then
    display dialog "Error: Failed to load framework at " & frameworkPath
    
return
  end if
  
  
— Frameworkのクラスをロード
  
set isLoaded to bundle’s load()
  
if isLoaded is false then
    display dialog "Error: Failed to load framework"
    
return
  end if
  
  
— クラスを取得
  
set className to current application’s NSClassFromString(functionName)
  
if className is missing value then
    display dialog "Error: Function ’" & functionName & "’ not found"
    
return
  end if
  
  
log className
  
  
— メソッドを実行(クラスメソッドとして想定)
  
try
    className’s performSelector:"execute"
    
display dialog "Function ’" & functionName & "’ executed successfully."
  on error errMsg
    display dialog "Error executing function: " & errMsg
  end try
end loadAndExecuteFramework

★Click Here to Open This Script 

Posted in System | Tagged 13.0savvy 14.0savvy 15.0savvy | Leave a comment

Finder上で選択中のファイルをJPEG形式で指定フォルダに書き出し(自動補正つき)

Posted on 1月 23 by Takaaki Naganoya

Finderの最前面のウィンドウで選択しておいた画像をオープンして自動画質補正を行いつつ、指定の番号からの連番をつけたJPEG画像に変換して指定フォルダに書き込むAppleScriptです。

さっそく、昨日書いた画質自動補正のプログラムを使い回しています。他のものもほぼ、過去に書いたものを使い回しているだけで、新規に書いた部分はほとんどありません。必要以上に長くなっており、おそらく呼び出していないルーチンなども含まれているはずです。

この、連番のJPEG画像はプロジェクターのスライドショー機能を用いて写真を表示するための仕様です。USBメモリなどにJPEG画像を入れておくと、ファイル名順に再生を行ってくれます。

当初はMacをプロジェクターにつないで写真.app(Photos.app)のBGMつきスライドショーを試してみたのですが、BGMに合わせた画像切り替えを行ってくれる一方で、強制的に1写真あたりの表示時間を指定することができず、「これでは使えない」として、プロジェクターの内蔵スライドショー機能を使うことにしたので、このようなScriptを作ったものです。

AppleScript名:Finder上で選択中のファイルをJPEG形式で指定フォルダに書き出し(自動補正つき).scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/01/23
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

use AppleScript
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "CoreImage"
use framework "UniformtypeIdentifiers"

property CIFilter : a reference to current application’s CIFilter
property NSArray : a reference to current application’s NSArray
property CIImage : a reference to current application’s CIImage
property NSUUID : a reference to current application’s NSUUID
property |NSURL| : a reference to current application’s |NSURL|
property NSString : a reference to current application’s NSString
property NSImage : a reference to current application’s NSImage
property NSPredicate : a reference to current application’s NSPredicate
property NSPNGFileType : a reference to current application’s NSPNGFileType
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep

tell application "Finder"
  set aSel to selection as alias list
end tell

set posList to {}
set aCount to 1

set bFol to POSIX path of (choose folder with prompt "出力先フォルダを選択")

repeat with i in aSel
  set j to POSIX path of i
  
set aUTI to getUTIFromFile(j) of me
  
if aUTI is not equal to missing value then
    –ファイルから求めたUTIが指定のUTIに含まれるかをチェック
    
set bRes to filterUTIList({aUTI}, "public.image")
    
    
if bRes is not equal to {} then
      –自動画質調整
      
set aNSImage to makeNSImageFromPOSIXpath(j) of me
      
set bImgRes to autoFiltersForNSImage(aNSImage) of me
      
if bImgRes = false then return
      
      
–NSImageをJPEGで書き出す
      
set aStr to makeFN(aCount, 5) of me
      
set outPath to bFol & aStr & ".jpg"
      
set sRes to saveNSImageAtPathAsJPG(bImgRes, outPath, 0.9) of JPGkit
      
      
set aCount to aCount + 1
      
    else
      log j
    end if
    
    
log j
  end if
end repeat

on autoFiltersForNSImage(aNSImage)
  set aCIImage to convNSImageToCIimage(aNSImage) of me
  
set filterList to aCIImage’s autoAdjustmentFilters
  
if filterList = missing value then return false
  
  
repeat with i in filterList
    set aFilter to contents of i
    (
aFilter’s setValue:(aCIImage) forKey:"inputImage")
    
set aOutImage to (aFilter’s valueForKey:"outputImage")
    
    
copy aOutImage to aCIImage
  end repeat
  
  
set outNSImage to convCIimageToNSImage(aOutImage) of me
  
  
return outNSImage
end autoFiltersForNSImage

on convCIimageToNSImage(aCIImage)
  set aRep to NSBitmapImageRep’s alloc()’s initWithCIImage:aCIImage
  
set tmpSize to aRep’s |size|()
  
set newImg to NSImage’s alloc()’s initWithSize:tmpSize
  
newImg’s addRepresentation:aRep
  
return newImg
end convCIimageToNSImage

on convNSImageToCIimage(aNSImage)
  set tiffDat to aNSImage’s TIFFRepresentation()
  
set aRep to NSBitmapImageRep’s imageRepWithData:tiffDat
  
set newImg to CIImage’s alloc()’s initWithBitmapImageRep:aRep
  
return newImg
end convNSImageToCIimage

on makeNSImageFromAlias(anAlias)
  set imgPath to (POSIX path of anAlias)
  
set aURL to (|NSURL|’s fileURLWithPath:(imgPath))
  
return (NSImage’s alloc()’s initWithContentsOfURL:aURL)
end makeNSImageFromAlias

on makeNSImageFromPOSIXpath(aPOSIX)
  set aURL to (|NSURL|’s fileURLWithPath:(aPOSIX))
  
return (NSImage’s alloc()’s initWithContentsOfURL:aURL)
end makeNSImageFromPOSIXpath

on getUTIFromFile(aPath)
  set aWS to current application’s NSWorkspace’s sharedWorkspace()
  
set pRes to (aWS’s isFilePackageAtPath:aPath) as boolean
  
if pRes = false then
    set superType to (current application’s UTTypeData)
  else
    set superType to (current application’s UTTypePackage)
  end if
  
  
set pathString to current application’s NSString’s stringWithString:aPath
  
set aExt to (pathString’s pathExtension()) as string
  
  
set aUTType to current application’s UTType’s typeWithFilenameExtension:aExt conformingToType:(superType)
  
if aUTType = missing value then return missing value
  
  
set aUTIstr to aUTType’s identifier() as string
  
return aUTIstr
end getUTIFromFile

on filterUTIList(aUTIList, aUTIstr)
  set anArray to NSArray’s arrayWithArray:aUTIList
  
set aPred to NSPredicate’s predicateWithFormat_("SELF UTI-CONFORMS-TO %@", aUTIstr)
  
set bRes to (anArray’s filteredArrayUsingPredicate:aPred) as list
  
return bRes
end filterUTIList

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

script JPGkit
  use scripting additions
  
use framework "Foundation"
  
use framework "AppKit"
  
property parent : AppleScript
  
  
on saveAImageASJPG(aFile, aNewFile)
    set aPOSIX to (POSIX path of aFile)
    
set aImage to current application’s NSImage’s alloc()’s initWithContentsOfFile:(aPOSIX)
    
    
set newPath to current application’s NSString’s stringWithString:(POSIX path of aNewFile)
    
set newExt to (newPath’s pathExtension()) as string
    
if newExt is not equal to "jpg" then
      set newPath to repFilePathExtension(newPath, ".jpg") of me
    end if
    
    
set sRes to saveNSImageAtPathAsJPG(aImage, newPath, 1.0) of me
  end saveAImageASJPG
  
  
  
on repFilePathExtension(origPath, newExt)
    set aName to current application’s NSString’s stringWithString:origPath
    
set theExtension to aName’s pathExtension()
    
if (theExtension as string) is not equal to "" then
      set thePathNoExt to aName’s stringByDeletingPathExtension()
      
set newName to (thePathNoExt’s stringByAppendingString:newExt)
    else
      set newName to (aName’s stringByAppendingString:newExt)
    end if
    
return newName as string
  end repFilePathExtension
  
  
  
–NSImageを指定パスにJPEG形式で保存、qulityNumは0.0〜1.0。1.0は無圧縮
  
on saveNSImageAtPathAsJPG(anImage, outPath, qulityNum as real)
    set imageRep to anImage’s TIFFRepresentation()
    
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
    
set pathString to current application’s NSString’s stringWithString:outPath
    
set newPath to pathString’s stringByExpandingTildeInPath()
    
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSJPEGFileType) |properties|:{NSImageCompressionFactor:qulityNum})
    
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
    
return aRes –true/false
  end saveNSImageAtPathAsJPG
end script

★Click Here to Open This Script 

Posted in Image UTI | Tagged 13.0savvy 14.0savvy 15.0savvy | Leave a comment

CoreImageで指定画像をautoAdjustmentFilters

Posted on 1月 21 by Takaaki Naganoya

Core ImageのCIFilterから、autoAdjustmentFiltersを呼び出して、いい感じにKeynote上とかで自動画像調整を行うのと同様に、画像に対して自動調整を行うAppleScriptです。

KeynoteやPages上の画像の自動補正機能は、大当たりすることもなければ大はずしすることもない、なかなかお得な機能です。

ちょっと、Finder上で選択した画像にひととおり自動補正をかけてお茶をにごしたい。

そんな機能が存在しないかと調べていたのですが、autoAdjustmentFiltersの存在は知っていたものの、いろいろ試しては、

current application’s CIImage’s autoAdjustmentFilters()

とか、

current application’s CIFilter’s autoAdjustmentFilters()

などと間違った記述を行なってmissing valueが返ってきては、首をひねりまくっていました。

Googleの検索エンジンで探してもなかなかサンプルに行き当たらないあたり、みんな苦労しているんじゃないかと疑っていますが、これは、

CIImage画像に対してautoAdjustmentFilters()を実行すると、自動調整用のCIFilterにパラメータが設定された状態でarrayに入って返ってくるのでした(これは、わからないぞ)。

半信半疑で実行してみたら、なんとなくそれっぽく自動調整された画像がデスクトップに出力されます。

AppleScript名:CoreImageで指定画像をautoAdjustmentFilters.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/01/21
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.8"
use framework "Foundation"
use framework "AppKit"
use framework "CoreImage"
use scripting additions

property CIFilter : a reference to current application’s CIFilter
property NSUUID : a reference to current application’s NSUUID
property |NSURL| : a reference to current application’s |NSURL|
property CIImage : a reference to current application’s CIImage
property NSString : a reference to current application’s NSString
property NSImage : a reference to current application’s NSImage
property NSPNGFileType : a reference to current application’s NSPNGFileType
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep

set imgPath to POSIX path of (choose file)
set aNSImage to makeNSImageFromPOSIXpath(imgPath) of me

set bImgRes to autoFiltersForNSImage(aNSImage) of me
if bImgRes = false then return

set outPath to retUUIDfilePath(POSIX path of (path to desktop), "png") of me
set sRes to saveNSImageAtPathAsPNG(bImgRes, outPath) of me

on autoFiltersForNSImage(aNSImage)
  set aCIImage to convNSImageToCIimage(aNSImage) of me
  
set filterList to aCIImage’s autoAdjustmentFilters
  
if filterList = missing value then return false
  
  
repeat with i in filterList
    set aFilter to contents of i
    (
aFilter’s setValue:(aCIImage) forKey:"inputImage")
    
set aOutImage to (aFilter’s valueForKey:"outputImage")
    
    
copy aOutImage to aCIImage
  end repeat
  
  
set outNSImage to convCIimageToNSImage(aOutImage) of me
  
  
return outNSImage
end autoFiltersForNSImage

on retUUIDfilePath(aPath, aEXT)
  set aUUIDstr to (NSUUID’s UUID()’s UUIDString()) as string
  
set aPath to ((NSString’s stringWithString:aPath)’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:aEXT
  
return aPath
end retUUIDfilePath

on convCIimageToNSImage(aCIImage)
  set aRep to NSBitmapImageRep’s alloc()’s initWithCIImage:aCIImage
  
set tmpSize to aRep’s |size|()
  
set newImg to NSImage’s alloc()’s initWithSize:tmpSize
  
newImg’s addRepresentation:aRep
  
return newImg
end convCIimageToNSImage

on convNSImageToCIimage(aNSImage)
  set tiffDat to aNSImage’s TIFFRepresentation()
  
set aRep to NSBitmapImageRep’s imageRepWithData:tiffDat
  
set newImg to CIImage’s alloc()’s initWithBitmapImageRep:aRep
  
return newImg
end convNSImageToCIimage

on makeNSImageFromAlias(anAlias)
  set imgPath to (POSIX path of anAlias)
  
set aURL to (|NSURL|’s fileURLWithPath:(imgPath))
  
return (NSImage’s alloc()’s initWithContentsOfURL:aURL)
end makeNSImageFromAlias

on makeNSImageFromPOSIXpath(aPOSIX)
  set aURL to (|NSURL|’s fileURLWithPath:(aPOSIX))
  
return (NSImage’s alloc()’s initWithContentsOfURL:aURL)
end makeNSImageFromPOSIXpath

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to NSBitmapImageRep’s imageRepWithData:imageRep
  
set pathString to NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
set myNewImageData to (aRawimg’s representationUsingType:(NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –true/false
end saveNSImageAtPathAsPNG

★Click Here to Open This Script 

Posted in filter Image | Tagged 12.0savvy 13.0savvy 14.0savvy 15.0savvy CIFilter CIImage | Leave a comment

Numbersで選択範囲のデータを切り捨て

Posted on 1月 20 by Takaaki Naganoya

Numbersの表の選択範囲のデータを指定の数(10,000とか、100万とか)で切り捨てるAppleScriptです。Numbers v14.3で検証してありますが、凝った機能は何も使っていないので、古いバージョンのNumbersでも問題なく動作することでしょう。

もともとは、Keynoteで作った資料でデータが細かくて見にくかったので、指定桁で切り捨て(100万円で切り捨て、など)するために作ったものです。

本来はiWorkアプリ上でこうした操作を行うには、「データフォーマット」で「カスタムフォーマット」を定義するのがiWorkの流儀です。

ただ、このカスタムフォーマットが割と遠回りでわかりにくかったので(+AppleScriptから操作できないので)、即物的にデータを編集するプログラムを作ってしまった次第です。割と、使い捨てレベルの素朴なScriptでもあります。

AppleScript名:選択範囲のデータを100万円で切り捨て.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/01/19
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

set calcNum to 10000

tell application "Numbers"
  tell front document
    tell active sheet
      tell table 1
        set aSel to cell of selection range
        
        
set newList to {}
        
repeat with i in aSel
          set j to contents of i
          
if j is not equal to missing value then
            set tmpV1 to (value of j)
            
if tmpV1 is not equal to missing value then
              set tmpV2 to tmpV1 div calcNum
              
ignoring application responses
                set value of j to tmpV2
              end ignoring
            end if
          end if
        end repeat
      end tell
    end tell
  end tell
end tell

★Click Here to Open This Script 

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

Pagesで選択中のテキストボックスの一番近くにある白い文字のボックスのテキストを取得

Posted on 1月 16 by Takaaki Naganoya

Pagesで作成した書類で、プログラムリストの上に配置したタイトルのテキストを取得するAppleScriptです。

割といきあたりばったりで作ってしまったツールです。

Pagesで電子書籍を作成し、レイアウトしたAppleScriptのプログラムリストのファイル名を求めるために、プログラムリストの上に配置した白い文字で記述したテキストフレーム(Pages上ではShapeオブジェクト)を特定します。

フィルタ参照で相対座標値を表現できるといいのですが、そういうのはできないので、地道に距離計算しています。

「上」「下」という相対的な位置関係を表現するのに、結局数値比較しかできないので、どうしたものかと考えていたのですが、結局この「上」という表現は用いずじまいでした。「一番距離が近いテキストフレーム、文字色は白っぽい」だけで割と正確に特定できたので、いいだろうかというところです。相対位置関係を表記するライブラリなども作っておくといいかもしれません。

予想外の要素が、白いとだけ思っていた文字色が、RGB値では若干ゆらいでいたので、そのあたりの辻褄合わせを地味にやっています。カラードメイン(色名をラフに計算する)系のライブラリを使えば「white」などと雑な表現で指定できたかもしれません。

実際に使っているものは、本Scriptにくわえて選択中のテキストフレームの内容をAppleScriptとしてメモリ上で構文確認とコンパイルを行なって、ここで取得したファイル名でAppleScriptとして保存する処理を行なっています。

AppleScript名:Pagesで選択中のテキストボックスの一番近くにある白い文字のボックスの名前を取得.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/01/16
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

use AppleScript
use scripting additions
use framework "Foundation"
use framework "OSAKit"

property |NSURL| : a reference to current application’s |NSURL|
property OSANull : a reference to current application’s OSANull
property NSString : a reference to current application’s NSString
property OSAScript : a reference to current application’s OSAScript
property OSALanguage : a reference to current application’s OSALanguage
property NSFontAttributeName : a reference to current application’s NSFontAttributeName
property OSALanguageInstance : a reference to current application’s OSALanguageInstance
property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey

tell application "Pages"
  tell front document
    set aSel to selection
    
if aSel = {} then return
    
set aaSel to first item of aSel
    
    
set targPos to position of aaSel
    
set targCon to object text of aaSel –選択中のtext frame(Pages上ではShape)の本文
    
    
tell current page
      –文字が入っているiWork objectのみが対象
      
set tList to every shape whose object text is not equal to targCon and object text of it is not equal to "" –オブジェクト
      
set pList to position of every shape whose object text is not equal to targCon and object text of it is not equal to "" –座標
      
set cList to color of object text of every shape whose object text is not equal to targCon and object text of it is not equal to "" –文字色
    end tell
    
    
–クレヨンピッカーから指定しても、白色に若干の「ゆらぎ」があるようなので、数値比較で抽出
    
set aRes to findItemNums({65500, 65500, 65500}, cList) of me
    
set aLen to length of aRes
    
if aLen = 0 then
      display dialog "No Hit(error)"
      
    else if aLen = 1 then
      set tmpTarg to first item of aRes
      
set tmpTargTextFrame to item tmpTarg of tList
      
set oRes to object text of tmpTargTextFrame
      
    else
      set p2List to {}
      
repeat with i in aRes
        set j to contents of i
        
set the end of p2List to contents of item j of pList
      end repeat
      
      
set L2ItemNums to retNearestItemByPosition({targPos}, p2List) of me
      
set oRes to object text of (item (first item of L2ItemNums) of tList)
      
    end if
  end tell
end tell

return oRes

–RGBの値がaNumにlistで入ってくる{r, g, b}
–リスト中に入っている指定要素をサーチして、各チャネルの値よりも大きい場合に合致したとみなし、出現アイテム番号を返す(複数対応)
on findItemNums(aNum, aList)
  if aList = {missing value} then return {}
  
if aNum = {missing value} then return {}
  
  
set iCount to 1
  
set hitF to false
  
set hitList to {}
  
copy aNum to {aNum1, aNum2, aNum3}
  
  
repeat with i in aList
    set j to contents of i
    
if j is not equal to missing value then
      copy j to {tmpR, tmpG, tmpB}
      
      
if (tmpR > aNum1) and (tmpG > aNum2) and (tmpB > aNum3) then
        set the end of hitList to iCount
      end if
    end if
    
set iCount to iCount + 1
  end repeat
  
  
return hitList
end findItemNums

on retNearestItemByPosition(L1Pos, L2Pos)
  
  
set resItemNum to {}
  
  
repeat with i in L1Pos
    set j to contents of i
    
set iCount to 1
    
set tDList to {}
    
    
repeat with ii in L2Pos
      set jj to contents of ii
      
      
copy jj to {tmpX1, tmpY1}
      
copy j to {tmpX2, tmpY2}
      
      
if tmpX1 ≥ tmpX2 then
        set xDist to tmpX1 – tmpX2
      else
        set xDist to tmpX2 – tmpX1
      end if
      
      
if tmpY1 ≥ tmpY2 then
        set yDist to tmpY1 – tmpY2
      else
        set yDist to tmpY2 – tmpY1
      end if
      
      
set tArea to xDist * yDist
      
set t2Area to absNum(tArea) of me
      
set the end of tDList to {area:t2Area, itemNum:iCount}
      
set iCount to iCount + 1
    end repeat
    
    
set resList to sortRecListByLabel(tDList, "area", true) of me
    
–> {{itemNum:2, area:100}, {itemNum:3, area:1739}, {itemNum:4, area:3780}, {itemNum:1, area:4554}}
    
    
set tItem to itemNum of first item of resList
    
set the end of resItemNum to tItem
    
  end repeat
  
  
return resItemNum
end retNearestItemByPosition

on arrangeTargItemByItemNumList(L2Pos, L2ItemNums)
  set L3Pos to {}
  
repeat with i in L2ItemNums
    set j to contents of i
    
set the end of L3Pos to item j of L2Pos
  end repeat
  
  
return L3Pos
end arrangeTargItemByItemNumList

on absNum(q)
  if q is less than 0 then set q to –q
  
return q
end absNum

–リストに入れたレコードを、指定の属性ラベルの値でソート
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 

Posted in list Text | Tagged 13.0savvy 14.0savvy 15.0savvy Pages | Leave a comment

Numbersで選択中の範囲を横方向に逆順に並べて、選択範囲に再設定

Posted on 1月 14 by Takaaki Naganoya

Numbersで縦方向に行単位で任意の並べ替え(Ascending、Descending)を行うのは問題ないのですが、横方向に並べ替えをする機能がなかったので、作ってみました。


▲初期状態。左側のデータが新しく、右端が一番古いデータ。並べ替えを行う範囲を選択


▲実行後。横方向に逆順に並べ替えを行った。左端が一番古く、右端が一番新しいデータ

標準機能で欲しいところです。

データ取得は速いものの、スプレッドシートへのデータの書き込みに時間のかかるNumbers。本ScriptもApple Silicon Macで実行すればそこそこの速度で実行してくれますが、おそらくExcelに対して同様の処理を実行したら1,000倍ぐらい高速です。

それほど大量のデータを処理すると、非同期処理が途中でおかしくなるので、数千セルぐらいを上限としておいたほうがよいでしょう。

AppleScript名:Numbersで選択中の範囲を横方向に逆順に並べて、選択範囲に再設定.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/01/14
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

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

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

set (aList of spd) to get2DListFromNumbersSelection() of me
if (aList of spd) = "" then return "No Selection"

set (bList of spd) to {}

repeat with i in (aList of spd)
  set tmpList to contents of i
  
set tmpList to reverse of tmpList
  
set the end of (bList of spd) to tmpList
end repeat

set (bList of spd) to FlattenList((bList of spd)) of me

tell application "Numbers"
  tell front document
    tell active sheet
      tell table 1
        set (cList of spd) to cell of selection range
        
        
set iCount to 1
        
repeat with i in (cList of spd)
          set newVal to contents of item iCount of (bList of spd)
          
if (newVal as string) is equal to "missing value" then set newVal to ""
          
          
ignoring application responses
            set value of i to newVal
          end ignoring
          
          
set iCount to iCount + 1
        end repeat
      end tell
    end tell
  end tell
end tell

on get2DListFromNumbersSelection()
  –Numbersで選択範囲を縦に区切ったリストを返す
  
tell application "Numbers"
    tell front document
      tell active sheet
        try
          set theTable to first table whose class of selection range is range
        on error
          return "" –何も選択されてなかった場合
        end try
        
        
tell theTable
          set selList to value of every cell of selection range –選択範囲のデータを取得
          
          
set selName to name of selection range –選択範囲のrange情報を取得
          
set {s1, s2} to parseByDelim(selName, ":") of me
          
          
–始点の情報を取得する
          
set s1Row to (address of row of range s1) as integer
          
set s1Column to (address of column of range s1) as integer
          
          
–終点の情報を取得する
          
set s2Row to (address of row of range s2) as integer
          
set s2Column to (address of column of range s2) as integer
          
          
–選択範囲の情報を取得する
          
set selHeight to s2Row – s1Row + 1 –高さ(Height of selection range)
          
set selWidth to s2Column – s1Column + 1 –幅(Width of selection range)
          
        end tell
      end tell
    end tell
  end tell
  
  
set aLen to length of selList
  
set aaLen to selHeight
  
  
set bList to {}
  
repeat with i from 1 to aaLen
    set aHoriList to {}
    
    
repeat with ii from 1 to selWidth
      set j1 to ii + (i – 1) * selWidth
      
set tmpCon to contents of item j1 of selList
      
      
set aClass to class of tmpCon
      
if aClass = number or aClass = integer or aClass = real then
        set tmpCon to tmpCon as integer
      end if
      
      
set the end of aHoriList to tmpCon
    end repeat
    
    
set the end of bList to aHoriList
  end repeat
  
  
return bList
end get2DListFromNumbersSelection

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

–By Paul Berkowitz
–2009年1月27日 2:24:08:JST
–Re: Flattening Nested Lists
on FlattenList(aList)
  set oldDelims to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to {"????"}
  
set aString to aList as text
  
set aList to text items of aString
  
set AppleScript’s text item delimiters to oldDelims
  
return aList
end FlattenList

★Click Here to Open This Script 

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

Skimがv1.7.8でopen locationコマンドを削除

Posted on 1月 14 by Takaaki Naganoya

オープンソースのPDFビューワー「Skim」がバージョン1.7.8において「open location」コマンドを削除しました。

open locationコマンドは標準装備されているものであり、Skim側で実装しなくても問題ないという結論に至ったのかもしれません。

なお、オープンできる(Skimが応答する)URLはhttps://のみであり、http://については応答しないのもv1.7.6から変わっていません。

ただ、これまでにSkimは何度も「トラブルを起こしたコマンドをいったん削除してあとあと再実装」という動きをしているので、再実装される可能性は否定できません。しらんけど。

Posted in URL | Tagged 13.0savvy 14.0savvy 15.0savvy Skim | Leave a comment

選択範囲の値を取得して、冒頭の値の新しい数値を指定すると以下自動加算

Posted on 1月 14 by Takaaki Naganoya

Numbers上で選択範囲のデータに対して一括で数値を加算するAppleScriptです。

Numbers上で台割(PDFに対して付加するTOC用データ)を管理しているところに、実際の電子書籍の記事が増えて、各記事のノンブル(ページ番号)を変更する必要があるわけですが……これに、当初は「+18で」みたいなScriptを運用していたのですが、暗算で差分を計算していたものの、この仕様だと使いにくかったのです。

そこで、新たなページ数を入力すると、AppleSript側で差分を計算して後の選択範囲に対して加算するようにしてみました。


▲初期状態


▲PDFを参照して新版の「おくづけ」は552ページになっていることを確認 ここで、本Scriptを実行


▲差分(増分)を暗算で計算して入力するのではなく、最初のページの変更後のページ数が何か、を入力。Script側で差分を自動計算


▲実行後の状態

巨大なScriptも役立ちますが、こういう「ちょっとした」サイズのScriptもまた役に立ちます。

AppleScript名:選択範囲の値を取得して、冒頭の値の新しい数値を指定すると以下自動加算.scpt
set sNum to text returned of (display dialog "Input New First Num" default answer "")
tell application "Numbers"
  tell front document
    tell active sheet
      tell table 1
        set mySelectedRanges to value of every cell of selection range
        
set cellList to cell of selection range
        
        
set addNum to sNum – (first item of mySelectedRanges)
        
        
        
set iCount to 0
        
set newList to {}
        
repeat with i in cellList
          set tmpVal to value of i
          
set the end of newList to tmpVal + addNum
        end repeat
        
        
repeat with i from 1 to (length of cellList)
          tell item i of cellList
            set value to item i of newList
          end tell
        end repeat
      end tell
    end tell
  end tell
end tell

★Click Here to Open This Script 

Posted in Number | Tagged 13.0savvy 14.0savvy 15.0savvy Numbers | Leave a comment

スタイルつきテキストでスタイルつきテキストを検索 v1.1

Posted on 1月 13 by Takaaki Naganoya

スタイルつきテキストの中をスタイルつきテキストで検索するAppleScriptです。フォント、サイズ、色の属性を考慮して文字とこれらの属性値が合っている場合に合致しているものとみなします。

最初のバージョンはChatGPTに書かせたもので、実際に動かしてみたら激遅だったので、2パスで検索することで高速化してみました。オリジナルより100倍以上速くなっているはずです。

Step1: 検索対象文字列、検索文字列の両方をテキスト化して、テキストベースで出現情報を計算
Step2: 出現情報をもとにスタイルつきテキスト(NSAttributedString)の書式情報の照合を行い、合致するものを出力

という処理に変更しました。ChatGPTが出力してきたAppleScriptは、1文字ずつチェック範囲を変更しながら書式情報とテキスト情報の照合を行うという「脳筋処理」だったので、少なく見積もっても100倍。データ量が増えれば増えるほど高速化の度合いが上昇します。

AppleScript名:find Styled Text in Styled Text_v1.1.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/01/12
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

use AppleScript
use framework "Foundation"
use scripting additions

property NSString : a reference to current application’s NSString
property NSLiteralSearch : a reference to current application’s NSLiteralSearch
property NSMutableArray : a reference to current application’s NSMutableArray

— サンプルデータ
set targetText to "これはサンプルテキストです。サンプルは重要です。サンプルだよー。サンプルサンプル"
set searchText to "サンプル"

— 属性付き文字列の作成
set targetAttributedString to current application’s NSMutableAttributedString’s alloc()’s initWithString:targetText
set searchAttributedString to current application’s NSMutableAttributedString’s alloc()’s initWithString:searchText

— 属性を設定 (例: フォントと色)
set targetFont to current application’s NSFont’s fontWithName:"HiraginoSans-W2" |size|:13
set targetColor to current application’s NSColor’s redColor()
set searchFont to current application’s NSFont’s fontWithName:"HiraginoSans-W2" |size|:13
set searchColor to current application’s NSColor’s redColor()

— 属性を追加
targetAttributedString’s addAttribute:(current application’s NSFontAttributeName) value:targetFont range:{0, targetAttributedString’s |length|()}
targetAttributedString’s addAttribute:(current application’s NSForegroundColorAttributeName) value:targetColor range:{0, targetAttributedString’s |length|()}
searchAttributedString’s addAttribute:(current application’s NSFontAttributeName) value:searchFont range:{0, searchAttributedString’s |length|()}
searchAttributedString’s addAttribute:(current application’s NSForegroundColorAttributeName) value:searchColor range:{0, searchAttributedString’s |length|()}

— 属性付き検索を実行
set matches to searchAttributedStringWithAttributes(targetAttributedString, searchAttributedString) of me
–> {{location:3, |length|:4}, {location:14, |length|:4}, {location:24, |length|:4}, {location:32, |length|:4}, {location:36, |length|:4}}

— NSAttributedStringの属性付き検索を行うハンドラー(複数一致対応)
on searchAttributedStringWithAttributes(targetAttributedString, searchAttributedString)
  set targText to targetAttributedString’s |string|() as string
  
  
set searchAttributes to searchAttributedString’s attributesAtIndex:0 effectiveRange:(missing value)
  
set searchString to searchAttributedString’s |string|() as string
  
  
–テキストベースで検索
  
set strRangeList to searchWordRanges(targText, searchString) of me
  
–あとは、検索箇所の文字書式をループで照合する
  
  
set matList to {} — 結果を格納するリスト
  
  
— ループで対象の文字列が含まれる位置の書式情報を検索
  
repeat with i in strRangeList
    set j to contents of i
    
set tmpLoc to location of j
    
set tmpLen to |length| of j
    
    
— 対象範囲の属性を取得
    
set targetAttributes to (targetAttributedString’s attributesAtIndex:(tmpLoc) effectiveRange:(current application’s NSMakeRange(tmpLoc, tmpLen)))
    
    
if (targetAttributes = searchAttributes) then
      set the end of matList to {location:(tmpLoc as integer), |length|:(tmpLen as integer)} — 属性が一致した場合
    end if
  end repeat
  
  
return matList — 一致したすべての範囲を返す
end searchAttributedStringWithAttributes

–プレーンテキストベースで検索文字列の出現情報を返す(複数対応)
on searchWordRanges(aTargText as string, aSearchStr as string)
  set aStr to NSString’s stringWithString:aTargText
  
set bStr to NSString’s stringWithString:aSearchStr
  
  
set hitArray to NSMutableArray’s alloc()’s init()
  
set cNum to (aStr’s |length|()) as integer
  
  
set aRange to current application’s NSMakeRange(0, cNum)
  
  
repeat
    set detectedRange to aStr’s rangeOfString:bStr options:(NSLiteralSearch) range:aRange
    
set aLen to (detectedRange’s |length|) as number
    
    
if aLen = 0 then exit repeat
    
    
hitArray’s addObject:detectedRange
    
    
set aNum to (detectedRange’s location) as number
    
set bNum to (detectedRange’s |length|) as number
    
    
set aRange to current application’s NSMakeRange(aNum + bNum, cNum – (aNum + bNum))
  end repeat
  
  
return hitArray
end searchWordRanges

★Click Here to Open This Script 

Posted in RTF search | Tagged 13.0savvy 14.0savvy 15.0savvy NSColor NSFont NSLiteralSearch NSMutableArray NSMutableAttributedString NSString | Leave a comment

スタイルつきテキストでスタイルつきテキストを検索

Posted on 1月 13 by Takaaki Naganoya

スタイルつきテキストの中をスタイルつきテキストで検索するAppleScriptです。フォント、サイズ、色の属性を考慮して文字とこれらの属性値が合っている場合に合致しているものとみなします。

たかだか3Kバイトごときの文字量のスタイルつきテキストから検索を行うのに、M2 Airで2・3秒ぐらいかかります。

属性値をDictionary in Arrayとして解釈して検索を行うよりも、大幅に処理に時間がかかるようです。

1文字ずつ開始位置をズラして文字&書式の再照合を行っているので、アホみたいに処理時間がかかります。Cocoaの機能を使って処理しているのに、Pagesに問い合わせるよりも時間がかかっている雰囲気です。

本ScriptはChatGPTに書かせたもので、おそらく処理に時間がかかって「無駄」になるものと見込んでいました。

スタイルつきテキストに対してスタイルつきテキストによる検索を行うのは、予想どおりものすごく負荷が大きくなるようで……本Scriptは残念ながら作り捨てになりそうです。

もう少し頭を使って、文字だけで出現位置チェックを行い、出現位置情報をもとに書式の照合を行うようにすれば、10倍ぐらい高速に処理できそうです。

AppleScript名:find Styled Text in Styled Text.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/01/12
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

use AppleScript
use framework "Foundation"
use scripting additions

— 使用例
set targetText to "これはサンプルテキストです。サンプルは重要です。サンプルだよー。"
set searchText to "サンプル"

— 属性付き文字列の作成
set targetAttributedString to current application’s NSMutableAttributedString’s alloc()’s initWithString:targetText
set searchAttributedString to current application’s NSMutableAttributedString’s alloc()’s initWithString:searchText

— 属性を設定 (例: フォントと色)
set targetFont to current application’s NSFont’s fontWithName:"HiraginoSans-W2" |size|:13
set targetColor to current application’s NSColor’s redColor()
set searchFont to current application’s NSFont’s fontWithName:"HiraginoSans-W2" |size|:13
set searchColor to current application’s NSColor’s redColor()

— 属性を追加
targetAttributedString’s addAttribute:(current application’s NSFontAttributeName) value:targetFont range:{0, targetAttributedString’s |length|()}
targetAttributedString’s addAttribute:(current application’s NSForegroundColorAttributeName) value:targetColor range:{0, targetAttributedString’s |length|()}
searchAttributedString’s addAttribute:(current application’s NSFontAttributeName) value:searchFont range:{0, searchAttributedString’s |length|()}
searchAttributedString’s addAttribute:(current application’s NSForegroundColorAttributeName) value:searchColor range:{0, searchAttributedString’s |length|()}

— 属性付き検索を実行
set matches to searchAttributedStringWithAttributes(targetAttributedString, searchAttributedString) of me
–> {{location:3, |length|:4}, {location:14, |length|:4}, {location:24, |length|:4}}

— NSAttributedStringの属性付き検索を行うハンドラー(複数一致対応、変数名変更)
on searchAttributedStringWithAttributes(targetAttributedString, searchAttributedString)
  — 検索対象の全長を取得
  
set targetLength to targetAttributedString’s |length|()
  
set searchLength to searchAttributedString’s |length|()
  
  
— 検索する属性辞書を取得
  
set searchAttributes to searchAttributedString’s attributesAtIndex:0 effectiveRange:(missing value)
  
set searchString to searchAttributedString’s |string|() as string
  
  
— 結果を格納するリスト
  
set matches to {}
  
  
— ループで対象の文字列を検索
  
set currentIndex to 1
  
  
repeat while (currentIndex + searchLength ≤ targetLength)
    — 対象範囲の属性辞書を取得
    
set targetAttributes to targetAttributedString’s attributesAtIndex:currentIndex effectiveRange:(missing value)
    
    
— 対象範囲の文字列を取得
    
set targetRange to (current application’s NSMakeRange(currentIndex, searchLength))
    
set targetSubstring to (targetAttributedString’s attributedSubstringFromRange:(targetRange))’s |string|()
    
    
— 属性と文字列の一致を確認
    
if (targetSubstring as string = searchString) and (targetAttributes = searchAttributes) then
      set end of matches to {location:currentIndex, |length|:searchLength}
    end if
    
    
— 次の位置に進む
    
set currentIndex to currentIndex + 1
  end repeat
  
  
return matches — 一致したすべての範囲を返す
end searchAttributedStringWithAttributes

★Click Here to Open This Script 

Posted in RTF | Tagged 13.0savvy 14.0savvy 15.0savvy NSMutableAttributedString | Leave a comment

AS書類を書式で分解して再構成

Posted on 1月 12 by Takaaki Naganoya

AppleScriptの書類を読み込んでNSAttributedStringに変換し、書式情報にもとづいてNSDictionary in NSArrayに変換。この状態でデータ抽出などを行なっていたのですが、このデータをもとにNSAttributedStringに再構成するAppleScriptです。

本Scriptの通しの処理内容としては、読み込んだAppleScriptを書式情報をもとに分解して、再構成するという……大豆から豆腐を作って、豆腐を崩して豆を得る、みたいな内容です。

NSAttributedStringを再構成する部分の処理を書いていなかったので、必要に迫られて書いてみました。

AppleScript構文色分け設定情報をもとに処理するため、色分け設定で複数の構文要素で同じ色を指定している場合にはエラーを返します。単にNSAttributedStringを解釈して再構成する、といった処理であればAppleScript構文色分け設定へのアクセス自体は必要ないところですが、すでに不可分なレベルで組み込まれているため、現状ではそのままです。

いっそ、こうした処理をする前にplistをバックアップし、必要な情報を書き込んだplistを設定ファイルとして使用するといった処理を行った方がいいのかもしれません。これまでは、「そんな処理はとても行えない」と判断していましたが、よくよく考えればとくに苦労せずに実現できそうです。

AppleScript名:AS書類を書式で分解して再構成.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/01/12
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

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

property NSFont : a reference to current application’s NSFont
property NSColor : a reference to current application’s NSColor
property |NSURL| : a reference to current application’s |NSURL|
property NSString : a reference to current application’s NSString
property OSAScript : a reference to current application’s OSAScript
property NSDictionary : a reference to current application’s NSDictionary
property NSUnarchiver : a reference to current application’s NSUnarchiver
property NSMutableDictionary : a reference to current application’s NSMutableDictionary
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

property asCol : {}

set asCol to getAppleScriptSourceColors() of me –AppleScript構文色分け設定をplistから読み込む

set aFile to POSIX path of (choose file of type {"com.apple.applescript.script", "com.apple.applescript.script-bundle"})
set aURL to |NSURL|’s fileURLWithPath:(aFile)
set theScript to current application’s OSAScript’s alloc()’s initWithContentsOfURL:aURL |error|:(missing value)
set styledText to theScript’s richTextSource()

–Styled TextをDictionarry in Listに
set sRes to getAttributeRunsFromAttrStringRBO(styledText) of styleTextToDict

–Dictionarry in ListをStyled Textに再構成
set bRes to retAttributedStringFromAttrDict(sRes) of attrDictToAttrStr

script styleTextToDict
  use AppleScript
  
use framework "Foundation"
  
use framework "AppKit"
  
use scripting additions
  
property parent : AppleScript
  
  
–Styled Textを
  
on getAttributeRunsFromAttrStringRBO(theStyledText)
    script aSpd
      property styleList : {}
    end script
    
    
set (styleList of aSpd) to {} —for output
    
    
set thePureString to theStyledText’s |string|() –pure string from theStyledText
    
    
set theLength to theStyledText’s |length|()
    
set startIndex to 0
    
set aCount to 0
    
    
repeat until (startIndex = theLength)
      set {theAtts, theRange} to theStyledText’s attributesAtIndex:startIndex longestEffectiveRange:(reference) inRange:{startIndex, theLength – startIndex}
      
      
–String  
      
set aText to (thePureString’s substringWithRange:theRange) as string
      
set strLen to (length of aText)
      
      
–Color
      
set aColor to (theAtts’s valueForKeyPath:"NSColor")
      
if aColor is not equal to missing value then
        set aSpace to aColor’s colorSpace()
        
        
set aRed to (aColor’s redComponent()) * 255
        
set aGreen to (aColor’s greenComponent()) * 255
        
set aBlue to (aColor’s blueComponent()) * 255
        
        
set colList to {aRed as integer, aGreen as integer, aBlue as integer} –for comparison
        
set colStrForFind to (aRed as integer as string) & " " & (aGreen as integer as string) & " " & (aBlue as integer as string) –for filtering
      else
        set colList to {0, 0, 0}
        
set colStrForFind to "0 0 0"
      end if
      
      
–Font
      
set aFont to (theAtts’s valueForKeyPath:"NSFont")
      
if aFont is not equal to missing value then
        set aDFontName to aFont’s displayName()
        
set aDFontSize to aFont’s pointSize()
      end if
      
      
–Range
      
set the end of (styleList of aSpd) to {stringVal:aText, atrIndex:aCount, colorStr:colStrForFind, colorVal:colList, fontName:aDFontName as string, fontSize:aDFontSize}
      
set startIndex to current application’s NSMaxRange(theRange)
      
      
set aCount to aCount + 1
    end repeat
    
    
return (styleList of aSpd)
    
  end getAttributeRunsFromAttrStringRBO
  
  
–NSColorからRGBの値を取り出す
  
on retColListFromNSColor(aCol, aMAX as integer)
    using terms from scripting additions
      set aRed to round ((aCol’s redComponent()) * aMAX) rounding as taught in school
      
set aGreen to round ((aCol’s greenComponent()) * aMAX) rounding as taught in school
      
set aBlue to round ((aCol’s blueComponent()) * aMAX) rounding as taught in school
    end using terms from
    
if aRed > aMAX then set aRed to aMAX
    
if aGreen > aMAX then set aGreen to aMAX
    
if aBlue > aMAX then set aBlue to aMAX
    
    
return {aRed, aGreen, aBlue}
  end retColListFromNSColor
  
  
–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
  
end script

script attrDictToAttrStr
  use AppleScript
  
use framework "Foundation"
  
use framework "AppKit"
  
use scripting additions
  
property parent : AppleScript
  
  
–書式つきテキストを組み立てる(メイン側)
  
on retAttributedStringFromAttrDict(attrRes)
    script aSpd
      property styleList : {}
    end script
    
    
set (styleList of aSpd) to {} —for output
    
    
set allAttrStr to NSMutableAttributedString’s alloc()’s init()
    
    
repeat with i in attrRes
      set j to contents of i
      
set tmpAttrStr to makeRTFfromParameters(stringVal of j, fontName of j, fontSize of j, colorVal of j) of me
      
      (
allAttrStr’s appendAttributedString:tmpAttrStr)
    end repeat
    
    
return allAttrStr
  end retAttributedStringFromAttrDict
  
  
–書式つきテキストを組み立てる(パーツ組み立て用サブ側)
  
on makeRTFfromParameters(aStr as string, fontName as string, aFontSize as real, aColorList as list)
    –Font & Size
    
set aVal1 to NSFont’s fontWithName:fontName |size|:aFontSize
    
set aKey1 to (NSFontAttributeName)
    
    
–Color
    
copy aColorList to {rCol, gCol, bCOl}
    
set aVal2 to makeNSColorFromRGBAval(rCol, gCol, bCOl, 255, 255) of asCol
    
set aKey2 to (NSForegroundColorAttributeName)
    
    
set keyList to {aKey1, aKey2}
    
set valList to {aVal1, aVal2}
    
set attrsDictionary to NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList
    
    
–Text
    
set attrStr to NSMutableAttributedString’s alloc()’s initWithString:aStr attributes:attrsDictionary
    
return attrStr
  end makeRTFfromParameters
  
  
  
–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
  
end script

–AppleScriptの構文色分けのカラー値をRGBで取得する
on getAppleScriptSourceColors()
  — get the plist info as a dictionary
  
set thePath to NSString’s stringWithString:"~/Library/Preferences/com.apple.applescript.plist"
  
set thePath to thePath’s stringByExpandingTildeInPath()
  
set theInfo to NSDictionary’s dictionaryWithContentsOfFile:thePath
  
  
— extract relevant part and loop through
  
set theArray to (theInfo’s valueForKey:"AppleScriptSourceAttributes") as list
  
  
set colList to {}
  
  
repeat with i from 1 to count of theArray
    set anEntry to item i of theArray
    
    
set colorData to NSColor of anEntry
    
set theColor to (NSUnarchiver’s unarchiveObjectWithData:colorData)
    
    
set {rVal, gVal, bVal} to retColListFromNSColor(theColor, 255) of me
    
    
set fontData to NSFont of anEntry
    
set theFont to (NSUnarchiver’s unarchiveObjectWithData:fontData)
    
    
set aFontName to theFont’s displayName() as text
    
set aFontSize to theFont’s pointSize()
    
    
set aColRec to {redValue:rVal, greenValue:gVal, blueValue:bVal, fontName:aFontName, fontSize:aFontSize}
    
    
set the end of colList to aColRec
  end repeat
  
  
return colList
end getAppleScriptSourceColors

–NSColorからRGBの値を取り出す
on retColListFromNSColor(aCol, aMAX as integer)
  using terms from scripting additions
    set aRed to round ((aCol’s redComponent()) * aMAX) rounding as taught in school
    
set aGreen to round ((aCol’s greenComponent()) * aMAX) rounding as taught in school
    
set aBlue to round ((aCol’s blueComponent()) * aMAX) rounding as taught in school
  end using terms from
  
  
if aRed > aMAX then set aRed to aMAX
  
if aGreen > aMAX then set aGreen to aMAX
  
if aBlue > aMAX then set aBlue to aMAX
  
  
return {aRed, aGreen, aBlue}
end retColListFromNSColor

★Click Here to Open This Script 

Posted in Color file Font OSA RTF | Tagged 13.0savvy 14.0savvy 15.0savvy NSAttributedString NSColor NSDictionary NSFont NSMutableAttributedString NSMutableDictionary NSString NSUnarchiver NSURL OSAScript | Leave a comment

OSAScriptViewのじっけん#2

Posted on 1月 9 by Takaaki Naganoya

OSAScriptViewの実験の続編です。#1ではSingle Windowのアプリを作って実験してみました(モノ自体は作ってあったので)。macOS 15.3 beta+Xcode 16.2でテストしました。

#2ではDocumentベースのアプリを作って、そこにOSAScriptViewを載せました。余計なテキストフィールドが載っているのは、いろいろ野望があるためです。

–> Download Fake Script Editor

#1と同様にコピペでAppleScriptを入力して、実際に動かして、結果を受け取れます。

ただし、この段階ですでに問題山積の状態です。Compile操作を行うと、ひさしぶりのビーチボール表示になって返ってきません。

Run Scriptはできるのに、Compile(Check Syntax)動作で落ちます。

この段階でかなり「どうすんの、これ?」という状態です。普通に部品を並べて普通につないで動かしたらクラッシュするというのは……

Posted in AppleScript Application on Xcode | Tagged 13.0savvy 14.0savvy 15.0savvy OSAScriptView | Leave a comment

OSAScriptViewのじっけん#1

Posted on 1月 9 by Takaaki Naganoya

OSASCriptViewを試してみましょう。自前でScript Editorをどの程度作れるのかという確認作業です。Xcode 16.2+macOS 15.3betaで確認を行なっています。

–> Download Xcode Project osascript_test

とはいえ、これは2017年にすでに調査してありました。OSASCriptControllerとOSAScriptViewをCocoa Bindingでつないで、さらにいくつかの必要なボタンをOSASCriptControllerにつないで、簡単なAppleScript記述+実行のテストプロジェクトを作成。

この実行環境は、AppleScriptライブラリを認識して呼び出せますし、OSの構文色分け設定を認識します。

ただし、Apple純正のスクリプトエディタ同様、Cocoa Objectのログ表示は行えません。

また、かなり致命的な問題なのですが、バンドル形式のAppleScriptはこの状態では編集・実行できません。

Appleが配布していたサンプルコードで、AppleScriptObjCが出たての頃にスクリプトエディタをASOCで組んだプロジェクトを見かけたのですが、それを探して編集するのが手っ取り早そうです。ただ、あれもバンドル形式のAppleScript書類を編集・実行できなかった記憶があります。

Posted in AppleScript Application on Xcode OSA | Tagged 13.0savvy 14.0savvy 15.0savvy OSAScriptController OSAScriptView | Leave a comment

指定フォルダ以下の画像のMD5チェックサムを求めて、重複しているものをピックアップしてダイアログでプレビュー_v4

Posted on 1月 2 by Takaaki Naganoya

指定フォルダ以下の画像(種別問わず)をすべてピックアップして、それぞれMD5チェックサムを計算し、重複しているものをピックアップしてデータとして出力するAppleScriptです。実行にはScript Debuggerを必要とします。今後は、ScriptableなライブラリをXcodeで1本作って、そこにAppleScriptから呼び出すのに便利なFrameworkを突っ込みまくるようにするのかも? 

–> Download Script Bundle within framework and library

前バージョンのScriptでは指定フォルダ直下の画像だけをピックアップするようになっていました、Spotlight検索でサブディレクトリ以下もすべて画像収集するように変更し、本Scriptだけで重複画像のブラウズができるようになっています。NSOutlineView+NSImageでブラウズするダイアログの部品はedama2さんから提供していただいています。

AppleScript名:指定フォルダ以下の画像のMD5チェックサムを求めて、重複しているものをピックアップしてダイアログでプレビュー_v4.scptd
— Created 2015-10-01 by Takaaki Naganoya
— Modified 2015-10-01 by Shane Stanley–With Cocoa-Style Filtering
— Modified 2018-12-01 by Takaaki Naganoya
— Modified 2024-12-19 by Takaaki Naganoya
— Modified 2025-01-01 by Takaaki Naganoya
— Modified 2025-01-02 by Takaaki Naganoya
use AppleScript
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "md5Lib" –https://github.com/JoeKun/FileMD5Hash
use outImageV : script "visLib" –NSOUtlineView+NSImageView Lib by edama2
use mdLib : script "Metadata Lib" version "2.0.0"

property |NSURL| : a reference to current application’s |NSURL|
property NSArray : a reference to current application’s NSArray
property NSPredicate : a reference to current application’s NSPredicate
property NSCountedSet : a reference to current application’s NSCountedSet
property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey
property NSString : a reference to current application’s NSString
property NSFileManager : a reference to current application’s NSFileManager
property NSMutableArray : a reference to current application’s NSMutableArray
property NSSortDescriptor : a reference to current application’s NSSortDescriptor

script spd
  property fList : {}
  
property fRes : {}
  
property md5List : {}
  
property fmdList : {}
  
property dupRes : {}
  
property outList : {}
end script

set aFol to POSIX path of (choose folder)
–set aFol to POSIX path of (path to pictures folder)

set (fRes of spd) to mdLib’s searchFolders:{aFol} searchString:("(kMDItemContentTypeTree CONTAINS %@)") searchArgs:{"public.image"}

–すべての画像のMD5チェックサムを計算
set (md5List of spd) to {}
set (fmdList of spd) to {}

repeat with i in (fRes of spd)
  set j to contents of i
  
set md5Res to (current application’s FileHash’s md5HashOfFileAtPath:(j)) as string
  
set the end of (md5List of spd) to md5Res
  
set the end of (fmdList of spd) to {filePath:j, md5:md5Res}
end repeat

–チェックサムが重複している画像を取り出す
set fmdArray to NSArray’s arrayWithArray:(fmdList of spd)

set (dupRes of spd) to returnDuplicatesOnly((md5List of spd)) of me
set (outList of spd) to {}
set procMDs to {}
set aRecord to {}

repeat with i in (dupRes of spd)
  set j to contents of i
  
  
if j is not in procMDs then
    set aRes to filterDictArrayByLabel(fmdArray, "md5 == ’" & j & "’") of me
    
    
set tmpMD5 to filePath of (first item of aRes)
    
    
set tmpRes to {}
    
repeat with ii in aRes
      set jj to contents of ii
      
set idSrcURL to (current application’s NSURL’s fileURLWithPath:(filePath of jj))
      
set the end of tmpRes to {|name|:idSrcURL’s lastPathComponent(), fileURL:idSrcURL, isLeaf:true}
    end repeat
    
    
set aRec to {|name|:j, fileRes:"", isLeaf:false, children:tmpRes}
    
set aRecord’s end to aRec
    
set the end of procMDs to j
    
set the end of (outList of spd) to aRec
  end if
end repeat

–OutlineView+ ImageViewでダイアログ表示
set mainMes to "重複画像一覧"
set subMes to "指定フォルダ以下の重複画像は以下のとおりです"
set aRes to outImageV’s alert:mainMes informativeText:subMes treeData:(outList of spd) isExpand:true

–リストに入れたレコードを、指定の属性ラベルの値で抽出
on filterDictArrayByLabel(aArray, aPredicate as string)
  –抽出
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat:aPredicate
  
set filteredArray to aArray’s filteredArrayUsingPredicate:aPredicate
  
return filteredArray
end filterDictArrayByLabel

–指定フォルダ以下のすべてのファイルを再帰で取得
on retFullpathsWithinAFolderWithRecursive(aFol)
  set anArray to NSMutableArray’s array()
  
set aPath to NSString’s stringWithString:aFol
  
set dirEnum to NSFileManager’s defaultManager()’s enumeratorAtPath:aPath
  
  
repeat
    set aName to (dirEnum’s nextObject())
    
if aName = missing value then exit repeat
    
set aFullPath to aPath’s stringByAppendingPathComponent:aName
    
anArray’s addObject:(aFullPath as string)
  end repeat
  
  
return anArray as list
end retFullpathsWithinAFolderWithRecursive

–Alias listから指定UTIに含まれるものをPOSIX pathのリストで返す
on filterAliasListByUTI(aList, targUTI)
  set newList to {}
  
repeat with i in aList
    set j to POSIX path of i
    
set tmpUTI to my retUTIfromPath(j)
    
set utiRes to my filterUTIList({tmpUTI}, targUTI)
    
if utiRes is not equal to {} then
      set the end of newList to j
    end if
  end repeat
  
return newList
end filterAliasListByUTI

–指定のPOSIX pathのファイルのUTIを求める
on retUTIfromPath(aPOSIXPath)
  set aURL to |NSURL|’s fileURLWithPath:aPOSIXPath
  
set {theResult, theValue} to aURL’s getResourceValue:(reference) forKey:NSURLTypeIdentifierKey |error|:(missing value)
  
  
if theResult = true then
    return theValue as string
  else
    return theResult
  end if
end retUTIfromPath

–UTIリストが指定UTIに含まれているかどうか演算を行う
on filterUTIList(aUTIList, aUTIstr)
  set anArray to NSArray’s arrayWithArray:aUTIList
  
set aPred to NSPredicate’s predicateWithFormat_("SELF UTI-CONFORMS-TO %@", aUTIstr)
  
set bRes to (anArray’s filteredArrayUsingPredicate:aPred) as list
  
return bRes
end filterUTIList

on returnDuplicatesOnly(aList as list)
  set aSet to NSCountedSet’s alloc()’s initWithArray:aList
  
set bList to (aSet’s allObjects()) as list
  
  
set dupList to {}
  
repeat with i in bList
    set aRes to (aSet’s countForObject:i)
    
if aRes > 1 then
      set the end of dupList to (contents of i)
    end if
  end repeat
  
  
return dupList
end returnDuplicatesOnly

★Click Here to Open This Script 

Posted in file Image | Tagged 13.0savvy 14.0savvy 15.0savvy | Leave a comment

執筆中:AppleScript最新リファレンスver2.8対応(macOS 15対応アップデート)

Posted on 1月 1 by Takaaki Naganoya

「AppleScript最新リファレンスver2.8対応」をお買い上げの読者の方々に対して、アップデート版として提供されます。

ほとんどできているのですが、「AppleScript最新リファレンスver2.8対応」添付のPiyomaru Script Assistantに合わせて内容の調整を行なっています。macOS 15の登場によって変更になった箇所の情報を中心に内容を補っています。前バージョンからは60ページほど内容を追記しています。

同ツールは初版に添付することをねらっていましたが、macOSのバグ(とくにText To Speech系)の状況確認や対応に時間がかかっていました。

English Version is here.

English version will be updated as original version. At first, English version is devided 3 part. But English version did not make good sales as I expected, so #2 and #3 project will be canceled.

Posted in Books | Tagged 12.0savvy 13.0savvy 14.0savvy 15.0savvy | 1 Comment

執筆中:Cocoa Scripting Course #10 NSAttributedString

Posted on 1月 1 by Takaaki Naganoya

目下、執筆中なのがCocoa Scripting Courseの10巻、NSAttributedStringです。FoundationとAppKitに分かれて機能が分布しており、なかなか言及すべき内容が多いものです。

WebKitにも機能が分布していますが、ざっと見たかぎりではWebKitのNSAttributedStringはAppleScriptから呼び出せないものがほとんどのようなので、ここは無視してよいでしょう。

NSAttributedStringとHTML、そしてMarkdownとの間の変換機能などが最近のmacOSのアップデートで追加されているため、こちらもすぐには完成しないことでしょう。

Posted in Books | Tagged 13.0savvy 14.0savvy 15.0savvy | Leave a comment

Post navigation

  • Older posts
  • Newer posts

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

Google Search

Popular posts

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

Tags

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

カテゴリー

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

アーカイブ

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

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

メタ情報

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

Forum Posts

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

メタ情報

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