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

Skimがv1.7.9にアップデート

Posted on 4月 15 by Takaaki Naganoya

オープンソースのPDFビューワー「Skim」がv1.7.9にアップデートしました。AppleScript用語辞書に変更が加わっていますが、説明文が追加された程度であり機能面での変更は見られません。

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

NaturalLanguage.frameworkを用いて日本語テキストの形態素解析を行う

Posted on 4月 10 by Takaaki Naganoya

NSLinguisticTaggerの後継であるNaturalLanguage(NLTokenizer)を用いて、日本語テキストの形態素解析を行なってみました。

この手の頭を使わないプログラミングだとChatGPTに丸投げすれば、(デバッグ作業が必要な)AppleScriptのコードが出てくるので、走らせて直して……で、15分ほどでしょうか。

NLTokenizerの処理結果は、間違ってはいないものの、相変わらず固有名詞を無視しまくるので、実用レベルにあるとはいえません。自分でAppleScriptで書いた簡易日本語パーサー「easyJParse」と処理結果が変わらないので、頑張ってNLTokenizerを使う意義はほとんどないといえます(日本語を処理すると品詞情報を返して来ないので余計に……)。

AppleScript名:NaturalLanguage.frameworkを用いて日本語テキストの形態素解析を行う.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/04/10
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

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

set inputText to current application’s NSMutableString’s stringWithString:"私の名前は長野谷です。"

— NLTokenizerのインスタンスを作成し、単語単位で設定
set tokenizer to current application’s NLTokenizer’s alloc()’s initWithUnit:(current application’s NLTokenUnitWord)
tokenizer’s setString:inputText
tokenizer’s setLanguage:(current application’s NLLanguageJapanese)

— 解析範囲の取得
set textLength to (inputText’s |length|()) as integer
set theRange to current application’s NSMakeRange(0, textLength)

— トークンを格納するリスト
set tokenList to {}

— トークン範囲を1つずつ取得して、文字列を抽出
set currentIndex to tokenizer’s tokenRangeAtIndex:0

repeat while (currentIndex’s location < (textLength))
  set subStr to (inputText’s substringWithRange:currentIndex)
  
copy (subStr as string) to end of tokenList
  
  
— 次のトークン範囲へ進む
  
set nextIndex to (currentIndex’s location) + (currentIndex’s |length|())
  
if nextIndex ≥ textLength then exit repeat
  
set currentIndex to tokenizer’s tokenRangeAtIndex:nextIndex
end repeat

return tokenList
–> {"私", "の", "名前", "は", "長野", "谷", "です"}

★Click Here to Open This Script 

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

XIBから作るステータスメニューUI

Posted on 4月 8 by Takaaki Naganoya

AppleScriptで作るステータスメニューは、プログラムで動的に作るケースが圧倒的に多いところですが、Xcode上でCocoa Applicationを作成する場合にはXIBで(=XcodeのInterface Builder上で)作ったほうが簡単だし使い勝手がいいので、作成方法を確認しておきました。


▲ステータスメニュー


▲Interface Builder上でメニューをCocoa binding(Xcode 16.3)

–> Download Archive

AppleScript名:AppDelegate.applescript
—
— AppDelegate.applescript
— statusMenuFromXIB
—
— Created by Takaaki Naganoya2 on 2025/03/27.
—
—

script AppDelegate
  property parent : class "NSObject"
  
  
— IBOutlets
  
property theWindow : missing value
  
property theStatMenu : missing value –xib上で作っておいたメニュー。Cocoa Binding
  
  
on applicationWillFinishLaunching:aNotification
    set theIcon to current application’s NSImage’s imageNamed:(current application’s NSImageNameComputer)
    
set statusItem to (current application’s NSStatusBar’s systemStatusBar())’s statusItemWithLength:(current application’s NSVariableStatusItemLength)
    
statusItem’s setTitle:("PIYOMARU")
    
statusItem’s setImage:theIcon
    
statusItem’s setHighlightMode:true
    
statusItem’s setMenu:theStatMenu
    
    
statusItem’s popUpStatusItemMenu:theStatMenu
  end applicationWillFinishLaunching:
  
  
on applicationShouldTerminate:sender
    — Insert code here to do any housekeeping before your application quits
    
return current application’s NSTerminateNow
  end applicationShouldTerminate:
  
end script

★Click Here to Open This Script 

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

iWork Appsがバージョン14.4にアップデート

Posted on 4月 6 by Takaaki Naganoya

iWork Apps(Keynote、Pages、Numbers)がバージョン14.4にアップデートしました。各アプリのAppleScript用語辞書に変更はありません。

Pagesで継続して発生している、現在画面上で表示中のページ+2見開きのページ上のオブジェクト情報の取得/操作が行えない現象については、修正されていません。

Apple側はこれをバグとも思っていないようですし、修正するつもりもないのでしょう。この不具合に対処するために、情報取得する対象のページを強制的に表示するよう指示する必要があることでしょう(そんな機能はないので、GUI Scriptingで?)。

Pages書類の各ページ上の表の座標を求めると、正しい値が返らない

