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

Apple Creator Studioに含まれるKeynote/Pages/Numbersは新バージョン?

Posted on 1月 14 by Takaaki Naganoya

Final Cut Pro、Pixelmator Pro、Logic Pro、Motion、Compressor、MainStage、Keynote、Pages、Numbers、フリーボードをサブスク(月額1,780円 年17,800円)で利用できる「Apple Creator Studio」が発表されました。映像・音楽系の作業を中心に行なっているユーザーには、よくできたスイーツです。

Adobe Creative Cloudと比べて、映像系はまあまあ、音楽系は優勢、画像系はちょっと落ちる(CMYKサポートがないので)、ページデザインについては冗談みたいな雰囲気です(Adobe InDesignとPagesを比較するなんて、恐れ多くて話題にもならない)。

既存のKeynote/Pages/Numbersについてもそのまま提供されるとのことですが、アイコンが明確に異なっているので現行の14.4のアップデート版である15.xが提供されるということでしょうか(現時点では何も明確な情報はありません。)。

Apple Creator Studioに含まれるKeynote/Pages/Numbersについては、「プレミアムコンテンツ」(テンプレートや素材?)、Apple Intelligenceを活用するAI機能(いつもの作文ツールとか。実体はほぼない)が追加利用できることが明記されています。

これまでにも、「特定のセル数の表が作れない」といったオリジナリティあふれるバグを山のように作られましたが、これからはもっと画期的なバグを作ってくれるのでしょうか? ワクワクと震えが止まりません。

Posted in news | Tagged 26.0savvy Apple Creator Studio Keynote Numbers Pages | Leave a comment

macOS 26.3beta2が登場。System Eventsのバグ直らず

Posted on 1月 13 by Takaaki Naganoya

macOS 26.3beta2が登場しました。さっそくインストールしましたが、System Eventsのバグは修正されていません。

26.3(1月末一般公開?)でこのバグが修正されるかどうかは、ちょっとわかりません。

AppleScript名:System Events経由でscreen saver infoを取得.scpt
tell application "System Events"
  set sPref to (screen saver preferences)
  
set aRunF to running of sPref
  
–> false
  
  
set sClockF to show clock of sPref
  
–> false (macOS 15.7.4)
  
–> error "System Eventsでエラーが起きました: AppleEventのハンドラで誤りが起きました。" number -10000 (macOS 26.3)
  
  
set mScreenF to main screen only of sPref
  
–> false (macOS 15.7.4)
  
–> error "System Eventsでエラーが起きました: AppleEventのハンドラで誤りが起きました。" number -10000 (macOS 26.3)
  
  
set aClass to class of sPref
  
–> screen saver preferences object(macOS 15.7.4)
  
–> screen saver preferences object(macOS 26.3)
  
  
set dIntvl to delay interval of sPref
  
–> 0 (macOS 15.7.4)
  
–> error "System Eventsでエラーが起きました: AppleEventのハンドラで誤りが起きました。" number -10000 (macOS 26.3)
  
end tell

★Click Here to Open This Script 

Posted in Bug news | Tagged 26.0savvy System Events | Leave a comment

関数計算ライブラリで一部のユーザーから再現しない問題が報告される件

Posted on 1月 9 by Takaaki Naganoya

関数演算ライブラリ「calcLibAS」は、自分がフリー配布しているAppleScript用の関数演算ライブラリです。JavaScriptCore経由で関数を呼び出すという、ひじょうにシンプルな原理で動作しています。

このcalcLibASを呼び出した一部のユーザーから「演算を行うとエラーになる」といった報告が行われており、不思議に思っておりました。

  「こんなにシンプルなのに、どうやったらエラーになるのか?」

いろいろ調べてみたら、発生源が見えてきたような気がします。

小数点にカンマを利用している言語(国)がある

通常、こうした広域にバラまくライブラリを作ったら、日本語環境と英語環境で動作検証します。macOSの開発時のデフォルトの言語は英語なので、英語環境で動作確認を行うのは普通です。

小数点を含む数値を表記するのに、小数点を「.」(ピリオド)で表記するのが日本語のルールですし、英語(米国)でもそうです。

ところが、いろいろ調べてみたら、小数点を「,」(カンマ)で表記する言語があるとかで……実際にプログラムを組んで、macOSがサポートしているlocaleごとに数値フォーマットを調べ、SVGベースの世界地図にプロットしてみました。

# この世界地図を塗り分けしてダイアログ表示する処理はけっこう汎用性がありそうなので、ライブラリとして提供することを検討しています。ライブラリというよりは、display worldmap scriptingみたいな、不可視プロセスの補助アプリになりそうですが

→ 「display world map」の実行に、HTMLReader.frameworkを使わなくても大丈夫なように変更しました。同ライブラリの実行にScript Debugerはもう必要ありません。

国単位でみると、小数点=ピリオドで表記するところは少数派で(でも、人口ベースで見ると少なくなさそう)、とくにヨーロッパ圏で英国以外がみんな「,」を使用しているのは衝撃でした。

ヨーロッパ系の数値表記をしている国で、小数点以下を含む数値を文字列で渡してきたらどうなる?

他の関数演算ライブラリを見たときに、パラメータをas realではなくas {integer, real}でcastしている様子が目に止まりました。

これは処理としてはおかしいのですが、どうもこの小数点以下を含む数値が、しかも文字列で指定された場合には、こういう予防措置を講じておくと、誤った演算を行わないのかもしれません。

ただ、演算内容自体はおかしくなるはず(小数点以下を含んだ数値を、文字列で渡すと小数点以下が無視される?)です。

仕方がないので、関数演算ライブラリ側でパラメータとして数値でも文字列でも受け取るようにしておいて、数値文字列を受け取った場合には、ヨーロッパ系の数値表現(小数点をカンマで記述する)を、米英風の小数点をピリオドで記述する表現に変換する処理を通すのがいいんでしょう(ChatGPTに書かせたので、自分のプログラムとはテイストが違うものの、こんな●●な処理にテイストも●●もないでしょう)。

世界は、まだ広かった……。

AppleScript名:locNumFormatCalc_v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2026/01/08 (Modified: 2026/01/09)
—
–  Copyright © 2026 Piyomaru Software, All Rights Reserved
—

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

property NSLocale : a reference to current application’s NSLocale
property NSNumberFormatter : a reference to current application’s NSNumberFormatter
property NSMutableArray : a reference to current application’s NSMutableArray
property NSSortDescriptor : a reference to current application’s NSSortDescriptor

set nRes to getLocaleNumFormat() of me
–> {{|color|:"Red", cc:"001"}, {|color|:"Red", cc:"003"}, {|color|:"Blue", cc:"150"}, {|color|:"Blue", cc:"419"}, {|color|:"Red", cc:"AD"}, {|color|:"Blue", cc:"AE"}, {|color|:"Yellow", cc:"AF"}, {|color|:"Blue", cc:"AG"}, {|color|:"Blue", cc:"AI"}, {|color|:"Red", cc:"AL"}, {|color|:"Red", cc:"AM"}, {|color|:"Red", cc:"AO"}, {|color|:"Red", cc:"AR"}, {|color|:"Blue", cc:"AS"}, {|color|:"Red", cc:"AT"}, {|color|:"Blue", cc:"AU"}…}

on getLocaleNumFormat()
  — 1. データの収集
  
set allId to NSLocale’s availableLocaleIdentifiers()
  
set countryDataList to {} — 最終的な国別データ(レコードのリスト)
  
  
repeat with ident in allId
    set aLocale to (NSLocale’s alloc()’s initWithLocaleIdentifier:ident)
    
set countryCode to (aLocale’s objectForKey:(current application’s NSLocaleCountryCode)) as string
    
    
if countryCode is not "missing value" and countryCode is not "" then
      set formatter to NSNumberFormatter’s alloc()’s init()
      (
formatter’s setLocale:aLocale)
      
set decimalSeparator to formatter’s decimalSeparator() as string
      
      
— 色の判定
      
set col to "Yellow"
      
if decimalSeparator is "." then
        set col to "Blue"
      else if decimalSeparator is "," then
        set col to "Red"
      end if
      
      
— 既存データの上書きロジック
      
set foundIndex to -1
      
repeat with i from 1 to count of countryDataList
        if cc of item i of countryDataList is countryCode then
          set foundIndex to i
          
exit repeat
        end if
      end repeat
      
      
if foundIndex is not -1 then
        — 既にデータがある場合、新しい色が「赤」なら上書きする
        
if col is "red" then
          set item foundIndex of countryDataList to {cc:countryCode, |color|:col}
          
— それ以外の場合は何もしない(最初に見つかった色を維持)
        end if
      else
        — 新しい国コードの場合はそのまま追加
        
set end of countryDataList to {cc:countryCode, |color|:col}
      end if
    end if
  end repeat
  
  
— 2. 国コード順にソート(Cocoaの機能を利用)
  
set nsList to NSMutableArray’s arrayWithArray:countryDataList
  
set sortDesc to NSSortDescriptor’s sortDescriptorWithKey:"cc" ascending:true
  
nsList’s sortUsingDescriptors:{sortDesc}
  
  
return nsList as list
end getLocaleNumFormat

★Click Here to Open This Script 

AppleScript名:ヨーロッパ数値文字列形式をISO形式に変換する.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2026/01/09
—
–  Copyright © 2026 Piyomaru Software, All Rights Reserved
—

set raw1 to "2,5"
set raw2 to "1.234,56"
set raw3 to "1234.5" — ISO形式でもOK

set n1 to normalizeNumberString(raw1) — "2.5"
set n2 to normalizeNumberString(raw2) — "1234.56"
set n3 to normalizeNumberString(raw3) — "1234.5"

log (n1 as number)
log (n2 as number)
log (n3 as number)

— 数値文字列を強制的に「.」小数点に直して返す
on normalizeNumberString(txt)
  — まず前後の空白・改行を削る(純AppleScript)
  
set t to trimText(txt)
  
  
— 「1.234,56」系: "." を千区切りとみなして除去
  
repeat while t contains "."
    set AppleScript’s text item delimiters to "."
    
set t to text items of t
    
set AppleScript’s text item delimiters to ""
    
set t to t as text
  end repeat
  
  
— 「,」を小数点として「.」に統一
  
set AppleScript’s text item delimiters to ","
  
set toks to text items of t
  
set AppleScript’s text item delimiters to "."
  
set t to toks as text
  
  
set AppleScript’s text item delimiters to ""
  
return t
end normalizeNumberString

— 前後空白を除去(AppleScript標準のみ)
on trimText(txt)
  set AppleScript’s text item delimiters to {space, return, linefeed, tab}
  
set theText to txt as text
  
— remove leading
  
repeat while theText starts with space or theText starts with tab or theText starts with return or theText starts with linefeed
    set theText to text 2 thru -1 of theText
  end repeat
  
— remove trailing
  
repeat while theText ends with space or theText ends with tab or theText ends with return or theText ends with linefeed
    set theText to text 1 thru -2 of theText
  end repeat
  
return theText
end trimText

★Click Here to Open This Script 

Posted in Library Number Text | Tagged 15.0savvy 26.0savvy | Leave a comment

Skim v1.7.12でshareコマンドを追加

Posted on 1月 8 by Takaaki Naganoya

オープンソースで開発を続けられているPDFビューワー「Skim」。AppleScriptへの対応度も高く、万人におすすめできるMac用アプリです。

そのSkimがバージョンアップして、AppleScriptのコマンド「share」が追加されました。


▲「ファイル」>「共有」コマンド以下のメニュー項目と等価なshareコマンド

すでに数年前から、AppleScriptからAirDropでファイル共有する処理を実際に書いて動かしていましたが、それをSkim側でも実装してきたようです。

shareコマンドのオプションは「The name of the service to use. 」とだけ書かれており、サービス名のenumが用意されていたりはしないようです。というわけで、ひととおり試してみたわけですが、英語で指定するのではなくローカライズされたサービス名を指定するようになっています。

AppleScript名:AirDropで共有.scpt
tell application "Skim"
  share front document using "AirDrop"
end tell

★Click Here to Open This Script 

AppleScript名:メールで共有.scpt
tell application "Skim"
  share front document using "メール"
end tell

★Click Here to Open This Script 

AppleScript名:メッセージで共有.scpt
tell application "Skim"
  share front document using "メッセージ"
end tell

★Click Here to Open This Script 

AppleScript名:メモで共有.scpt
tell application "Skim"
  share front document using "メモ"
end tell

★Click Here to Open This Script 

AppleScript名:フリーボードで共有.scpt
tell application "Skim"
  share front document using "フリーボード"
end tell

★Click Here to Open This Script 

AppleScript名:Simulatorで共有.scpt
tell application "Skim"
  share front document using "Simulator"
end tell

★Click Here to Open This Script 

Posted in Object control PDF | Tagged 15.0savvy 26.0savvy Skim | Leave a comment

Gender APIを使って名前から性別を判定

Posted on 1月 7 by Takaaki Naganoya