Posted in news | Tagged 14.0savvy 15.0savvy Pages | Leave a comment

Dock Menu

Posted on 4月 5 by Takaaki Naganoya

Dock Menuを表示するAppleScriptアプリです。探すと意外と情報がまとまっていないので、掲載しておきます。

Dock Menuについては、スクリプトエディタやスクリプトメニュー、アプレットなどで動作する通常のAppleScriptでは利用できませんが、Xcode上で作成するアプリやCocoa AppleScript Applicationでは利用できます。このあたりは、どのぐらいAppleScriptの実行環境がアプリのイベントをAppleScript側に提供しているかどうかによります。

スクリプトエディタ上で作成するアプレットの一種、Cocoa-AppleScript Appletを用いると、Dock Menuを動的に作ることが可能です(後述)。

–> Download Xcode Project Archive

AppleScript名:AppDelegate.applescript
—
— AppDelegate.applescript
— dock menu
—
— Created by Takaaki Naganoya2 on 2025/04/05.
—
—

script AppDelegate
  property parent : class "NSObject"
  
  
— IBOutlets
  
property theWindow : missing value
  
property dockMenu : missing value
  
  
on applicationWillFinishLaunching:aNotification
    
  end applicationWillFinishLaunching:
  
  
on applicationShouldTerminate:sender
    return current application’s NSTerminateNow
  end applicationShouldTerminate:
  
  
  
–Dock Menu Enabled
  
on applicationDockMenu:(aNotification)
    return dockMenu
  end applicationDockMenu:
  
  
  
on clicked:aSender
    set aTag to (tag of aSender) as integer
    
display dialog (aTag as string)
  end clicked:
end script

★Click Here to Open This Script 

Cocoa-AppleScriptアプレット版はこちらです。macOS 12以降では、Finder上でRosettaを利用して実行するように指定する必要があります。

アプレット本体側のscriptではなく、ランタイム側の「CocoaAppletAppDelegate.scpt」を書き換える必要があります。これを読み返すと、つくづく「いきなりこの内容をScripterに使わせようとしたのは無理があった」と感じます。内容が、macOS 10.7当時のScripterのCocoaへの理解度を考えると難解すぎです。

–> Download Cocoa-AppleScript Applet

AppleScript名:CocoaAppletAppDelegate.scpt
—
— CocoaAppletAppDelegate.applescript
— Cocoa-AppleScript Applet
—
— Copyright 2011 {Your Company}. All rights reserved.
—

— This application delegate emulates the OSA script applet by loading "main.scpt" from the
— "Scripts" folder in the application resources and invoking the traditional run/open/reopen/quit
— handlers in response to Cocoa application delegate methods being called.
—
— This is provided in source form so that you may customize or replace it if your needs go
— beyond the basic applet handlers.
—
— Some of these methods must guard against re-entrancy, because invoking the main.scpt
— handler may end up invoking the event handler inherited from the current application,
— which calls the application delegate’s method again.

script CocoaAppletAppDelegate
  property parent : class "NSObject"
  
property mainScript : missing value — the applet’s main.scpt
  
property didOpenFiles : false — true = the application opened documents during startup
  
property isOpeningFiles : false — re-entrancy guard: true = in the process of opening files
  
property isReopening : false — re-entrancy guard: true = in the process of re-opening
  
property isQuitting : false — re-entrancy guard: true = in the process of quitting
  
  
on applicationWillFinishLaunching:aNotification
    — Insert code here to initialize your application before any files are opened
    
    
— Emulate an OSA Applet: Load the main script from the Scripts resource folder.
    
try
      set my mainScript to load script (path to resource "main.scpt" in directory "Scripts")
    on error errMsg number errNum
      — Perhaps this should silently fail if it can’t load the script; that way, a Cocoa applet
      
— can just have Cocoa classes and no main.scpt.
      
display alert "Could not load main.scpt" message errMsg & " (" & errNum & ")" as critical
    end try
  end applicationWillFinishLaunching:
  
  
on applicationDidFinishLaunching:aNotification
    — Insert code here to do startup actions after your application has initialized
    
    
if mainScript is missing value then return
    
    
— Emulate an OSA Applet: Invoke the "run" handler.
    
    
— If we have already opened files during startup, don’t invoke the run handler.
    
if didOpenFiles then return
    
    
try
      tell mainScript to run
    on error errMsg number errNum
      if errNum is not -128 then
        display alert "An error occurred while running" message errMsg & " (" & errNum & ")" as critical
      end if
    end try
    
    
— TODO: Read the applet’s "stay open" flag and quit if it’s false or unspecified.
    
— For now, all Cocoa Applets stay open and require the run handler to explicitly quit,
    
— which is arguably more correct for a Cocoa application, anyway.
    
(* if not shouldStayOpen then
      quit
    end if *)
  end applicationDidFinishLaunching:
  
  
on applicationShouldHandleReopen:sender hasVisibleWindows:flag
    — Insert code here to perform actions in response to a "reopen" event
    
    
if mainScript is missing value then return true
    
    
— Guard against re-entrancy.
    
if not isReopening then
      set isReopening to true
      
      