Gender API(https://www.genderapi.io/ja#)のREST APIを呼び出して、氏名から性別を判定するAppleScriptを書いてみました。

本APIは、POST methodで呼び出すものですが、NSURLConnection経由で呼び出すPOST呼び出しのScriptしか書いてありませんでした。NSURLConnectionは同期実行が行えるため、AppleScriptからは呼び出しやすいものですが、Deprecated宣言されてしまっているため、いつ本当になくなるかわかりません(いうても、あちこちで必要なのですぐになくならない気もする)。

# 本Scriptは、間違いなく2026年の意義あるScriptにリストアップされるものです

そこで、NSURLSessionを呼び出すPOST method呼び出しのAppleScriptを書いておいた次第です。ChatGPTに書かせました。

set aPostData to {|name|:”ぴよ まるお”, country:”JP”, askToAI:false, forceToGenderize:false}

のように、氏名を指定して呼び出すと、

{|name|:”ぴよ まるお”, |to|:false, remaining_credits:178, q:”ぴよ まるお”, expires:1.767849716E+9, isHumanName:true, total_names:1, used_credits:1, probability:80, duration:”828ms”, country:”JP”, status:true, gender:”male”}

のように結果が返ってきます。

Gender APIは無料コースが用意されており、1日に200回までの呼び出しの範囲で無料利用できます。本当は、「日本語の氏名から性別を判定できる機械学習モデル」(Classifier)があれば、それを呼び出すだけで済むのですが、ちょっと探したぐらいでは見当たりませんでした。

こういうのは、公共機関が整備して配布すべきもののような気もするのですが……

AppleScript名:POST method REST API v4.2(NSURLSession)_blog.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2026/01/07
—
–  Copyright © 2026 Piyomaru Software, All Rights Reserved
—

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

property |NSURL| : a reference to current application’s |NSURL|
property NSString : a reference to current application’s NSString
property NSURLCache : a reference to current application’s NSURLCache
property NSURLSession : a reference to current application’s NSURLSession
property NSMutableData : a reference to current application’s NSMutableData
property NSOperationQueue : a reference to current application’s NSOperationQueue
property NSMutableDictionary : a reference to current application’s NSMutableDictionary
property NSMutableURLRequest : a reference to current application’s NSMutableURLRequest
property NSJSONSerialization : a reference to current application’s NSJSONSerialization
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding
property NSURLSessionConfiguration : a reference to current application’s NSURLSessionConfiguration

property retData : missing value
property retCode : 0
property drecF : false
property aSession : missing value
property aCache : missing value

on run
  –https://www.genderapi.io/ja# にアクセスしてAPI Keyを取得してください
  
set apiKey to "Bearer " & "999zzz99z9999z99999z999z"
  
set reqURLStr to "https://api.genderapi.io/api"
  
set aPostData to {|name|:"長野谷 隆昌", country:"JP", askToAI:false, forceToGenderize:false}
  
  
set jsonDict to callRestPOSTJSON(reqURLStr, aPostData, 5, apiKey) of me
  
return jsonDict as record
  
–> {status:false, errno:93, errmsg:"query limit reached"}–API使用制限に到達した場合の返答
  
–> {status:false, errno:94, errmsg:"invalid or missing key"}–API Keyを指定しなかった場合の返答
  
–> {|name|:"長野谷 隆昌", |to|:false, remaining_credits:178, q:"長野谷 隆昌", expires:1.767849716E+9, isHumanName:true, total_names:1, used_credits:1, probability:80, duration:"828ms", country:"JP", status:true, gender:"male"}
end run

— POST JSON REST APIを呼び出す
on callRestPOSTJSON(reqURLStr as string, aRec as record, timeoutSec as integer, apiKey)
  set retData to NSMutableData’s alloc()’s init()
  
set retCode to 0
  
set drecF to false
  
  
–URL Cache(GETと同じ)
  
set cachePath to (POSIX path of (path to temporary items folder)) & "/Caches/AppleScriptURLCache"
  
set aCache to NSURLCache’s alloc()’s initWithMemoryCapacity:512000 diskCapacity:1024 * 1024 * 5 diskPath:cachePath
  
NSURLCache’s setSharedURLCache:aCache
  
  
–URL
  
set aURL to |NSURL|’s URLWithString:reqURLStr
  
  
–POST リクエスト作成
  
set aRequest to NSMutableURLRequest’s requestWithURL:aURL
  
aRequest’s setHTTPMethod:"POST"
  
aRequest’s setTimeoutInterval:timeoutSec
  
aRequest’s setValue:"application/json; charset=UTF-8" forHTTPHeaderField:"Content-Type"
  
aRequest’s setValue:apiKey forHTTPHeaderField:"Authorization"
  
aRequest’s setValue:"AppleScript/Cocoa" forHTTPHeaderField:"User-Agent"
  
  
–JSON化
  
set jsonData to NSJSONSerialization’s dataWithJSONObject:aRec options:0 |error|:(missing value)
  
aRequest’s setHTTPBody:jsonData
  
  
–Session
  
set aConfig to NSURLSessionConfiguration’s defaultSessionConfiguration()
  
aConfig’s setURLCache:aCache
  
  
set aSession to NSURLSession’s sessionWithConfiguration:aConfig delegate:(me) delegateQueue:(NSOperationQueue’s mainQueue())
  
set aTask to aSession’s dataTaskWithRequest:aRequest
  
aTask’s resume()
  
  
–delegate終了待ち
  
repeat (1000 * timeoutSec) times
    if drecF is true then exit repeat
    
delay "0.001" as real
  end repeat
  
  
–Session終了
  
aSession’s finishTasksAndInvalidate()
  
set aSession to missing value
  
  
–結果パース
  
return my parseSessionResults()
end callRestPOSTJSON

— delegate: body accumulation
on URLSession:tmpSession dataTask:tmpTask didReceiveData:tmpData
  retData’s appendData:tmpData
end URLSession:dataTask:didReceiveData:

— delegate: finished/failed
on URLSession:tmpSession task:tmpTask didCompleteWithError:tmpError
  if tmpError = missing value then
    set drecF to true
  else
    error "POST Failed:" & tmpError
  end if
end URLSession:task:didCompleteWithError:

–JSON parse
on parseSessionResults()
  set resStr to NSString’s alloc()’s initWithData:retData encoding:NSUTF8StringEncoding
  
set jsonString to NSString’s stringWithString:resStr
  
set jsonData2 to jsonString’s dataUsingEncoding:NSUTF8StringEncoding
  
set jsonDict to NSJSONSerialization’s JSONObjectWithData:jsonData2 options:0 |error|:(missing value)
  
return jsonDict
end parseSessionResults

★Click Here to Open This Script 

Posted in REST API | Tagged 15.0savvy 26.0savvy NSURLSession | Leave a comment

macOS 26.xのSystem Events/Screen Saver preferencesにバグ

Posted on 1月 4 by Takaaki Naganoya

macOS 26.xのSystem EventsのScreen Saver preferencesにバグがあることが報告されていました。

show clock
main screen only
delay interval

の3つのpropertyについて、AppleScript用語辞書に記載はあるものの、アクセスするとエラーになります。

macOS 15.7.xで実行するとまともに動作するため、macOS 26.xのエラーで間違いないでしょう。

AppleScript名:screen saver info.scpt
tell application "System Events"
  set sPref to (screen saver preferences)
  
set aRunF to running of sPref
  
–> false
  
  
–set sClockF to show clock of sPref
  
–> false (macOS 15.7.4)
  
–> error "System Eventsでエラーが起きました: AppleEventのハンドラで誤りが起きました。" number -10000 (macOS 26.3)
  
  
–set mScreenF to main screen only of sPref
  
–> false (macOS 15.7.4)
  
–> error "System Eventsでエラーが起きました: AppleEventのハンドラで誤りが起きました。" number -10000 (macOS 26.3)
  
  
–set aClass to class of sPref
  
–> screen saver preferences object(macOS 15.7.4)
  
–> screen saver preferences object(macOS 26.3)
  
  
set dIntvl to delay interval of sPref
  
–> 0 (macOS 15.7.4)
  
–> error "System Eventsでエラーが起きました: AppleEventのハンドラで誤りが起きました。" number -10000 (macOS 26.3)
  
end tell

★Click Here to Open This Script 

shell command経由でScreen Saver起動時間の取得、設定ができるので、Screen Saver系についてはこちらを使うとよいでしょう。

AppleScript名:screen saver起動時間取得_v2.scpt
set idle_time_seconds to (do shell script "defaults -currentHost read com.apple.screensaver idleTime") as integer

return idle_time_seconds
–> 300

★Click Here to Open This Script 

AppleScript名:screen saver起動時間変更_ v2.scpt

set idleTime to 60
do shell script "defaults -currentHost write com.apple.screensaver idleTime " & (idleTime as string)

★Click Here to Open This Script 

Posted in Bug Screen Saver System | Tagged 26.0savvy System Events | Leave a comment

ASCII ART QR Encoder

Posted on 12月 31, 2025 by Takaaki Naganoya

指定のデータをASCII ARTで表現されたQRコードのテキストに変換するAppleScriptです。もともと、QR Code画像の作成は普通にできているので、あえてASCII ARTで作成する必要はないのですが、思いつきで作って(作らせて)みました。

この手の「作ってみるほどの価値はないが、冗談半分で作ってみる」のに人間のパワーを割くのは得策ではありません。ChatGPTに作らせてみました(2回ほど動かないコードが出てきましたが)。

作ったあとで他の作例がないか確認してみたところ、Terminal上でQRコードを表示するのに利用している例が見当たりました。

このASCII ART QR CodeのダイアログをiPhone内蔵カメラで認識させてみたところ、問題なく認識できました。

AppleScript名:ASCII ART QR Encoderscptd.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/12/31
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

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

set testString to "http://piyocast.com/as/"
set asciiQR to makeAsciiQRCode(testString)

display dialog asciiQR buttons {"OK"} default button "OK"

— ASCII ART QR Encoder
on makeAsciiQRCode(theText)
  — 1. 文字列 → NSData
  
set textData to current application’s NSString’s stringWithString:theText
  
set dataObj to textData’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
  
— 2. QR生成
  
set qrFilter to current application’s CIFilter’s filterWithName:"CIQRCodeGenerator"
  
qrFilter’s setDefaults()
  
qrFilter’s setValue:dataObj forKey:"inputMessage"
  
qrFilter’s setValue:"M" forKey:"inputCorrectionLevel"
  
  
set ciImage to qrFilter’s outputImage()
  
  
— 3. CIImage → NSBitmapImageRep
  
set bitmapRep to current application’s NSBitmapImageRep’s alloc()’s initWithCIImage:ciImage
  
  
— サイズ取得
  
set pixelsWide to bitmapRep’s pixelsWide()
  
set pixelsHigh to bitmapRep’s pixelsHigh()
  
  
set resultText to ""
  
  
— 4. ピクセル走査
  
repeat with y from (pixelsHigh – 1) to 0 by -1
    set lineText to ""
    
repeat with x from 0 to (pixelsWide – 1)
      set pixelColor to (bitmapRep’s colorAtX:x y:y)
      
set grayColor to (pixelColor’s colorUsingColorSpaceName:(current application’s NSCalibratedWhiteColorSpace))
      
set brightness to grayColor’s whiteComponent()
      
      
if brightness < 0.5 then
        set lineText to lineText & "■"
      else
        set lineText to lineText & " " — 全角スペース
      end if
    end repeat
    
set resultText to resultText & lineText & linefeed
  end repeat
  
  
return resultText
end makeAsciiQRCode

★Click Here to Open This Script 

Posted in Image | Tagged 15.0savvy 26.0savvy | Leave a comment

最初期に書かれた書籍「AppleScript道入門」の序文をいま振り返る

Posted on 12月 30, 2025 by Takaaki Naganoya

自分が1994年当時に書店で手にとった書籍「AppleScript道入門」(原題:The Tao of AppleScript)Derrick Shneider著/大塚浩昭 監訳/小舘光正 訳 を本棚から引っ張り出してきました。

当時、AppleScriptがどういうものかを知りたかったので、書店で購入。オマケについてきたFDDには日本語AppleScript v1.1のインストーラが入っていました。日本語Diarectではほとんど使ったことはありませんけれども。

書籍のサンプルは付録FDDに入っていたので、それを展開して実行。Finderのウィンドウを画面の外周部に沿って1回回転させるScriptを実行したことを覚えています。しかも、たいへんに遅かったので(当時、IIsiに68030/50MHzのアクセラレータを搭載)「これでどうしろと?」という内容でした。

いま、本の内容を見直してみると「最初のリリースでけっこうな内容がそろっている」ことに逆に驚かされます。でも、Script対応アプリケーションは(当時は)少なかったですし、「Scriptを書いてグラフィックの作成とかできるのだろうか?」などと考えてみたものの、「やりたいこと」を実現するためのパーツが絶望的に少なかった感じでした。

序文の内容から当時の傾向とその後の発展を推測

序文(引用ここから)
「Macintoshのどこが気に入ってるか?」と聞かれたら、みなさんは何と答えるだろう。マウスか、アイコンか、それともメニューだろうか。これらはすべてMacintoshの「よいもの」なのだが、ときには「融通がきかないな」と思うこともある。

たとえば、フォルダを自動的に移動できたら、と思ったことはないだろうか。

もしくは、大きな容量のファイルをすべて見つけられたら、と。50章もある文書にスペルチェックをかけ、書式を整え、そしてPageMakerにかけなければならないケースはないだろうか。

たしかにこれらの仕事は、すべてマウスやメニューコマンドを使ってできる。

だが、必要な操作を考えると頭が痛くなる。必要なフォルダを1つのコマンドだけで移動できたらどんなに便利だろう。また、50章もの文書を自動的に処理してくれるようなプログラムがあったら。

そこでAppleScriptの登場となる。AppleScriptとは、このような決まりきった仕事を自動化するための言語だ。心をクリエイティブにしてAppleScriptに取り組めば、マウスも長持ちするかもしれない。

AppleScriptのコマンドは、「tell」、「make」、「create」、「quit」というように、とてもシンプルだ。AppleScriptを使えば、日常の作業を自動化できるし、時間も節約できる。つまり、コンピュータを本当の意味で「制御」できるのだ。

BMUGは、世界中のMacintoshユーザーの時間を節約することとトラブルを解決することを専門としているグループだ。だから、BMUGの有志たちがMacintoshのスクリプティングの本を書いても不思議はない。

このAppleScriptのガイドブックは、リンゴの芯とおしゃれなネズミたちであふれたバークレーの裏通りから生まれた。本書は、Macintoshの「よい部分」の代わりになるものではない。「よい部分」をさらによくするためのガイドだ。

Cliff Stoll
(引用ここまで)

当時、Macinsoth OS(Systemとか漢字Talkと言われていた)の比較対象はMS-DOS。DOSのバッチ処理に対してのMacの操作の「かったるさ」が(DOSユーザーから)問題視されていた時代。

ファイル処理は、たしかに当時はおおごとでした。でも、Mac OS X移行後では、シェルのコマンドを呼び出してもいいし、ファイル処理自体はそれほど問題ではないでしょう。ファイル処理はAppleScriptで実現できる用途のひとつではあるものの、ほんのごく一部です。

一定容量を超えるファイルであるとか、特定の条件を満たすファイルを抽出するのは、たしかに面倒ではあるものの、Spotlightで高速に検索できてしまいます。各種書類の、アプリごとの事情を抱える情報にもとづいて区分けや抽出を行うというのは、たしかにScriptでなければできません。

この序文には歴史的に興味深い内容がいくつもありますが、昔は本文テキストのスペルチェックがリアルタイムで行えなかったということが大きな驚きとともにあげられます。コンピュータの処理能力向上によって、人間が気合いを入れて実行する「コマンド」ではなく、勝手に行わせておくような「サービス」に変化したということです。

書式を整え……というあたりは、Adobe InDesignあたりではまだ有効な内容ですが、PagesやKeynoteでは文字書式を細かくいじくることはできても、GUI上で管理している書式にアクセスすることはできません。技術的には、後退した部分もあると見えます。

> AppleScriptのコマンドは、「tell」、「make」、「create」、「quit」というように、とてもシンプルだ。

このあたりは、「できること」「やりたいこと」が増えた結果、コマンドや用語は増えてきたわけで、Cocoa Scriptingを常用するにいたっては、ほぼ別の言語といっても過言ではない状態でしょう。

2000年代初頭から、Cocoa Dev-MLなどAppleのMailing ListをAppleScriptによる自動仕分けシステムによってこまかく用語ごとに仕分けて、データベースをメンテナンスしてきたことで、筆者の手元には膨大なQ&A情報がたまっています。

2014年に「AppleScriptからCocoaを自由に使えるようになりました」という出来事が起こったものの、10年以上前からCocoaの情報を調査するシステム(MLの超精密自動仕分けAppleScript)を開発し、日々それを動かして分析してきたからこそ、かなり早期からCocoa Scriptingに対応できたわけです(もちろん、Shane Stanleyから直接教えてもらえたことの意義は大きいです)。

そうはいっても、誰もが報われるかどうかがわからない努力をするのはどうかと思うので、AppleScript的な英単語による高度な機能の呼び出しモジュール「AppleScriptライブラリ」でよく使う機能をまとめて提供する試みを行なっています。

さらに、AppleScriptライブラリにSDEFをつけて「display youtube」みたいなわかりやすくて使いやすいコマンドを追加することができるようになってきています。

2025年現在、自分が希望するような高度なアプリケーション操作を実現するためには、より高度な知識が必要になる……という当たり前の結論になってきています。「最小限の努力で最大限の成果を」というロマンは存在しているものの「最大限の成果には、最大限の努力と知識が必要」という、宇宙不偏の常識をなぞることになっているのが2025年の現状でもあります。

また、プラットフォーム全体の健全性や問題の発生が頻繁に発生しており、そのために多大なる努力を強いられています。少なくとも、筆者個人が情報をまとめてメーカーに提示し、修正を要求することが欠かせません。

体感的には、ハードウェアの性能は過去最高の状態ですし、Intel CPUの時代よりもさらにパワーアップしました。AppleScriptから使える機能も、Cocoaの機能を直接利用できることで、格段に便利になっています。安定性も向上しているため、一昔前だと一晩かかっていたような作業が、数分で終わってしまいます。

本書で紹介されたウィンドウの回転みたいな処理も、複数のウィンドウを楕円移動させるような処理が簡単にできるようになりました。

あとは、OSに細かい不具合がRelase版に残ってしまうという残念な状況が解消されるとよいのですが。年明けにAppleのCEOが交代して、現状が改善されることを期待したいところです。

Posted in Books | Leave a comment

2025年に書いた価値あるAppleScript

Posted on 12月 29, 2025 by Takaaki Naganoya

2025年に使用していたmacOS:macOS 15+macOS 26

毎年行なっている、Piyomaru Softwareが書いたAppleScriptの1年を振り返る記事の2025年版です。

2008年から10年ほど運営を続けてきた旧「AppleScriptの穴」Blogが2018年の年初にホスティング会社との行き違いでシャットダウンされ、ゼロから再構築したのが現行の「AppleScriptの穴」Blogです。

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

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

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

本Blogは、もともとは、2000年代初頭に開発していた「人工知能インタフェース Newt On」のソースコード部品バラバラにして掲載し、用いた部品を個別にメンテナンスすることを「隠れた目的」としていました。また、Scripter間のノウハウの共有を推進することも目的としています。

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

https://note.com/140software/

前述のとおり、2018年1月にいちど本Blogは消えていました。その際に、「本Blogが存在しない場合にはどのような現象が起こるのか」を観察。その結果、AppleScriptについて知識を持たない人たちが好き勝手に「嘘」を流布しはじめる、という現象が観測されました。本Blogはそうした「嘘つき」を封じ込めるためのキーストーンとしての役割を果たしているといえます。

電子書籍の発行状況

本Blogを公開しているだけでは、ホスティング費用やドメイン費用がかかるだけで、何も収益が生まれません。そこで、本Blog+αの情報を整理してまとめた電子書籍を発行しています。本Blog読者のみなさまにおかれては、電子書籍を購入することで本Blog運営を支えていただけますと幸いです。

電子書籍の2025年末における刊行は、現時点で98冊。年間4冊となっています。

AppleScriptセキュリティ実践ガイド
AppleScript+Xcode GUIアプリソース集
AppleScript最新リファレンス v2.8対応 v2.0
スクリプトエディタScripting Book with AppleScript

目下、既刊本の最新環境へのアップデートを実行中です。

2025年に書いたAppleScriptの中で注目すべきもの

Blogよりも電子書籍用(掲載用、作業用)にかなりまとまったScriptを書いていたため、そちらの充実度が光ります。とはいえ、かなり技術的に重要なScriptをBlogにも多数書いています。ChatGPTを用いてScriptの作成を行なってみたところ、技術的な難易度が高い割につまらないとか、書くのが面倒くさいとか、すでに存在するものを作り直したくないといった「人間が書くのは気が乗らない」ものを中心に、Webブラウザとのやりとりだけで書けているので

2025年1月
NSObjectのクラス名を取得 v2.1

NSObjectのクラス名を取得 v2.1

Script Debuggerの開発が終了したことを受けて、Xcode上でAppleScriptObjCによるAppleScript開発環境の構築の可能性や、Xcode Projectの作業性の向上をねらって、とりあえずログに情報を出すためのまともな手段を用意しておこうと考えたものです。

こうした試みの成果により、Xode上でもともとのlogコマンドのように情報の確認が行えるようになってはいるものの、やはりlogコマンドが使えないと取りきれない(特定し切れない)バグなどもあるので、logコマンドの正常化には期待を寄せたいところです。

2025年2月
画像をAppleScriptでアスキーアート化

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

これは、Script内容自体は割とどうでもいいのですが、ChatGPTで高度なScriptを書かせる実験の一環です。やればできることはわかっていつつも、めんどうくさいので書きたくない種類のScriptをChatGPTに書かせてみました。

かなり使えるという手応えが得られたので、一歩進めてObjective-CのプログラムもChatGPTに書かせ、書籍のオマケ用に利用しています。

2025年3月
NSIndexSetを作成し、各index要素を取り出す

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

これも、ChatGPTに書かせたものです。必要に迫られて書く必要があったものに対して、ChatGPTを利用。Cocoa Scriptingのプログラムは、割とAPIの仕様を確認して、それに合わせるだけの内容のものが多いため、「プログラミングというよりも作業」だと感じていました。つまり、Cocoa ScriptingはChatGPTなどのLLMとの相性がいいと言えるかもしれません。

2025年4月
macOS 15.5で特定ファイル名パターンのfileをaliasにcastすると100%クラッシュするバグ

macOS 15.5で特定ファイル名パターンのfileをaliasにcastすると100%クラッシュするバグ

自分で書いたScriptという話ではなく、macOSのバグの話です。これをレポートするために、割といろいろ書いて試行錯誤しました。一応、macOS 15.5のRelease版で修正されたしたが、ちゃんと検証してからReleaseしてほしいところです。

Xcode上のAppleScriptObjCのプログラムから、Xcodeのログ欄へのメッセージ出力を実行

Xcode上のAppleScriptObjCのプログラムから、Xcodeのログ欄へのメッセージ出力を実行

Xcodeのログに出力するObjective-Cのプログラムを見つけたので、以前に作ったものと組み合わせてかなり便利に使えるようになりました。

2025年5月
macOS 26, Tahoe

macOS 26, Tahoe


Beta登場時に「Finderにempty trashコマンドを実行するとエラーになる」バグが発見されており、Release版で修正されていなかったことに驚かされました。

2025年6月
macOS 26, 15.5でShortcuts.app「AppleScriptを実行」アクションのバグが修正される

macOS 26, 15.5でShortcuts.app「AppleScriptを実行」アクションのバグが修正される

CotEditor用ブロック崩しゲーム

CotEditor用ブロック崩しゲーム

ChatGPTに書かせてみたものですが、CotEditorの最前面の書類ウィンドウの内容をAppleScriptで書き換えてゲームを実現してみました。

2025年7月
ASCII ARTで円を線で描く
ASCII ARTで円を塗る
ASCII ARTで直線を引く v3.1

テキストで作成した仮想画面に対して各種描画を行うものです。ChatGPTに書かせて手動で高速化を行なっています。

2025年8月
開始時刻から終了時刻までhh:mm形式の文字列を15分単位でリスト出力

開始時刻から終了時刻までhh:mm形式の文字列を15分単位でリスト出力

1か月分の(奥様の職場の)勤務パターンの視覚化、勤務形態を自動で処理できないかと考えて試作したものです。

2025年9月
暗黙のuseコマンド

暗黙のuseコマンド



個人的に忙しかったのですが、海外の掲示板で聞かれた内容についてまとめたものです。この記事を書く義理は400%なかったのですが、まとめておきました。掲示板にリンクURL を置いておき、あとは勝手に質問者が翻訳サービスなどを使って翻訳すればよいのでは? と、考えてそのまま放っておいたら、掲示板のアカウントが「日本語でコメントを書いた」などの理由で停止されていました。まったくおかしな理由でアカウント停止にされたので、その掲示板のことは忘れることにしました。なので、その掲示板にはログインできないし、メッセージを受け取ることもできません(何回書いても理解してもらえないようなので困っております。どうして被害者の自分が何回も無駄な説明をしなくてはならないのでしょう)。

macOS 15.xで自作AppleScriptライブラリの一部がScript Menuから使えなくなったので修正

macOS 15.xで自作AppleScriptライブラリの一部がScript Menuから使えなくなったので修正

割と困って、いろいろ書き換えてテストしていたのですが……どうやら、JXAをサポートするためにパラメータ(enum)をas stringでcastしていた部分が、スクリプトメニュー上で動かした場合にエラーになっていました。つまり、「AppleScriptライブラリでJXAをサポートしてはいけない」というのが現状のようです。

JXAはバージョン1.1でアップデートが停止しているため、動いても動かなくても知らないよという存在に見えます。

指定フォルダ内から指定拡張子のファイルを取得し、エイリアスだったらオリジナルのパスをPOSIX pathで取得

指定フォルダ内から指定拡張子のファイルを取得し、エイリアスだったらオリジナルのパスをPOSIX pathで取得

フォルダにScriptを入れて動作を行うプログラムにおいて、Scriptのエイリアスを入れておけば処理できるようにしたかったので書いたものです。

各種GUIアプリ書類のオープン速度を向上するためにUIアニメーションの一時停止を

各種GUIアプリ書類のオープン速度を向上するためにUIアニメーションの一時停止を

これは、久しぶりに大笑いしました。たったこれだけのささいな処理を追加するだけで、書類のオープン/クローズをともなう処理において、1書類あたり0.2秒、400書類で80秒も処理速度が向上。つまり、M1 MacでM4 Macと同等の速度を叩き出すことが可能になるわけで、実に爽快な話です(M4で実行すればM4なりに速くなります)。

スクリプトメニューでAirDropが使えない?

スクリプトメニューでAirDropが使えない?

macOS 15/26上のスクリプトメニューに対してAppleの魔の手が迫ってきました。セキュリティ上の制限がさらに厳しくなり、スクリプトメニュー内でAirDropを呼び出すAppleScriptの実行が妨害されるようになりました。

2025年10月
指定日が所属する週のうち、最終日の日付を求める v2

指定日が所属する週のうち、最終日の日付を求める v2

かなり込み入ったカレンダー計算系Scriptです。ただ、書いた甲斐はあったと思います。
カレンダー計算系のScriptは「Newt On Project」の遺産であり、自然言語とAppleScriptを組み合わせた処理を行ううえで、欠かせないものです。

FaceTimeカメラから取り込み v1

FaceTimeカメラから取り込み v1

Cocoaの機能を利用して、FaceTime Cameraから静止画を取り込むものです。いま、ちょうどXcode上で同様のテストを行なっているのですが、なかなか取り込めません。

タブでインデントしたテキストをOutLineViewで表示できるデータ形式に変換 v4(3階層対応)

タブでインデントしたテキストをOutLineViewで表示できるデータ形式に変換 v4(3階層対応)

NSOutlineViewをアラートダイアログ上に表示する「箱庭ダイアログ」系のScript Librariesを準備していますが、単にOutlineViewを表示できるだけでなく、タブでインデントしたテキストデータの構造を読み取ってOutlineViewを表示できるようにする必要性を感じて作成したものです。これも、めんどくさかったのでChatGPTに書かせて添削を行ないました。

階層を指定したlistからOutLineViewで表示できるデータ形式に変換 v4(3階層対応)

階層を指定したlistからOutLineViewで表示できるデータ形式に変換 v4(3階層対応)

1つのScriptを書けたからといって、運用上すべてのニーズを満たせるわけでもありません。複数のやりかたが存在するので、複数のデータ型でパラメータを受け取る準備はしておく必要があります。タブでインデントしたテキストが適しているパターンもあれば、リストで指定するのが適していることもあります。

macOS 15.7.2 スクリプトメニューから実行できなくなった地図系ライブラリ?

macOS 15.7.2 スクリプトメニューから実行できなくなった地図系ライブラリ?

NSAlertダイアログにさまざまなGUI部品を載せて利用する「箱庭ダイアログ」シリーズにおいて、地図を表示するものは実に使い勝手のよい部品です。ただし、スクリプトメニューから実行したときにMkMapViewを表示するScriptが実行できなくなっていました。とはいうものの、すべてが実行できなくなっているということではなく、一部に表示できるものもあり……まだ問題点の洗い出しが済んでいません。住所ジオコーダーまわりは実行できない環境が多いのですが、より機能が低いライブラリで実行できなかったりと、なかなか理解しにくいものがあります。

2025年11月

YouTubeムービー再生実験 v2c

YouTubeムービー再生実験 v2c

YouTube側の仕様が変わったことで、「display youtube」ライブラリを書き換える必要が出てきました。こうした箱庭UIライブラリを公開している人は(Shaneのライブラリは方向性が違いすぎるし)ほかにいないので、なかなか苦労させられます。幸いにしてedama2さんの助言を得られて最小限の修正(Local Web Serverを使用しない)で済みました。

Keynote書類上の選択中の2つのテキストアイテムで、左を比較元、右を比較先として行単位の差分を比較先に赤くマーク

Keynote書類上の選択中の2つのテキストアイテムで、左を比較元、右を比較先として行単位の差分を比較先に赤くマーク

diffとほぼ同じ動作をGUIアプリ上のオブジェクト内のテキスト同士に対して実行できています。Keynote版とPages版を用意しました。こういう道具の必要性を感じていたので、たいへん便利です。これまで、個人的に「車輪の再発明」をなるべく避けていましたが、自分で書くのでなければ再発明上等。ChatGPTは、他の処理系や言語で書かれた既存の処理をAppleScriptで再現するのが一番得意に感じます。

Posted in news | Tagged 15.0savvy 26.0savvy | Leave a comment

macOS 26.3 Beta(25D5087f)で、Finderのempty trash実行時のエラーが出なくなった

Posted on 12月 16, 2025 by Takaaki Naganoya

本日配布開始になったmacOS 26.3 Beta(25D5087f)において、これまで確認されていた「Finderのempty trashバグ」が出なくなったことを確認しました。

これは、AppleScriptからFinderのゴミ箱のクリア(empty trash)コマンドを実行すると、コマンドの実行後にエラーを返すというmacOS 26のリリース時から発生していたバグです。

ただし、macOS 26.3は1月後半のリリースが見込まれているため、それまでにバグが復活する可能性もあります。

Posted in Bug | Tagged 26.0savvy Finder | Leave a comment

CotEditor 6.2リリース AS用語辞書に変更なし

Posted on 12月 14, 2025 by Takaaki Naganoya

CotEditor 6.20がリリースされました。

前バージョンから14箇所ほど変更点が見られますが、すべて説明文の内容であり機能が追加されたり変更されていることはありません。

Posted in news Update | Tagged 26.0savvy CotEditor | Leave a comment

FSFindFolder failed with error=-43

Posted on 11月 29, 2025 by Takaaki Naganoya

# Because this information contains important content, linking to macscripter.net or reproduction is prohibited. This is because the macscripter.net administrator’s policy prohibits links to Japanese articles.

Xcode上で作成したAppleScript App Project(AppleScriptObjC)において、Projectに組み込んだ.scpt/.scptdを呼び出したときに、

のように、「FSFindFolder failed with error=-43」のエラーが出て実行できない問題に直面しました。

同エラーは特定のフォルダが見つからない、というCarbon由来のエラーのようですが、とくに呼び出しているScriptではファイルパスの処理は一切していません(カレンダー計算しているだけです)。

このエラーは電子書籍「AppleScript+Xcode GUIアプリソース集」の執筆時に、

本来はTable Viewに指定年の日本の祝祭日をすべて掲載するつもりだったのですが、その計算Scriptをバンドル内に組み込んで呼び出すとエラーに。

引数を単に返してくるだけの単純なハンドラ(testMeハンドラ)を呼び出す分にはエラーにならず、もちろんXcode Projectに組み込むAppleScriptはスクリプトエディタ/Script Debugger上で実行するとエラーになりません。

同書籍の執筆時には「とても解決するための時間が取れない」と考えて祝祭日の計算ライブラリを外して収録・掲載していました。ちょうど、Xcode 26+macOS 26に合わせた内容のアップデート作業を行なっていたところ、本来の計算機能を組み込んでみたところ、やはり動かないことからAppleにバグ(AppleScriptObjC.framework側?)として報告したものです。

組み込んだScriptを呼び出しても、シンプルなテストハンドラでは実行を妨げられないのですが、複雑な処理を行うと問題になります。

Posted in AppleScript Application on Xcode Bug | Tagged 15.0savvy 26.0savvy | Leave a comment

Keynote書類上の選択中の2つのテキストアイテムで、左を比較元、右を比較先として行単位の差分を比較先に赤くマーク

Posted on 11月 21, 2025 by Takaaki Naganoya

Keynote書類上で2つのテキストアイテムを選択し、左を比較元、右を比較先として行単位で差分を計算し、変更や追加が行われた行を赤く着色するAppleScriptです。

ほとんどの部分をChatGPTに書かせていますが、相当にやりとりしてダメ出ししないと書いてくれません。ほかにも、2D Bin Packing(任意の矩形図形xn個を指定エリアに詰め込む演算)のプログラムなどもAppleScriptで実装し直しておきたいところです。


▲Keynote書類上で2つのテキストアイテムを選択。座標値から左右を判定し、左側を比較元、右側を比較先として処理する


▲変更や新規追加のあった行を赤く着色する

こういうScriptを整備していないと、作業の負荷を下げられなくて大変です。

AppleScript名:Keynote書類上の選択中の2つのテキストアイテムで、左を比較元、右を比較先として行単位の差分を比較先に赤くマーク.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/11/21
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

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

— Keynote 側の処理:選択順で source / target を決め、target 側の差分行を赤くする
tell application "Keynote"
  tell front document
    set selItems to selection
    
if (count of selItems) is not 2 then
      display dialog "2つのテキストボックスを選択してください。(選択順が重要です)" buttons {"OK"} default button 1
      
return
    end if
    
    
set sourceTI to item 1 of selItems — 基準
    
set targetTI to item 2 of selItems — 変更を反映する対象
    
    
if (class of sourceTI) is not text item or (class of targetTI) is not text item then
      display dialog "選択されたオブジェクトがテキストボックスではありません。" buttons {"OK"} default button 1
      
return
    end if
    
    
–X座標値が小さい(左に存在する)ものを比較元とする
    
set {sPosX, sPosY} to position of sourceTI
    
set {tPosX, tPosY} to position of targetTI
    
if tPosX < sPosX then copy {sourceTI, targetTI} to {targetTI, sourceTI}
    
    
set sourceText to (object text of sourceTI) as string
    
set targetText to (object text of targetTI) as string
  end tell
end tell

set sourceLines to paragraphs of sourceText
set targetLines to paragraphs of targetText

— LCS を計算して target 側で「保持すべき行」のインデックスを決める
set pairs to computeLCS(sourceLines, targetLines)
set keepIdx to {}
repeat with p in pairs
  set end of keepIdx to item 2 of p — pair is {i, j} -> keep j (target index)
end repeat

— target の全テキストを一旦黒に戻す
tell application "Keynote"
  tell front document
    tell object text of targetTI
      set its color to {0, 0, 0}
    end tell
  end tell
end tell

— keepIdx に含まれない target の行を赤色にする
repeat with idx from 1 to (count targetLines)
  if keepIdx does not contain idx then
    set thisLine to item idx of targetLines
    
set startPos to offsetOfLine(idx, targetText)
    
set endPos to startPos + (length of thisLine)
    
if endPos ≥ startPos then
      tell application "Keynote"
        tell front document
          tell object text of targetTI
            set color of characters startPos thru endPos to {65535, 0, 0}
          end tell
        end tell
      end tell
    end if
  end if
end repeat

— LCS(最長共通部分列)を AppleScript のリストで実装(行単位)
— 戻り値: {{i1, j1}, {i2, j2}, …} という形式のペアリスト(1-based indices)
on computeLCS(listA, listB)
  set lenA to count listA
  
set lenB to count listB
  
  
— DP テーブル初期化: (lenA+1) 行 × (lenB+1) 列、全て 0
  
set dp to {}
  
repeat with r from 0 to lenA
    set row to {}
    
repeat with c from 0 to lenB
      set end of row to 0
    end repeat
    
set end of dp to row
  end repeat
  
  
— DP 計算(注意:dp の行は 0..lenA を 1..(lenA+1) 順で保持)
  
repeat with i from 1 to lenA
    
    
repeat with j from 1 to lenB
      set row_im1 to item i of dp — dp[i-1]
      
set row_i to item (i + 1) of dp — dp[i]
      
      
if (item i of listA) is equal to (item j of listB) then
        — dp[i][j] = dp[i-1][j-1] + 1
        
set prevVal to item j of row_im1 — dp[i-1][j-1]
        
set newVal to prevVal + 1
        
set item (j + 1) of row_i to newVal — store into dp[i][j]
        
        
— 更新した row_i を dp に戻す
        
set item (i + 1) of dp to row_i
      else
        
        
— dp[i][j] = max( dp[i-1][j], dp[i][j-1] )
        
set valUp to item (j + 1) of row_im1 — dp[i-1][j]
        
set valLeft to item j of row_i — dp[i][j-1]
        
        
if valUp ≥ valLeft then
          set item (j + 1) of row_i to valUp
        else
          set item (j + 1) of row_i to valLeft
        end if
        
set item (i + 1) of dp to row_i
        
      end if
    end repeat
  end repeat
  
  
— LCS を復元(後ろ向きに辿る)
  
set i to lenA
  
set j to lenB
  
set lcsPairs to {}
  
  
repeat while (i > 0 and j > 0)
    if (item i of listA) is equal to (item j of listB) then
      — 一致ペアを先頭に追加({{i, j}} & lcsPairs)
      
set lcsPairs to ({{i, j}} & lcsPairs)
      
set i to i – 1
      
set j to j – 1
    else
      — dp[i-1][j] と dp[i][j-1] を比較して移動方向を決める
      
set valUp to item (j + 1) of item i of dp — dp[i-1][j]
      
set valLeft to item j of item (i + 1) of dp — dp[i][j-1]
      
      
if valUp ≥ valLeft then
        set i to i – 1
      else
        set j to j – 1
      end if
      
    end if
  end repeat
  
  
return lcsPairs
end computeLCS

— 行の開始オフセット(文字単位、1-based)
on offsetOfLine(n, fullText)
  if n ≤ 1 then return 1
  
set paras to paragraphs of fullText
  
set pos to 1
  
repeat with idx from 1 to (n – 1)
    set pos to pos + (length of (item idx of paras)) + 1 — 改行分 +1
  end repeat
  
return pos
end offsetOfLine

★Click Here to Open This Script 

Posted in Object control Text | Tagged 15.0savvy 26.0savvy Keynote | Leave a comment

YouTubeムービー再生実験 v2c

Posted on 11月 14, 2025 by Takaaki Naganoya

メイン環境をmacOS 26にアップデートしたところ、display youtubeライブラリが動作しなくなっていたので、対処のために作った試作品の改良版です。

# 2a→2bで機能に関係ない範囲の微修正をしました
# 2b→2cでレスポンシブルモードで表示するようにHTML部分を変更しました

edama2さんからYouTubeムービー再生用の改良Scriptを送っていただいて、なんで動かなくなっていたのかの理由がわかりました。HTMLを文字列で与えるのは、問題ないものの……リファラーを「https://www.youtube.com」ではなく「https://www.google.com」にする必要があったのだとか(検索エンジンの検索結果から表示できるように、という話に見えます)。

結局、local web serverを起動する必要はなかったので起動せず、起動していないのでkillもせず、htmlの書き出しも行わないのでファイルの削除もせず、かなりシンプルな内容に戻りましたし、ダイアログ表示と同時にYouTubeムービーの再生を開始する機能も復活。

Thanks!>edama2氏

AppleScript名:YouTubeムービー再生実験 v2c.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/11/13
–  Modified by edama2 & Takaaki Naganoya on: 2025/11/13
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.8"
use framework "Cocoa"
use framework "WebKit"
use scripting additions

property |NSURL| : a reference to current application’s |NSURL|
property WKWebView : a reference to current application’s WKWebView
property NSURLRequest : a reference to current application’s NSURLRequest
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding
property WKWebViewConfiguration : a reference to current application’s WKWebViewConfiguration

property returnCode : 0

set mainMessage to "Youtube Test"
set subMessage to "Simple YouTube Player"
set viewSizeArray to {1280, 720}
set vId to "GP_tVXTYdmY"
set startSec to 32

set htmlString to "<body style=’background-color:red;overflow:hidden;margin:auto 0;padding:auto 0;’><div id=’ytplayer’></div>
<script>
var tag=document.createElement(’script’);
tag.src=’https://www.youtube.com/player_api’;
var firstScriptTag=document.getElementsByTagName(’script’)[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubePlayerAPIReady() {player = new YT.Player(’ytplayer’,{height:’100%’,width:’100%’,videoId:’"
& vId & "’,playerVars:{autoplay:1,mute:0,start:" & (startSec as string) & "}});}
</script>"

set paramObj to {myMessage:mainMessage, mySubMessage:subMessage, viewSize:viewSizeArray, myHTML:htmlString}
–my browseURLContents:paramObj–For Debug with Script Editor
my performSelectorOnMainThread:"browseURLContents:" withObject:(paramObj) waitUntilDone:true

— WKWebView表示用ハンドラ
on browseURLContents:paramObj
  set webSize to viewSize of paramObj
  
copy webSize to {aWidth, aHeight}
  
set htmlString to myHTML of paramObj
  
  
set idConf to current application’s WKWebViewConfiguration’s new()
  
set aWebView to current application’s WKWebView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight)) configuration:idConf
  
set baseURL to (current application’s NSURL’s URLWithString:"https://www.google.com/")
  
aWebView’s loadHTMLString:htmlString baseURL:baseURL
  
  
— アラートに埋め込む
  
set theAlert to current application’s NSAlert’s new()
  
tell theAlert
    –addButtonWithTitle_("Cancel")
    
its setMessageText:(myMessage of paramObj)
    
its setInformativeText:(mySubMessage of paramObj)
    
its addButtonWithTitle:"OK"
    
its setAccessoryView:aWebView
    
set myWindow to its |window|
    
tell myWindow
      its setLevel:(current application’s NSScreenSaverWindowLevel)
      
setInitialFirstResponder_(aWebView)
    end tell
  end tell
  
  
— モーダル表示
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
set returnCode to (theAlert’s runModal()) as number
  
  
— WKWebViewの後始末
  
aWebView’s loadHTMLString:"" baseURL:(missing value)
end browseURLContents:

★Click Here to Open This Script 

Posted in dialog Web Contents Control | Tagged 26.0savvy | 1 Comment

YouTubeムービー再生実験

Posted on 11月 13, 2025 by Takaaki Naganoya

macOS 26上でdisplay youtube AppleScriptライブラリの機能を利用したAppleScriptを、macOS標準搭載の「スクリプトメニュー」から呼び出すと、

のようにエラー表示されるようになっていました。

macOS 26.0βのときには再生されたりしていたのですが、リリース後のmacOS 26.2では再生されません。

これが、macOSの内部機能やポリシーの変更によるものなのか、あるいはmacOS 26のデフォルト設定の変化によるものかは不明です。YouTube側の仕様変更という疑いもありますが、定かではありません。

以前は文字列で組み立てたHTMLをWkWebViewに読み込ませていましたが、いまmacOS 26上ではそのやり方ではYouTubeのムービーは再生されません。

そこで、根本的な解決を図るため、local web server(httpd)を介してHTMLを表示する方式に変更。docrootをtemporary items folderに設定したhttpdを起動。temporary items folderに書き込んだhtmlをダイアログ上のWkWebViewに表示するようにしました。

このlocal web serverの起動にpython3を呼び出しており、インストールされていない環境(一般的な環境ではインストールされていない)ではDeveloper Toolsのインストールが実行初回時に行われます。一般ユーザーのことを考えるとPython3以外のツールを使って起動すべきなんでしょう。

以前のバージョンと異なるのは、ダイアログ上のWkWebViewに再生用のUI(中央にYouTUbeロゴ)が配置され、それをクリックしないとムービーの再生が始まらないことです。このあたりは、自動再生を開始できるように改変できそうではあるものの、同時にデメリット(音声の再生が行えないとか)が生じるおそれがあるため、現状のままがよさそうです。

それでも、macOS 26上でWkWebViewでYouTubeムービーを再生させられるようになりました。まだ、繰り返し実行して問題が出ないかといったテストを行なっている段階です。

htmlファイルの書き込みが間に合わないと上記のようなエラーが出ていましたが、処理の冒頭で明示的にhttpdをkillすることで、この問題を解消できるようになりました。httpdのkillについては、他のプログラムが起動していた場合には問題になりそうなので、そこも様子見といったところでしょう。

ちなみに、YouTubeムービー再生以外の用途では、とくにこのような大幅な改変は必要ではないと認識しています。たとえば、CDN上のJavaScriptライブラリを呼び出してアニメーション表示つきのグラフ表示をAppleScriptで行なっていますが、こちらでは書き換えは必要ありませんでした。

AppleScript名:youtubeムービー再生実験.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/11/12
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

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

property |NSURL| : a reference to current application’s |NSURL|
property WKWebView : a reference to current application’s WKWebView
property NSURLRequest : a reference to current application’s NSURLRequest
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding
property WKWebViewConfiguration : a reference to current application’s WKWebViewConfiguration

property returnCode : 0

set mainMessage to "Youtube Test"
set subMessage to "Using local Web Server"
set viewSizeArray to {1200, 640}

set youtubeMovieID to "GP_tVXTYdmY"

–テスト用HTML文字列
–set htmlString to "<!DOCTYPE html><html><body><h1>Hello World</h1></body></html>"

— HTML文字列
set htmlString to "
<!DOCTYPE html>
<html lang=\"ja\">
<head>
<meta charset=\"UTF-8\">
<title>YouTube Embed</title>
<style>
body { margin:0; padding:0; }
iframe { width:100%; height:100vh; border:none; }
</style>
</head>
<body>
<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/"
& youtubeMovieID & "?start=1\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>
</body>
</html>
"

try
  do shell script "pkill -f ’http.server’ || true"
end try

set docroot to POSIX path of (path to temporary items)

–1. Python3でバックグラウンドサーバー起動(Local Web Server)
set pythonCmd to "python3 -m http.server 8000 –directory " & quoted form of docroot & " >/dev/null 2>&1 & echo $!"
set pidStr to do shell script pythonCmd
set serverPID to pidStr as integer

— 2. HTMLを書き出す
set htmlPath to docroot & "index.html"
set nsHTML to current application’s NSString’s stringWithString:htmlString
nsHTML’s writeToFile:htmlPath atomically:true encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value)

— 3. 少し待ってサーバー起動を待機
delay 0.5

try
  — 4. WKWebViewでHTTP URLを読み込む
  
set httpURL to "http://localhost:8000/index.html"
  
set paramObj to {myMessage:mainMessage, mySubMessage:subMessage, viewSize:viewSizeArray, htmlStr:"", myURL:httpURL}
  
  
–my browseURLContents:paramObj
  
my performSelectorOnMainThread:"browseURLContents:" withObject:(paramObj) waitUntilDone:true
on error errMsg
  display dialog errMsg
end try

— 5. サーバープロセス終了
try
  do shell script "pkill -f ’http.server’ || true"
end try

— WKWebView表示用ハンドラ
on browseURLContents:paramObj
  set webSize to viewSize of paramObj
  
copy webSize to {aWidth, aHeight}
  
  
set aURL to myURL of paramObj
  
  
set aConf to WKWebViewConfiguration’s alloc()’s init()
  
set aWebView to WKWebView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight)) configuration:aConf
  
aWebView’s setNavigationDelegate:me
  
aWebView’s setUIDelegate:me
  
aWebView’s setTranslatesAutoresizingMaskIntoConstraints:true
  
  
set bURL to |NSURL|’s URLWithString:aURL
  
set bReq to NSURLRequest’s requestWithURL:bURL
  
aWebView’s loadRequest:bReq
  
  
— Move to frontmost
  
current application’s NSApplication’s sharedApplication()’s setActivationPolicy:(current application’s NSApplicationActivationPolicyRegular)
  
current application’s NSApp’s activateIgnoringOtherApps:true
  
  
— アラートに埋め込む
  
set theAlert to current application’s NSAlert’s alloc()’s init()
  
tell theAlert
    –addButtonWithTitle_("Cancel")
    
its setMessageText:(myMessage of paramObj)
    
its setInformativeText:(mySubMessage of paramObj)
    
its addButtonWithTitle:"OK"
    
its setAccessoryView:aWebView
    
set myWindow to its |window|
    
tell myWindow
      its setLevel:(current application’s NSScreenSaverWindowLevel)
      
setInitialFirstResponder_(aWebView)
    end tell
  end tell
  
  
— モーダル表示
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
set returnCode to (theAlert’s runModal()) as number
  
  
— WKWebViewの後始末
  