— Emulate an OSA Applet: Invoke the "reopen" handler. If there isn’t one, let the application object
      
— handle reopen (this is different from an OSA applet, which would do nothing if there is no handler;
      
— this way, the application will perform the usual "create untitled document" behavior by default).
      
try
        tell mainScript to reopen
        
set isReopening to false
        
        
return false
      on error errMsg number errNum
        if errNum is not -128 then
          display alert "An error occurred while reopening" message errMsg & " (" & errNum & ")" as critical
        end if
      end try
      
      
set isReopening to false
    end if
    
    
return true
  end applicationShouldHandleReopen:hasVisibleWindows:
  
  
on |application|:sender openFiles:filenames
    — Insert code here to perform actions in response to an "open documents" event
    
    
— Remember that we opened files, to avoid invoking the "run" handler later.
    
set didOpenFiles to true
    
    
— Guard against re-entrancy.
    
if not isOpeningFiles and mainScript is not missing value then
      set isOpeningFiles to true
      
      
try
        — Convert all the filenames from NSStrings to script strings
        
set theFilenameStrings to {}
        
repeat with eachFile in filenames
          set theFilenameStrings to theFilenameStrings & (eachFile as text)
        end repeat
        
        
tell mainScript to open theFilenameStrings
        
set isOpeningFiles to false
        
        
tell sender to replyToOpenOrPrint:(current application’s NSApplicationDelegateReplySuccess)
      on error errMsg number errNum
        if errNum = -128 then
          tell sender to replyToOpenOrPrint:(current application’s NSApplicationDelegateReplyCancel)
        else
          display alert "An error occurred while opening file(s)" message errMsg & " (" & errNum & ")" as critical
          
tell sender to replyToOpenOrPrint:(current application’s NSApplicationDelegateReplyFailure)
        end if
      end try
      
      
set isOpeningFiles to false
    else
      tell sender to replyToOpenOrPrint:(current application’s NSApplicationDelegateReplyFailure)
    end if
  end |application|:openFiles:
  
  
on applicationShouldTerminate:sender
    — Insert code here to do any housekeeping before your application quits
    
    
— Guard against re-entrancy.
    
if not isQuitting and mainScript is not missing value then
      set isQuitting to true
      
      
— Emulate an OSA Applet: Invoke the "quit" handler; if the handler returns, it has fully
      
— handled the quit message and we should not quit, otherwise, it calls "continue quit",
      
— which returns error -10000.
      
try
        tell mainScript to quit
        
set isQuitting to false
        
        
return current application’s NSTerminateCancel
      on error errMsg number errNum
        — -128 means there is no quit handler
        
— -10000 means the handler did "continue quit"
        
if errNum is not -128 and errNum is not -10000 then
          display alert "An error occurred while quitting" message errMsg & " (" & errNum & ")" as critical
        end if
      end try
      
      
set isQuitting to false
    end if
    
    
return current application’s NSTerminateNow
  end applicationShouldTerminate:
  
  
  
–Dock Menu Enabled
  
on applicationDockMenu:(aNotification)
    set aMenu to current application’s NSMenu’s alloc()’s init()
    
set aMenuItem to (current application’s NSMenuItem’s alloc()’s initWithTitle:"Dock Menuだよ" action:"actionHandler:" keyEquivalent:"")
    (
aMenuItem’s setTarget:me)
    (
aMenu’s addItem:aMenuItem)
    
return aMenu
  end applicationDockMenu:
  
  
on actionHandler:sender
    set aTag to (tag of sender) as string
    
set aTitle to (title of sender) as string
    
    
display dialog (aTitle as string)
  end actionHandler:
end script

★Click Here to Open This Script 

Posted in AppleScript Application on Xcode Cocoa-AppleScript Applet | Tagged 13.0savvy 14.0savvy 15.0savvy | Leave a comment

NSIndexSetを作成し、各index要素を取り出す

Posted on 3月 30 by Takaaki Naganoya

NSIndexSetを作成し、そこから各インデックス(数値)を取り出すAppleScriptです。

{3, 4, 5, 6, 7}

から構成されるNSIndexSetを作成して処理すると、

{3, 4, 5, 6, 7}

が返ってきます。

NSTableViewで複数行選択時の行インデックスを取得する際に、NSIndexSetで結果が返ってきたので、ChatGPTに書かせてみました。

本Script内でNSIndexSet内の各インデックス数値に対してオフセット加算ができるようにしているのは、このNSTableViewで1行目が0と返ってくる仕様のためで、AppleScriptと合わせるために+1のオフセット加算を行う必要があったためこのようになっています。

NSTableViewで複数行を選択すると、結果がNSIndexSetで返ってくる

初回から動くコードは返してこなかったものの、何回かやりとりしている間に、書き直せばなんとかなりそうだったので、引き継いで手で書いてみました。CocoaのAPI呼び出しはプログラミングではなくパズルみたいなものなので、ChatGPTに向いているといえば向いているのですが、AppleScriptObjCがBlocks構文を呼べないとかいった前提条件が認識されていないようなので、「手で描き直した方が速い」ということに。

NSNotFoundについては、Apple側も真面目に実装している風ではない(これを返すことが徹底されているわけではない、と)ので、あてにできないと感じています。

AppleScript名:NSIndexSetを作成し、各index要素を取り出す.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/03/30
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

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

— サンプルのNSIndexSetを作成(3, 4, 5, 6, 7 を含む)
set indexSet to current application’s NSIndexSet’s indexSetWithIndexesInRange:(current application’s NSMakeRange(3, 5))
set aList to getEachIndexFromIndexSet(indexSet, 0) of me
–> {3, 4, 5, 6, 7}

— インデックスを取得する処理
on getEachIndexFromIndexSet(indexSet, offsetNum)
  set indexList to {}
  
set currentIndex to indexSet’s firstIndex() — 最初のインデックスを取得
  
  
repeat while currentIndex ≠ (current application’s NSNotFound)
    — 取得したインデックスをAppleScriptのリストに追加
    
if currentIndex > 9.99999999E+8 then exit repeat
    
    
set end of indexList to ((currentIndex as number) + offsetNum)
    
    
— 次のインデックスを取得
    
set currentIndex to indexSet’s indexGreaterThanIndex:currentIndex
  end repeat
  
  
return indexList
end getEachIndexFromIndexSet

★Click Here to Open This Script 

AppleScript名:NSIndexSetを作成し、各index要素を取り出す(書き換え後).scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/03/30
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

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

— サンプルのNSIndexSetを作成(3, 4, 5, 6, 7 を含む)
set indexSet to current application’s NSIndexSet’s indexSetWithIndexesInRange:(current application’s NSMakeRange(3, 5))
set aList to getEachIndexFromIndexSet(indexSet, 0) of me
–> {3, 4, 5, 6, 7}

— インデックスを取得する処理
on getEachIndexFromIndexSet(indexSet, offsetNum)
  set indexList to {}
  
set currentIndex to indexSet’s firstIndex() — 最初のインデックスを取得
  
  
— 取得したインデックスをAppleScriptのリストに追加  
  
repeat while currentIndex ≤ 9.99999999E+8
    set end of indexList to ((currentIndex as number) + offsetNum)
    
    
— 次のインデックスを取得
    
set currentIndex to indexSet’s indexGreaterThanIndex:currentIndex
  end repeat
  
  
return indexList
end getEachIndexFromIndexSet

★Click Here to Open This Script 

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

Keynoteの現在のスライド上で選択中のテキストをもとに、後続の記事トビラページのタイトルに内容を設定 v2a

Posted on 3月 23 by Takaaki Naganoya

Keynote書類の現在表示中のスライド上で選択中のテキストアイテム(ボックス)の内容をもとに、後続の記事トビラページのタイトルを設定するAppleScriptです。Keynote 14.3+macOS 15.4betaで動作確認していますが、とくにバージョン依存した書き方などは行なっていません。

また、本来はiWork汎用オブジェクトの座標によるソート機能をライブラリとして独立させ、バンドル形式のScript書類に入れてあったのですが、Blog掲載のためにフラットなScriptに書き換えています。

本来、Keynoteのようにスライドのインデント(レベル変更)を行って階層構造を形成できるアプリでは、それぞれのスライド(ページ)のレベルを取得したり変更できることが望ましいのですが、Keynoteの機能セットの範囲内ではAppleScriptからそのような操作は行えません。そこで、各スライドのベースレイアウトに何を用いているかによって擬似的にレベルを判定しています。

KeynoteのAppleScript対応機能はiWork Apps中では屈指の対応度を誇っていますが、レイアウトした画像の内容データにアクセスできないのと、各スライドのレベルの取得/変更が行えない点がものすごく残念です。

電子書籍「Cocoa Scripting Course」の作成用に、以前にも作ったことがあるかもしれませんが、ふたたび作ってしまいました。ちょっと大きめの書き捨てScriptです。


▲Keynote書類の章トビラ上で章の記事内容を示すテキストボックスを選択した状態で本AppleScriptを実行。複数のボックスを選択してあっても、座標値でソートして順番を決定


▲各記事のトビラページに、章トビラから取得したテキストを設定。以下、繰り返し


▲章トビラ上のテキストをすべて記事トビラのタイトルに設定

AppleScript名:現在のスライド上で選択中のテキストをもとに、後続の記事トビラページのタイトルに内容を設定 v2a.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/03/23
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
–use iwoSortLib : script "iWorkObjSortLib"

tell application "Keynote"
  tell front document
    –章扉の上にあるテキストアイテム(各記事タイトルが入っているものと想定、複数可能)を取得
    
set aSelList to selection
    
set bSelList to {}
    
set sCount to count every slide
    
    
    
–画面上で選択しておいたオブジェクトのうち、text itemのみを抽出(念のため)
    
repeat with i in aSelList
      set j to contents of i
      
set aClass to class of j
      
if aClass is text item then
        set the end of bSelList to j
      end if
    end repeat
    
    
set cSelList to sortIWorkObjectsByPositionAndRetObjRef(bSelList, {"positionX", "positionY"}, {true, true}) of iWorkObjSort
    
    
    