set jsStop to "try { document.getElementById(’ytplayer’).contentWindow.postMessage(’{\"event\":\"command\",\"func\":\"stopVideo\",\"args\":\"\"}’, ’*’); } catch(e) {}"
  
aWebView’s evaluateJavaScript:jsStop completionHandler:(missing value)
  
delay 0.1
  
aWebView’s loadRequest:(NSURLRequest’s requestWithURL:(|NSURL|’s URLWithString:"about:blank"))
  
delay 0.1
  
aWebView’s stopLoading()
  
set aWebView to missing value
  
  
set aWebView to missing value
end browseURLContents:

★Click Here to Open This Script 

Posted in dialog Web Contents Control | Tagged 26.0savvy | Leave a comment

「AppleScriptセキュリティ実践ガイド」を発売

Posted on 11月 6, 2025 by Takaaki Naganoya

電子書籍の新刊を発売しました。「AppleScriptセキュリティ実践ガイド」です。PDF 562ページ、サンプルAppleScriptのZipアーカイブを添付。

→ 販売ページ

macOS上の各種機能を自由に呼び出せて、GUIベースのアプリの機能や情報を呼び出せる強力なAppleScriptは、ソースコードが読めない実行専用形式で、Scriptやアプレットとして公開可能です。

しかし、「暗号化済み」のように見える「実行専用形式」で保存されていたとしても、実際にはApple Events Codeという命令列の形で格納されており、文字列に関してはターミナル上でhexdumpやstringsコマンドによるダンプ出力が可能です。

さらに、昨今ではApple Events Codeそのものをダンプ(=内部の命令構造を可視化)するツールが登場。防衛用のツールですが、攻撃側もこれを利用できる状態にあります。

本書では、Apple Events Codeのダンプツールによってどのような情報が「抜かれ」、それらが実際にどのように見えるのかを詳細に検証しています。

実行専用のScript/アプレットで書き出した内容をダンプ(Apple Events Codeのダンプ)するapplescript-disassemblerと、その出力内容を読みやすく整形するaevt-decompileを用いて、さらにそれらを統合して使いやすくした統合ダンプツールをAppleScriptで開発。

対象フォルダ中のAppleScript書類を実行専用形式で書き出し、ダンプツールで解析して結果をテキスト書き出し……という作業フローを一括で行います。これを、さまざまな構造の複雑さを備えたテスト用AppleScriptに対して、さまざまなデータ型のデータを記述してどの程度漏洩するのか、しないのかを確認しています。

また、すべてのAppleScript予約語を含むサンプルScriptを作成し、個別にどのようにApple Events Codeにダンプされるかを掲載しています。

その上で、想定されるリスクと防止策を提示し、AppleScriptを安全に活用するための基礎資料としてご活用ください。

目次

1章 「実行専用」は安全なのか?

AppleScriptの概要と機能のひろがり/実行プログラムのひろがり/システム設定による機能制限/ヘックスダンプや文字ダンプで得られる情報/Apple Events関連の参考資料/コラム 本書掲載のAppleScriptリストの構文色分け設定について