–章トビラ上のテキストアイテム(複数可)をループしつつ、中のテキストを行ごとに分解してリスト化
    
–(連結前にあらかじめX座標をもとにソートしておいたほうがいい??)
    
set textList to {}
    
repeat with i in cSelList
      set tmpCon to object text of i
      
set tmpList to paragraphs of tmpCon
      
set textList to textList & tmpList
    end repeat
    
–return textList
    
    
–章トビラのページの情報を取得
    
tell current slide
      set curSlideNum to slide number
      
set curSlideLayout to name of base layout
    end tell
    
    
–章トビラの次のページの情報を取得(ここが必ず記事トビラであるという前提のもとに処理)
    
tell slide (curSlideNum + 1)
      set nextSlideLayout to name of base layout
    end tell
    
    
set targSlideList to {}
    
repeat with i from (curSlideNum + 1) to sCount
      tell slide i
        set tSTheme to name of base layout
        
if tSTheme = curSlideLayout then
          –章トビラを検出したら処理終了
          
exit repeat
        else if tSTheme = nextSlideLayout then
          –扉+1ページのスライド(記事カバー)を検出したら記録
          
set the end of targSlideList to i
        end if
      end tell
    end repeat
    
–return targSlideList
    
    
set iCount to 1
    
repeat with i in targSlideList
      try
        set tmpT to contents of item iCount of textList
        
tell slide i
          set object text of default title item of it to tmpT
        end tell
        
set iCount to iCount + 1
      on error
        return
      end try
    end repeat
  end tell
end tell

–ライブラリとしてバンドル形式のAppleScript書類に組み込んでいたものをBlog掲載用に展開した
script iWorkObjSort
  property parent : AppleScript
  
use AppleScript
  
use framework "Foundation"
  
use framework "AppKit"
  
use scripting additions
  
  
script spd
    property aaSel : {}
  end script
  
  
–Keynote上のiWork ObjをXY座標でソートして結果を返す(App Obj情報はitem noだけ)
  
on sortIWorkObjectsByPosition(aaSel, sortLabelLIst, sortDirectionList)
    tell application "Keynote"
      set aVer to version
      
if aVer < "12.0" then return
      
      
tell front document
        set posList to {}
        
set aCount to 1
        
        
repeat with ii in aaSel
          set jj to contents of ii
          
set bClass to class of jj
          
          
tell jj
            set {posX, posY} to position
            
            
try
              set tmpStr to object text as string
            on error
              set tmpStr to ""
            end try
          end tell
          
          
set the end of posList to {positionX:posX, positionY:posY, objID:aCount, myStr:tmpStr}
          
          
set aCount to aCount + 1
        end repeat
        
        
–座標データをもとにソート
        
set sortedList to sortRecListByLabel(posList, sortLabelLIst, sortDirectionList) of me
        
      end tell
    end tell
    
    
return sortedList
  end sortIWorkObjectsByPosition
  
  
  
–Keynote上のiWork ObjをXY座標でソートして結果を返す(App Objだけ返す)
  
on sortIWorkObjectsByPositionIncludingObjRef(aaSel, sortLabelLIst, sortDirectionList)
    tell application "Keynote"
      set aVer to version
      
if aVer < "12.0" then return
      
      
tell front document
        set posList to {}
        
set aCount to 1
        
        
repeat with ii in aaSel
          set jj to contents of ii
          
set bClass to class of jj
          
          
tell jj
            set {posX, posY} to position
            
            
try
              set tmpStr to object text as string
            on error
              set tmpStr to ""
            end try
          end tell
          
          
set the end of posList to {positionX:posX, positionY:posY, objID:aCount, myStr:tmpStr}
          
          
set aCount to aCount + 1
        end repeat
        
        
–座標データをもとにソート
        
set sortedList to sortRecListByLabel(posList, sortLabelLIst, sortDirectionList) of me
        
        
–データを返す配列にiWork Object への参照を含める
        
set sCount to 1
        
repeat with i from 1 to (length of aaSel)
          set tmpID to objID of contents of item i of sortedList
          
set tmpObj to contents of item tmpID of aaSel
          
set (item tmpID of sortedList) to (item tmpID of sortedList) & {objRef:tmpObj}
        end repeat
      end tell
    end tell
    
    
return sortedList
  end sortIWorkObjectsByPositionIncludingObjRef
  
  
  
–Keynote上のiWork ObjをXY座標でソートして結果を返す(App Obj入りのリストを返す)
  
on sortIWorkObjectsByPositionAndRetObjRef(aaSel, sortLabelLIst, sortDirectionList)
    tell application "Keynote"
      set aVer to version
      
if aVer < "12.0" then return
      
      
tell front document
        set posList to {}
        
set aCount to 1
        
        
repeat with ii in aaSel
          set jj to contents of ii
          
set bClass to class of jj
          
          
tell jj
            set {posX, posY} to position
            
            
try
              set tmpStr to object text as string
            on error
              set tmpStr to ""
            end try
          end tell
          
          
set the end of posList to {positionX:posX, positionY:posY, objID:aCount, myStr:tmpStr}
          
          
set aCount to aCount + 1
        end repeat
        
        