2章 AppleScriptアプレットの構造

スクリプトエディタでアプレットを作成/書き出したアプレットの内部構造を追う/クラシックOS時代のアプレットのscptリソースの内容と比較

3章 Apple Eventダンプによる情報抽出

アップルスクリプトの完全なデコンパイルは無理/あくまでApple Events Codeとして解釈して読みやすくする/applescript-disassembler/aevt_decompile/統合分析ツールas_disassem+decompile/strings/hexdump

4章 実行専用スクリプトから漏れる情報の実態

Apple Events Code上で各データ型がどう見えるか?/プログラムの複雑さを変更して結果を調べる/アルファベット+数字/日本語の文字列/絵文字の文字列/真偽値/整数値/実数値/dateオブジェクト/数値のリスト(配列)/文字列のリスト(配列)/レコード/アプリケーションのオブジェクト/Xcodeで開発したAppleScrIptObjCアプリ

5章 情報漏洩をふせぐ技術的手法

安直なダンプで見えない形式でユーザー名やパスワードを記述/キーチェーンに情報を保存して内容を取り出すにしてもアクセス用キーワードは必要/データ暗号化の基礎①シフト暗号/データ暗号化の基礎②暗号表による換字式暗号/データ暗号化の基礎③多表式暗号と鍵のしくみ(ヴィジュネル暗号)/データ暗号化の基礎④「鍵」をさらに安全・自動的に扱う仕組みをもつOpenSSLによる現代暗号/プログラム難読化①データ形式変更/プログラム難読化②変数名絵文字置換/プログラム難読化③構造高度化

6章 安全な配布のための設計指針

アップルスクリプトの配布形態とかけられる労力の違い/配布時に最低限でもコード署名が必要。そのために開発者登録も必須/習熟のために経験しておきたいアプレットのオンライン配布

7章 AppleScriptのセキュリティ再考

最近発生したAppleScriptがらみの諸問題はメモリリーク/ユーザー名やパスワード、APIキーをスクリプト内に平文で記録すると危険/かつては可能だったアプリとAppleScript間の通信傍受もいまや不可能に/ネットワーク経由の操作は、途中で傍受される危険性も/AppleScript実行ツールで、埋め込みテキストのスクリプトを設定ファイルに平文保存?

8章 Apple Events Codeダンプ分析資料

全予約語を含む記述例を実行専用状態でApple Events Codeダンプ

9章 ダンプ結果から見る情報露出傾向と対策

コマンド、記述方法、データ型から読み解く露出傾向/script objectによるダンプ対策が有効/「OSAMiner事件」から再考されたAppleScript環境におけるセキュリティ対策/コラム 本書作成のために作成・使用したAppleScript

Posted in Books news Security | Tagged 15.0savvy 26.0savvy | Leave a comment

macOS 26.1が登場。Finderのバグが直らない?

Posted on 11月 4, 2025 by Takaaki Naganoya

macOS 26.1がリリースされ、macOS 26.0で発生していたFinderまわりのバグが、一応修正されたような形跡もあるのですが、結論からいえば別のエラーが出るようになりました。

macOS 26.0:
ゴミ箱に何も入っていない状態で、AppleScriptからFinderに「empty trash」を実行すると、タイムアウト時間(180秒)まで待ってタイムアウトエラーに。

macOS 26.1、26.2:
ゴミ箱に何も入っていない状態で、AppleScriptからFinderに「empty trash」を実行すると、時間待ちしないでエラーに。

一応、empty trashをtry〜end tryで囲っておけば、ゴミ箱が空の場合に発生するエラーを回避できます。

AppleScript名:empty trash test 2.scpt
tell application "Finder"
  try
    empty trash
  end try
end tell

★Click Here to Open This Script 

Posted in Bug news | Tagged 26.0savvy | Leave a comment

日本のMac App StoreにEntanglerがカムバックしていた。が……

Posted on 11月 4, 2025 by Takaaki Naganoya

iOSデバイス(iPhone/iPad)からMac上のAppleScriptを実行するアプリには、

  EventScript(LAN/WLANを介して実行)
  Entangler(iCloudを経由して遠隔実行)

の2つがあるのですが、Entanglerについては日本のMac App Storeからしばらく消えていました。

このため、各種電子書籍でもentanglerの紹介については差し止めていました。海外のMac App Storeに出ているのは確認していたのですが、日本のMac App Storeで入手できないのでは紹介できません。

久しぶりにMac App Storeでいろいろ確認作業を行なっていたところ(AppleScriptでキーワード検索する程度のかんたんな作業)、Entanglerを見つけることができました。

これらのアプリには、

EventScripts:Keynoteのスライドめくりなど、割と応答速度が求められるような操作
Entangler:外出先から部屋の様子を撮影してメッセージで返すなど、リアルタイム性がシビアに求められないが、遠くから実行することに意義のある操作

といった「棲み分け」が発生しており、両方が存在する意義があると思っています。