–座標データをもとにソート
        
set sortedList to sortRecListByLabel(posList, sortLabelLIst, sortDirectionList) of me
        
        
–データを返す配列にiWork Object への参照を含める
        
set sCount to 1
        
set retList to {}
        
repeat with i from 1 to (length of aaSel)
          set tmpID to objID of contents of item i of sortedList
          
set tmpObj to contents of item tmpID of aaSel
          
set the end of retList to tmpObj
        end repeat
      end tell
    end tell
    
    
return retList
  end sortIWorkObjectsByPositionAndRetObjRef
  
  
  
–リストに入れたレコードを、指定の属性ラベルの値でソート
  
on sortRecListByLabel(aRecList as list, aLabelStr as list, ascendF as list)
    set aArray to current application’s NSArray’s arrayWithArray:aRecList
    
    
set aCount to length of aLabelStr
    
set sortDescArray to current application’s NSMutableArray’s new()
    
repeat with i from 1 to aCount
      set aLabel to (item i of aLabelStr)
      
set aKey to (item i of ascendF)
      
set sortDesc to (current application’s NSSortDescriptor’s alloc()’s initWithKey:aLabel ascending:aKey)
      (
sortDescArray’s addObject:sortDesc)
    end repeat
    
    
return (aArray’s sortedArrayUsingDescriptors:sortDescArray) as list
  end sortRecListByLabel
  
end script

★Click Here to Open This Script 

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

Numbersで選択範囲のdateの年を+1する

Posted on 3月 10 by Takaaki Naganoya

Numbersの書類上で選択中のセル内の日付形式データがあったら、yearを+1(インクリメント)するAppleScriptです。macOS 15.4beta+Numbers 14.3で動作確認していますが、OSバージョンおよびNumbersのバージョンに依存する部分はありません。

実行前

実行後

ものすごくつまらなくて、ものすごく用途が狭いScriptですが、実際に書いてみたら意外と手間取る感じでした。

当然、+1するだけではなくー1する機能も作ってあり、呼び出し部分を差し替えればー1するようになります。macOS標準搭載のスクリプトメニューに入れて実行することを想定しています。

AppleScript名:選択範囲のdateの年を+1する.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/03/10
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

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

tell application "Numbers"
  tell front document
    tell active sheet
      try
        set theTable to first table whose class of selection range is range
        
set cellList to cell of selection range of theTable
        
set valList to value of cell of selection range of theTable
        
set aLen to length of cellList
      on error
        display notification "Numbers: There is no selection"
        
return
      end try
      
      
set bValList to {}
      
repeat with i in valList
        set j to contents of i
        
set aClass to class of j
        
        
if aClass = date then
          set j to incremenetYearOf(j) of me
        end if
        
        
set the end of bValList to j
      end repeat
      
      
      
repeat with i from 1 to aLen
        set aVal to contents of item i of bValList
        
set aCell to contents of item i of cellList
        
        
ignoring application responses
          set value of aCell to aVal
        end ignoring
      end repeat
      
    end tell
  end tell
end tell

on incremenetYearOf(aDate)
  set {bYear, bMonth, bDate} to {year of aDate, month of aDate, day of aDate}
  
set bYear to bYear + 1
  
set {year of aDate, month of aDate, day of aDate} to {bYear, bMonth, bDate}
  
return aDate
end incremenetYearOf

on decremenetYearOf(aDate)
  set {bYear, bMonth, bDate} to {year of aDate, month of aDate, day of aDate}
  
set bYear to bYear – 1
  
set {year of aDate, month of aDate, day of aDate} to {bYear, bMonth, bDate}
  
return aDate
end decremenetYearOf

★Click Here to Open This Script 

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

CotEditor v5.1.1でprint機能に微修正

Posted on 3月 5 by Takaaki Naganoya

CotEditorのメンテナーの@1024jp氏の談話によると、

https://x.com/1024jp/status/1896829943587508664

CotEditor v 5.1.0 → 5.1.1 でAppleScript経由のprint機能がうまく動作していなかったのを動作するように修正したとのこと。

ここのところ、macOS側の機能の不全により、AppleScript経由でのprint機能の実行がうまく動作していないケースが発生しており、それに対処したとのこと。

Posted in Object control | Tagged 14.0savvy 15.0savvy CotEditor | Leave a comment

CotEditor v5.1.0でdocumentのcontentsにeditable属性を追加

Posted on 3月 3 by Takaaki Naganoya

CotEditorがバージョン5.1.0にアップデートしました(翌日、5.1.1にアップデートしましたが、AS的には差はありません)。

アップデート内容は多岐に渡っていますが、AppleScript的には、documentのcontentsにeditable(boolean)属性が追加されました。

実際に、AppleScriptからこの属性値を操作して、想定どおりの挙動を行うかどうかをチェックしてみました。こうしたテストは開発者側でも行なっているかどうか怪しいところなので(とくにAppleのノーチェックぶりが目に余る)、大事な作業です。

想定どおりの動作を行なっているので、確認OKです!

AppleScript名:v51.0 document editable test.scpt
tell application "CotEditor"
  tell front document
    set editable of it to true
    
set edF to editable
    
–> true
    
set contents of it to "ABC"
    
    
    
set editable of it to false
    
set edF to editable
    
–> false
    
set contents of it to "CDE"
  end tell
end tell

★Click Here to Open This Script 

Posted in Object control | Tagged 14.0savvy 15.0savvy CotEditor | Leave a comment

画像をAppleScriptでアスキーアート化

Posted on 2月 26 by Takaaki Naganoya

指定の画像をアスキーアート化して、ダイアログ表示するAppleScriptです。

–> Download Script archive with Library

面倒だったのでChatGPTに書かせてみましたが、Retina Display対応や細かい箇所のエラーを取りきれず、途中から自分で書き換えました。

画像のアスキーアート化Scriptは、できることはわかっていつつも、これほど役立たずに時間の無駄なプログラムも珍しいところ。こういうのはChatGPTに書かせるのがお似合いです。

それにしても、けっこうこまめにコメント入れるもんですね。正しい内容かどうかは定かではありませんが……>ChatGPT

AppleScript名:画像をAppleScriptでアスキーアート化.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/02/26
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4"
use framework "Foundation"
use framework "AppKit"
use scripting additions
use radioLib : script "displayTextView"

property retinaF : missing value

— ファイル選択ダイアログで画像を選ぶ
set imagePath to POSIX path of (choose file with prompt "画像を選択してください:")

— ASCIIアートを生成
set asciiText to convertImageToASCII(imagePath)
display text view asciiText main message "ASCII ART" sub message "Sub Message" with properties {font name:"Courier", size:12, width:620, height:620, color:{255, 255, 255}}

on convertImageToASCII(imagePath)
  set asciiChars to "@%#*+=-:. " — 濃い→薄い順の文字列
  
  
— Retina用のスケールファクターを取得
  
set retinaF to (current application’s NSScreen’s mainScreen()’s backingScaleFactor()) as real
  
  
— 画像を読み込む
  
set imageURL to current application’s NSURL’s fileURLWithPath:imagePath
  
set imageData to current application’s NSImage’s alloc()’s initWithContentsOfURL:imageURL
  
  
— 論理サイズ(points単位)を取得("size"は予約語なのでエスケープ)
  
set imageSize to imageData’s |size|()
  
set {w_pt, h_pt} to {imageSize’s |width|, imageSize’s |height|}
  
  
— リサイズ後の幅(文字数)を指定し、論理サイズに基づいてスケール計算
  
set newWidth to 80
  
set scaleFactor to newWidth / w_pt
  
set newHeight to round (h_pt * scaleFactor * 0.55) — 文字の縦横比調整
  
  
— ピクセル単位のサイズに変換(Retina対応)
  
set pixelWidth to newWidth * retinaF
  
set pixelHeight to newHeight * retinaF
  
set pixelSize to current application’s NSMakeSize(pixelWidth, pixelHeight)
  
  
— 新しいピクセルサイズでNSImageを作成し、元画像を描画
  
set resizedImage to current application’s NSImage’s alloc()’s initWithSize:pixelSize
  
resizedImage’s lockFocus()
  
current application’s NSGraphicsContext’s currentContext()’s setImageInterpolation:(current application’s NSImageInterpolationHigh)
  
imageData’s drawInRect:{{0, 0}, pixelSize} fromRect:{{0, 0}, imageSize} operation:(current application’s NSCompositingOperationCopy) fraction:1.0
  
resizedImage’s unlockFocus()
  
  
— リサイズ後の画像からNSBitmapImageRepを取得
  
set resizedRep to current application’s NSBitmapImageRep’s imageRepWithData:(resizedImage’s TIFFRepresentation())
  
  
— 各ピクセルをASCII文字に変換(Retina対応のため、retinaFごとにサンプリング)
  
set asciiArt to ""
  
set stepX to retinaF as integer
  
set stepY to retinaF as integer
  
  
repeat with y from 0 to (pixelHeight – 1) by stepY
    repeat with x from 0 to (pixelWidth – 1) by stepX
      set pixelColor to (resizedRep’s colorAtX:(x * retinaF) y:(y * retinaF))
      
      
set r to pixelColor’s redComponent()
      
set g to pixelColor’s greenComponent()
      
set b to pixelColor’s blueComponent()
      
set brightness to (r + g + b) / 3
      
      
set charIndex to round (brightness * ((count of asciiChars) – 1))
      
set asciiArt to asciiArt & (character (charIndex + 1) of asciiChars)
    end repeat
    
set asciiArt to asciiArt & linefeed
  end repeat
  
  
return asciiArt
end convertImageToASCII

★Click Here to Open This Script 

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

XcodeのWorkspace Documentをクローズ後、再オープン

Posted on 2月 21 by Takaaki Naganoya

XcodeでオープンしているWorkspace Document(.xcodeproj)のパスを取得してクローズし、再度オープンするAppleScriptです。macOS 15.3上のXcode 16.2で動作をテストしました。