……と、ここまでなら「心あたたまるニュース」であったのですが、Mac App Store上のリンクURLのリンク先(http://andymolloy.net/Entangler/)が応答不能(No Response)になっており、ちょっと心配です。

https://www.entanglerapp.com も、中華系のサイトが表示されるなど、きな臭い印象です。

ドメイン失効時にドメイン占有業者に乗っ取られたと見るべきでしょうか。ただ、これまで日本のMac App Storeに出ていなかったこのアプリが復帰した経緯がよくわかりません。

今後も、行方を注目しておくべきでしょう。

Posted in news Remote Control | Tagged 15.0savvy | Leave a comment

macOS 15.7.2 スクリプトメニューから実行できなくなった地図系ライブラリ?

Posted on 10月 11, 2025 by Takaaki Naganoya

macOS 15.7.2やmacOS 26.x上のスクリプトメニューで地図表示系のライブラリ呼び出し、とくにchoose location libが動作しません。

てっきり「スクリプトメニューで地図系のAPIへのアクセスが禁止されたのか?」と思っていたのですが、

同じく地図系APIにアクセスしているdisplay locationライブラリはスクリプトメニューから呼び出せています。

不思議。

以下に、AppleScriptライブラリの呼び出しが可能なAppleScript実行環境の一覧を示し、呼び出しの検証が行えているものは「Yes」を、検証して動かないことを確認したものに「No」と記入しています。

Program Name Can Call choose location Libraries?
Script Debugger 8 Yes
Script Editor Yes
Mail.app (rule–> Run AppleScript)
Shortcuts.app No Can not load map image
Shortcuts Events No Can not load map image
Script Menu (macOS 10.14 or later) No Can not execute
Terminal.app (osascript) Yes
Service Station
elgato Stream Deck
BBEdit No Can not execute
Jedit Ω
Adobe Indesign
Adobe Illustrator
Music (Script Menu) No Can not execute
Microsoft Excel
Microsoft Word
Microsoft PowerPoint
Keyboard Maestro
EventScript
FastScript 3 Yes
LaunchPalette
Visual Studio Code extension Yes
Dropzone 4
ScreenFloat
Xojo 2025 No Error
Live Code
Posted in Library Map | Tagged 15.0savvy 26.0savvy | 1 Comment

階層を指定したlistからOutLineViewで表示できるデータ形式に変換 v4(3階層対応)

Posted on 10月 10, 2025 by Takaaki Naganoya

入れ子のlist(2D List)で {{インデント階層+タイトル}…} 指定したデータを、NSOutlineViewで表示できるデータ形式に変換するAppleScriptです。

Keynoteに各スライドのインデント・レベルをAppleScriptに返す機能が存在しないため、各スライドのマスタースライド名から「このスライドマスターは、この階層に使いがち」といったルールをもとに階層関係を推測して処理しています。

主に、Keynote書類の各スライド(ページ)上のタイトルを、そのマスタースライド名をもとにインデントレベルを仮想的に判定し、PDFのTOCを作成する際の「プレビュー」を行うべく、NSOutLineViewで表示するために作成したものです。

これ自体は、2d ListからNSOutLineView表示用のデータを作成するだけのScriptです。

n階層をサポートしています。0がトップ階層。1がタブ1個と等価。2がタブ2個インデントと等価です。


{{0, "表紙"}, {0, "目次"}, {0, "1章"}, {1, "セクション1"}, {2, "項目1"}, {3, "コラム1"}, {2, "項目2"}, {3, "コラム2"}, {1, "セクション2"}, {2, "項目3"}, {0, "2章"}, {1, "セクションA"}, {2, "項目A1"}, {2, "項目A2"}, {1, "セクションB"}, {0, "裏表紙"}}

こんなデータを、

{{|name|:"表紙", isLeaf:true, children:{}}, {|name|:"目次", isLeaf:true, children:{}}, {|name|:"1章", isLeaf:false, children:{{|name|:"セクション1", isLeaf:false, children:{{|name|:"項目1", isLeaf:false, children:{{|name|:"コラム1", isLeaf:true, children:{}}}}, {|name|:"項目2", isLeaf:false, children:{{|name|:"コラム2", isLeaf:true, children:{}}}}}}, {|name|:"セクション2", isLeaf:false, children:{{|name|:"項目3", isLeaf:true, children:{}}}}}}, {|name|:"2章", isLeaf:false, children:{{|name|:"セクションA", isLeaf:false, children:{{|name|:"項目A1", isLeaf:true, children:{}}, {|name|:"項目A2", isLeaf:true, children:{}}}}, {|name|:"セクションB", isLeaf:true, children:{}}}}, {|name|:"裏表紙", isLeaf:true, children:{}}}

のように変換します。

NSOutlineViewをダイアログ表示するAppleScriptライブラリを作りかけて、データ作成部分もライブラリに組み込まないと使い物にならないと気づき、ChatGPTに作らせたものです。

AppleScript名:階層を指定したlistからOutLineViewで表示できるデータ形式に変換 v4(3階層対応).scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/10/10
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

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

— サンプル入力(3階層以上)
set srcList to {{0, "表紙"}, {0, "目次"}, {0, "1章"}, {1, "セクション1"}, {2, "項目1"}, {3, "コラム1"}, {2, "項目2"}, {3, "コラム2"}, {1, "セクション2"}, {2, "項目3"}, {0, "2章"}, {1, "セクションA"}, {2, "項目A1"}, {2, "項目A2"}, {1, "セクションB"}, {0, "裏表紙"}}

set aRec to convlistToStructuredRec(srcList) of me
–> {{|name|:"表紙", isLeaf:true, children:{}}, {|name|:"目次", isLeaf:true, children:{}}, {|name|:"1章", isLeaf:false, children:{{|name|:"セクション1", isLeaf:false, children:{{|name|:"項目1", isLeaf:false, children:{{|name|:"コラム1", isLeaf:true, children:{}}}}, {|name|:"項目2", isLeaf:false, children:{{|name|:"コラム2", isLeaf:true, children:{}}}}}}, {|name|:"セクション2", isLeaf:false, children:{{|name|:"項目3", isLeaf:true, children:{}}}}}}, {|name|:"2章", isLeaf:false, children:{{|name|:"セクションA", isLeaf:false, children:{{|name|:"項目A1", isLeaf:true, children:{}}, {|name|:"項目A2", isLeaf:true, children:{}}}}, {|name|:"セクションB", isLeaf:true, children:{}}}}, {|name|:"裏表紙", isLeaf:true, children:{}}}

on convlistToStructuredRec(allLines)
  set topList to {} — 最終出力
  
set stack to {} — 階層ごとの親ノードを保持
  
  
repeat with aLine in allLines
    copy aLine to {tabCount, lineStr}
    
set lineNS to (current application’s NSString’s stringWithString:(lineStr as text))
    
set contentText to (lineNS’s stringByTrimmingCharactersInSet:(current application’s NSCharacterSet’s whitespaceAndNewlineCharacterSet())) as text
    
if contentText is "" then
      — 空行スキップ
    else
      — 新しいレコード
      
set newRec to {|name|:contentText, isLeaf:true, children:{}}
      
      
if tabCount = 0 then
        — トップレベル
        
set end of topList to newRec
        
set stack to {newRec}
      else
        — stack を tabCount に合わせて切り詰め
        
if (count of stack) ≥ tabCount then
          set stack to items 1 thru tabCount of stack
        end if
        
        
— 親ノード取得
        
set parentRec to item tabCount of stack
        
        
— 親の children に追加
        
set parentChildren to parentRec’s children
        
set end of parentChildren to newRec
        
set parentRec’s children to parentChildren
        
        
— 親の isLeaf を false に
        
set parentRec’s isLeaf to false
        
        
— stack に追加
        
set end of stack to newRec
      end if
    end if
  end repeat
  
  
return topList
end convlistToStructuredRec

★Click Here to Open This Script 

Posted in list Record | Tagged 15.0savvy 26.0savvy | 1 Comment

Post navigation

  • Older posts

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

Google Search

Popular posts

  • macOS 26, Tahoe
  • Script Debuggerの開発と販売が2025年に終了
  • 【続報】macOS 15.5で特定ファイル名パターンのfileをaliasにcastすると100%クラッシュするバグ
  • NSObjectのクラス名を取得 v2.1
  • 2024年に書いた価値あるAppleScript
  • Xcode上のAppleScriptObjCのプログラムから、Xcodeのログ欄へのメッセージ出力を実行
  • AppleScript Dropletのバグっぽい動作が「復活」(macOS 15.5β)
  • Script Debuggerがフリーダウンロードで提供されることに
  • macOS 26, 15.5でShortcuts.app「AppleScriptを実行」アクションのバグが修正される
  • 指定フォルダ以下の画像のMD5チェックサムを求めて、重複しているものをピックアップ
  • 執筆中:AppleScript最新リファレンスver2.8対応(macOS 15対応アップデート)
  • Dock Menu
  • Applicationのactivateを記録する v2
  • Claris FileMaker Pro 2025(v22)がリリースされた
  • macOS 15.5beta5(24F74)でaliasのキャスティングバグが修正された???
  • 複数の重複検出ルーチンを順次速度計測
  • Numbersで選択範囲のdateの年を+1する
  • シンプルな文字置換
  • Appleに買収されたPixelmator ProがAppleとしての初アップデート
  • AS書類を書式で分解して再構成

Tags

10.11savvy (1101) 10.12savvy (1242) 10.13savvy (1391) 10.14savvy (587) 10.15savvy (438) 11.0savvy (283) 12.0savvy (212) 13.0savvy (204) 14.0savvy (159) 15.0savvy (165) 26.0savvy (35) CotEditor (67) Finder (53) Keynote (121) 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 (77) Pages (57) 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
  • Newt On Project
  • Noification
  • Notarization
  • Number
  • Object control
  • OCR
  • OSA
  • parallel processing
  • PDF
  • Peripheral
  • process
  • PRODUCTS
  • QR Code
  • Raw AppleEvent Code
  • Record
  • rectangle
  • recursive call
  • regexp
  • Release
  • Remote Control
  • Require Control-Command-R to run
  • REST API
  • Review
  • RTF
  • Sandbox
  • Screen Saver
  • Script Libraries
  • Scripting Additions
  • 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)
  • 未分類

アーカイブ

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

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

メタ情報

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

Forum Posts

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

メタ情報

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