Xcodeでオープン中の.applescriptファイルの構文確認を行うために、いろいろ試行錯誤してみたものの、Xcodeでオープン中にはファイルへの書き込み権限を取得できない雰囲気が濃厚。Xcodeのエディタで表示中のコンテンツ(.applescript)の本文に文字列を突っ込んでみても、Xcodeに蹴られます。

# AppleScriptからの制御が封じられているので、まっとうな手口が使えません

これに対策するために、Xcode Projectをいったんクローズして、構文確認を行うとよさそうだったので、試作品を作ってみたものです。

AppleScript名:XcodeのWorkspace Documentをクローズ後、再オープン.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/02/21
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

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

tell application "Xcode"
  set xcVer to version
  
  
tell workspace document 1
    set xWSprojPath to path
    
close
  end tell
end tell

–delay 1

tell application "Xcode"
  open ((POSIX file xWSprojPath) as alias)
end tell

★Click Here to Open This Script 

Posted in file File path Object control | Tagged 13.0savvy 14.0savvy 15.0savvy Xcode | Leave a comment

Xcodeでオープン中のAppleScriptのフルパスを返す

Posted on 2月 14 by Takaaki Naganoya

Xcodeでオープン中のXcode Projectで表示中のファイルのフルパスを返すAppleScriptです。Xcodeで表示中のAppleScript書類(テキストベースの.applescript)をコンパイルして、省略表記した部分をすべて展開して元ファイルに書き戻すAppleScriptを書こうとして作ったものです。

Xcode.appのAppleScript用語辞書は、実用性がないというべきなのか、編集中のファイルに対する補助機能を作ろうとしても編集中のファイルのファイル名が取得できないとか、selectionの取得もできないとか、いまひとつ「使えない」という印象です(仕事をしているフリでもしてるんだろうか?>担当者)。

XcodeのAppleScript用語辞書には、日常的な作業を便利にするために必要とされる基礎的な機能が何もないので、「これでどうしろと?」と、途方に暮れてしまう出来です。

ただ、強引にファイル名の情報を取得しつつ(Windowのnameから取得)、Xcode Projectのルートフォルダからファイル検索することで、どうにかファイルのフルパスを取得してみました。取得したファイル名のファイルがProject内に複数存在する可能性もあるため、そのような場合にはどのファイルかを選択するように書いてみました(実にナンセンスな処理です)。

本Scriptでは、AppleScriptのプロジェクトに対して利用することを前提にしているため「.applescript」ファイルを取得する仕様になっていますが、別に「.m」でも「.swift」でも抽出できるように変更するのは容易です。

AppleScript名:Xcodeでオープン中のAppleScriptのフルパスを返す.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/02/14
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

use AppleScript
use scripting additions
use framework "Foundation"

set targString to " " & string id 8212 & " " –コピペやURL Events経由で受け渡すと壊れる

tell application "Xcode"
  set xcVer to version
  
  
—オープン中のファイル名(余計な文字列つき)を取得
  
tell window 1
    set aStr to name
  end tell
  
  
–Xcode Project書類のパスを取得
  
tell document 1
    set aPrjPath to path of it
  end tell
end tell

set a1Str to parseFileNameFromXCodeWindowName(aStr, targString) of me
if a1Str does not end with ".applescript" then return

set pathString to current application’s NSString’s stringWithString:(aPrjPath)
set parentFol to (pathString’s stringByDeletingLastPathComponent()) as string

set aList to retFullPathUnderAFolderWithRecursiveFilterByFileName(parentFol, a1Str) of me
if length of aList > 1 then
  set aRes to first item of (choose from list aList)
else
  set aRes to first item of aList
end if

return aRes
–> "/Users/me/Documents/testXC162/testXC162/AppDelegate.applescript"

on parseFileNameFromXCodeWindowName(aStr, aDelim)
  set aCount to retFrequency(aStr, aDelim) of me
  
set aRes to parseByDelim(aStr, aDelim) of me
  
return item 2 of aRes
end parseFileNameFromXCodeWindowName

–指定文字列内の指定キーワードの出現回数を取得する
on retFrequency(origText, aKeyText)
  set aRes to parseByDelim(origText, aKeyText) of me
  
return ((count every item of aRes) – 1)
end retFrequency

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

on retFullPathUnderAFolderWithRecursiveFilterByFileName(aFol, aFileName)
  set anArray to current application’s NSMutableArray’s array()
  
set aPath to current application’s NSString’s stringWithString:aFol
  
set dirEnum to current application’s 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
  end repeat
  
  
set thePred to current application’s NSPredicate’s predicateWithFormat_("lastPathComponent == %@", aFileName)
  
set bArray to anArray’s filteredArrayUsingPredicate:thePred
  
  
return bArray as list
end retFullPathUnderAFolderWithRecursiveFilterByFileName

★Click Here to Open This Script 

Posted in file File path Text | Tagged 13.0savvy 14.0savvy 15.0savvy Xcode | Leave a comment

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

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

Post navigation

  • Older posts

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

Google Search

Popular posts

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

Tags

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

カテゴリー

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

アーカイブ

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

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

メタ情報

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

Forum Posts

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

メタ情報

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