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

Safariで表示中のWebページの最終更新日時を取得

Posted on 8月 17, 2018 by Takaaki Naganoya

指定のWebページ(URL)の最終更新日時(Last Modified Date)を取得するAppleScriptです。

AppleScriptそのものにWebの最終更新日時を取得する関数や機能はありません。はい、おしまい。

……というのでは、AppleScriptの本質がぜんぜん分かっていないね、ということになります。AppleScriptは「それができるアプリケーション」(など)に依頼を出すのが処理スタイルだからです。

まずは、Safariにコマンドを投げて実行するスタイル。

AppleScript名:Safariのdo javascriptコマンドで最終更新日時を取得
— Created 2018-08-17 by Takaaki Naganoya
— 2018 Piyomaru Software
tell application "Safari"
  tell front document
    set dRes to (do JavaScript "document.lastModified;")
  end tell
end tell

★Click Here to Open This Script 

だいたいは、これで手を打つでしょう。ただし、最近のmacOSではセキュリティ強化のためにSafariのdo javascriptコマンドがデフォルトでは禁止されているので、Safariで「開発」メニューを表示させたあとに、「開発」メニューの「AppleEventからのJavaScriptを許可」「スマート検索フィールドからのJavaScriptを許可」を実行しておく必要があります(→ 書籍「AppleScript 10大最新技術」P-84)。

Mac AppStore上で配布/販売するアプリケーションの中で処理することを考えると、SafariをコントロールすることをInfo.plist内で宣言しておけばとくに問題はありません。

do javascriptコマンドの実行で一般的にはファイナルアンサーなのですが、なぜでしょう。リアルタイム日付が返ってくるパターンが多いです。

次は、shellのcurlコマンドを呼び出すスタイルです。指定URLのレスポンスヘッダーを出力させられるので、これを検索して出力します。ただ、YouTubeをはじめとするWebサイトでこの最終更新日を返してこないので、これでもダメな時はダメです。

AppleScript名:curlコマンドで最終更新日時を取得
— Created 2018-08-17 by Takaaki Naganoya
— 2018 Piyomaru Software
tell application "Safari"
  tell front document
    set aURL to URL
  end tell
end tell

try
  set uRes to (do shell script "curl -D – -s -o /dev/null " & aURL & " | grep Date:")
on error
  return false
end try

★Click Here to Open This Script 

これも現在日時を返してくるパターンが多いですね。また、噂レベルではあるものの「do shell scriptコマンドは極力使わないほうがいいよ」というお達しがScripter界隈で流れているので、将来的に何かがあるのかもしれません(昔の、ごくごく初期のMac OS XはBSDレイヤーというかBSDコマンド類が、OSインストール時にオプション扱いだったので、そういう未来はあるかもしれない)。

Mac AppStore上で配布/販売するアプリケーションの中で処理するのも、とくに問題はないのですが、今度はネットワーク接続することをあらかじめ宣言しておくのと、httpによる通信を行うことを宣言しておかないとネットワーク接続ができません。

最後の手段。Cocoaを呼び出して自前でWebのレスポンスヘッダーを取得するスタイル。

AppleScript名:Cocoaの機能で最終更新日時を取得
— Created 2018-08-17 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

property NSString : a reference to current application’s NSString
property NSLocale : a reference to current application’s NSLocale
property NSURLRequest : a reference to current application’s NSURLRequest
property NSDateFormatter : a reference to current application’s NSDateFormatter
property NSURLConnection : a reference to current application’s NSURLConnection
property NSURLRequestUseProtocolCachePolicy : a reference to current application’s NSURLRequestUseProtocolCachePolicy

tell application "Safari"
  tell front document
    set aURL to URL
  end tell
end tell

set aURL to (current application’s |NSURL|’s URLWithString:aURL)
set {exRes, headerRes, aData} to checkURLResourceExistence(aURL, 3) of me
set aDate to headerRes’s |date| as string

set lastUpdateDate to dateFromStringWithDateFormat(aDate, "EEE, dd MMM yyyy HH:mm:ss zzz") of me
return lastUpdateDate

— 指定URLにファイル(画像など)が存在するかチェック
–> {存在確認結果(boolean), レスポンスヘッダー(NSDictionary), データ(NSData)}
on checkURLResourceExistence(aURL, timeOutSec as real)
  set aRequest to (NSURLRequest’s requestWithURL:aURL cachePolicy:(NSURLRequestUseProtocolCachePolicy) timeoutInterval:timeOutSec)
  
set aRes to (NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value))
  
set dRes to (first item of (aRes as list))
  
set bRes to (second item of (aRes as list))
  
if bRes is not equal to missing value then
    set hRes to (bRes’s allHeaderFields())
    
set aResCode to (bRes’s statusCode()) as integer
  else
    set hRes to {}
    
set aResCode to -1 –error
  end if
  
return {(aResCode = 200), hRes, dRes}
end checkURLResourceExistence

–指定形式の日付テキストをAppleScriptのdateオブジェクトに変換
on dateFromStringWithDateFormat(dateString, dateFormat)
  set dStr to NSString’s stringWithString:dateString
  
set dateFormatStr to NSString’s stringWithString:dateFormat
  
  
set aDateFormatter to NSDateFormatter’s alloc()’s init()
  
aDateFormatter’s setDateFormat:dateFormatStr
  
aDateFormatter’s setLocale:(NSLocale’s alloc()’s initWithLocaleIdentifier:"en_US_POSIX")
  
  
set aDestDate to (aDateFormatter’s dateFromString:dStr)
  
  
return aDestDate as date
end dateFromStringWithDateFormat

★Click Here to Open This Script 

結果は3つとも変わりませんでした。Cocoa呼び出しするものも、作り置きしておいたサブルーチンを使いまわしただけなので、作るのに3分もかかっていません。

curlを呼び出すスタイル同様、Mac AppStore上で配布/販売するアプリケーションの中で処理するのもとくに問題はないのですが、httpによる通信を行うことを宣言しておかないとネットワーク接続ができません。

Safariでdo javascriptコマンドを実行するものは、最初にdo javascriptコマンドを実行する設定が必要。curlコマンドはまあそんなもんだろうかと。Cocoaの機能を呼び出す方法は、ここまでやってダメならあきらめがつくというところでしょうか。

Posted in Calendar Internet JavaScript URL | Tagged 10.11savvy 10.12savvy 10.13savvy NSDateFormatter NSLocale NSString NSURLConnection NSURLRequest Safari | Leave a comment

心配性のリネームプログラム

Posted on 8月 15, 2018 by Takaaki Naganoya

安全策の上に安全策を講じた、心配性のファイル名称変更AppleScriptです。

基本的にはファイルのリネームプログラムであり、Finder上で選択中のファイルについてリネームを行います。

ただし、ファイルのリネーム時に同じファイル名のファイルがすでに存在していて、普段であれば衝突回避のために子番号を振るなどの対処を行うところが、そういう対応が許されていないようなケースに直面しました。

同じフォルダ内にある3つの画像ファイルを、名称が衝突するような他の名称に変更するようなケースです。

1.jpg --> 2.jpg(すでに2.jpgが存在)
2.jpg --> 3.jpg(すでに3.jpgが存在)
3.jpg --> 1.jpg

少々、頭を抱えてしまいました。

そこで、テンポラリフォルダをファイル1つごとに作成し、テンポラリフォルダにファイルを移動。

1.jpg --> /temp/uuid0001/1.jpg

そのタコツボ的なテンポラリフォルダの中でリネームを実施。

/temp/uuid0001/1.jpg --> /temp/uuid0001/2.jpg

リネームしたファイルを元のフォルダに戻すというリネームルーチンを作成した次第です。もちろん、作成したテンポラリフォルダは削除しておきます。

/temp/uuid0001/2.jpg --> 2.jpg

最近はこのAppleScriptのように、ファイル操作処理はNSFileManagerで実行し、Finderには「選択中のファイルの情報を取得」ぐらいしか行わせていません。そのため、ファイル処理が従来よりもはるかに高速に行えて、ちょっと楽しいぐらいです。

数千ファイルのコピー(込み入ったルールに従いJANコードなどのデータを参照して名前を決定したり、フォルダ名を製品名で作成したりとか)が1・2秒というオーダーで終わってしまうのは、SSD上で処理しているせいもありますが、NSFileManager経由でのファイル処理を行っているおかげです(64bit化したCocoa Finderはとにかく処理が遅いのでAppleScriptからのファイル操作用に使うとダメ)。

AppleScript名:tempフォルダに移動しつつリネームして、終了後に元フォルダに戻す v2.scptd
— Created 2018-08-14 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

property NSUUID : a reference to current application’s NSUUID
property NSString : a reference to current application’s NSString
property NSFileManager : a reference to current application’s NSFileManager

property tResList : {}
property tFol : ""
property newNameTemplate : "test_"

set tResList to {}
set tFol to POSIX path of (path to temporary items)

tell application "Finder"
  set aSel to selection as alias list
  
if aSel = {} then
    display notification "No Selection"
    
return
  end if
end tell

–コピー元ファイルの親フォルダを求める(リネーム後に戻す)
set origFol to POSIX path of (contents of first item of aSel)
set origFolStr to ((NSString’s stringWithString:origFol)’s stringByDeletingLastPathComponent()) as string

–一時フォルダに移動してリネーム
set aCount to 1
repeat with i1 in aSel
  set j1 to POSIX path of (contents of i1)
  
set newName to newNameTemplate & (aCount as string)
  
set j1Res to renameSafely(j1, newName) of me
  
set the end of tResList to (j1Res as string)
  
set aCount to aCount + 1
end repeat

–元のフォルダに戻して一時フォルダ削除
repeat with i2 in tResList
  set j2 to contents of i2
  
set j2Res to (my moveFileAt:j2 toFolder:origFolStr)
  
set j2Res to deleteParentFol(j2) of me
end repeat

–安全なリネーム(個別のテンポラリフォルダに移動してリネーム)
on renameSafely(aFile, newName)
  –set tFol to POSIX path of (path to temporary items)
  
set aUUIDstr to ((NSUUID’s UUID()’s UUIDString()) as string)
  
set aTmpFol to tFol & aUUIDstr
  
  
set dRes to makeDirAbsolutely(aTmpFol) of me
  
set mRes to my moveFileAt:aFile toFolder:aTmpFol
  
  
set aStr to (NSString’s stringWithString:aFile)
  
set newFullPath to aTmpFol & "/" & aStr’s lastPathComponent()
  
set aExt to aStr’s pathExtension()
  
  
set fRes to renameFileItem(newFullPath, newName) of me
  
  
set renamedPath to aTmpFol & "/" & newName & "." & aExt
  
  
return renamedPath
end renameSafely

–指定パスににフォルダを作成する
on makeDirAbsolutely(dirStr)
  set fileManager to NSFileManager’s defaultManager()
  
set aRes to fileManager’s createDirectoryAtPath:dirStr withIntermediateDirectories:true attributes:(missing value) |error|:(reference)
  
copy aRes to {aFlag, aError}
  
return aFlag as boolean
end makeDirAbsolutely

on moveFileAt:POSIXPath toFolder:folderPOSIXPath
  set POSIXPath to NSString’s stringWithString:POSIXPath
  
set theName to POSIXPath’s lastPathComponent()
  
set folderPOSIXPath to NSString’s stringWithString:folderPOSIXPath
  
set theNewPath to folderPOSIXPath’s stringByAppendingPathComponent:theName
  
set fileManager to NSFileManager’s defaultManager()
  
set theResult to fileManager’s moveItemAtPath:POSIXPath toPath:theNewPath |error|:(missing value)
  
return theNewPath
end moveFileAt:toFolder:

on renameFileItem(aPOSIXpath as string, newName as string)
  set theNSFileManager to NSFileManager’s defaultManager()
  
set POSIXPathNSString to NSString’s stringWithString:(aPOSIXpath)
  
  
–Make New File Path
  
set anExtension to POSIXPathNSString’s pathExtension()
  
set newPath to (POSIXPathNSString’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:newName)’s stringByAppendingPathExtension:anExtension
  
  
–Rename
  
if theNSFileManager’s fileExistsAtPath:newPath then
    return false
  else
    set theResult to theNSFileManager’s moveItemAtPath:POSIXPathNSString toPath:newPath |error|:(missing value)
    
if (theResult as integer = 1) then
      return (newPath as string)
    else
      return false
    end if
  end if
end renameFileItem

on deleteParentFol(aPOSIX)
  set aStr to NSString’s stringWithString:aPOSIX
  
set parentFol to aStr’s stringByDeletingLastPathComponent()
  
set aRes to deleteItemAt(parentFol) of me
  
return aRes
end deleteParentFol

on deleteItemAt(aPOSIX)
  set theNSFileManager to NSFileManager’s defaultManager()
  
set theResult to theNSFileManager’s removeItemAtPath:(aPOSIX) |error|:(missing value)
  
return (theResult as integer = 1) as boolean
end deleteItemAt

★Click Here to Open This Script 

Posted in file File path | Tagged 10.11savvy 10.12savvy NSFileManager NSString NSUUID | Leave a comment

Newt On Projectのプレゼン書類を公開

Posted on 8月 15, 2018 by Takaaki Naganoya

2002〜2003年ごろにAppleScriptでいまのSiriライクな人工知能インタフェース「Newt On」を作っていた頃の、プレゼン資料をSlideshare上に公開しました。
→ Slideshare上のアカウントが凍結されたので(なんで?) 本Blogに掲載しておきました。

書籍「AppleScriptの穴Blogアーカイブvol.3」掲載のNewt On Project記事と合わせてご覧になると、より分かりやすいと思います。

Posted in Books PRODUCTS | Leave a comment

CSVデータを読み込んで表インタフェースで表示確認 v2

Posted on 8月 14, 2018 by Takaaki Naganoya

指定のCSVファイルを読み込んで、表インタフェースで表示確認するAppleScriptです。

Numbers.appから文字コードにUTF-8を指定して書き出したCSVファイルを想定しています。CSVデータのparseにはBridgePlusを、表UIの表示にはMyriad Tables Libを利用しています。

ほぼ、テンプレートともいえるような定型処理ですが、巨大なAppleScriptに入れたときにはusing terms from句がないとアプレットとして動作中にクラッシュが発生する可能性があります。

CSVデータの処理はありふれたありきたりの内容で、本来は処理内容にはほとんど関係ない表示・確認を行わせるとユーザーの反応がいいようです。

あとは、CSVデータ中にカラムヘッダーが存在するかどうかをCSVデータからでは検出できないことが問題です。せめて、メタデータ中にでもカラムヘッダーの有無を(Export時に)書いておいてくれるとよいのですが。あとは、CSV1行目のデータと他の行との文字コードの分布状況を比較して統計処理すると、相関性を数値化してヘッダーかどうかを計算できそうですが、、、そこまでやるのは「やりすぎ」でしょう。

ユーザーにヘッダーの有無を確認するとか、そのぐらい?

_kMDItemOwnerUserID            = 504
kMDItemAlternateNames          = (
    "2010_index.csv"
)
kMDItemContentCreationDate     = 2018-08-14 00:51:24 +0000
kMDItemContentModificationDate = 2018-08-14 00:51:24 +0000
kMDItemContentType             = "public.comma-separated-values-text"
kMDItemContentTypeTree         = (
    "public.comma-separated-values-text",
    "public.data",
    "public.delimited-values-text",
    "public.plain-text",
    "public.item",
    "public.content",
    "public.text"
)
kMDItemDateAdded               = 2018-08-14 00:51:24 +0000
kMDItemDisplayName             = "2010_index"
kMDItemFSContentChangeDate     = 2018-08-14 00:51:24 +0000
kMDItemFSCreationDate          = 2018-08-14 00:51:24 +0000
kMDItemFSCreatorCode           = ""
kMDItemFSFinderFlags           = 16
kMDItemFSHasCustomIcon         = (null)
kMDItemFSInvisible             = 0
kMDItemFSIsExtensionHidden     = 1
kMDItemFSIsStationery          = (null)
kMDItemFSLabel                 = 0
kMDItemFSName                  = "2010_index.csv"
kMDItemFSNodeCount             = (null)
kMDItemFSOwnerGroupID          = 80
kMDItemFSOwnerUserID           = 504
kMDItemFSSize                  = 7746
kMDItemFSTypeCode              = ""
kMDItemKind                    = "Comma Separated Spreadsheet (.csv)"
kMDItemLogicalSize             = 7746
kMDItemPhysicalSize            = 8192
kMDItemUserCreatedDate         = (
    "2018-08-14 00:51:24 +0000"
)
kMDItemUserCreatedUserHandle   = (
    504
)

▲ここ(メタデータ)にCSVのヘッダーの有無の情報が入っているといいのに、、、、にしても、メタデータに大昔のResource Forkよろしくいろんなデータが突っ込まれるようになってきました


▲CSVファイルの選択


▲CSVファイル内容の表示


▲CSV内のカラム数が合っていた場合の動作


▲CSV内のカラム数が合っていない場合の動作(データ確認表示)


▲CSV内のカラム数が合っていない場合の動作(ダイアログ表示)

AppleScript名:CSVデータを読み込んで表インタフェースで表示確認 v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2018/08/10
—
–  Copyright © 2018 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use Bplus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html
use tableLib : script "Myriad Tables Lib" –https://www.macosxautomation.com/applescript/apps/Script_Libs.html#MyriadTablesLib

–Numbersから書き出したUTF-8のCSVを読み取る
set someString to read (choose file of type {"public.comma-separated-values-text"}) as «class utf8»

–読み込んだテキストをParseして、ヘッダーとデータ本体に分離
set {theHeader, origList} to readCSVAndParse(someString) of me

–Table UIを表示して内容を確認
set colMax to 3 –あらかじめ期待しているカラム数
set {dRes, tRes} to dispTableUI(theHeader, origList, colMax) of me
if dRes = false then
  display dialog "データ不全のため処理を終了します" with title "CSVデータエラー"
  
return
else
  display dialog "CSVデータの処理を続行します" with title "CSVデータOK"
end if

on readCSVAndParse(someString)
  load framework
  
using terms from script "BridgePlus"
    set theData to current application’s SMSForder’s arrayFromCSV:someString commaIs:","
    
set origList to (current application’s SMSForder’s subarraysIn:theData paddedWith:"" |error|:(missing value)) as list
  end using terms from
  
  
set theHeader to contents of first item of origList –Header Row
  
set origList to rest of origList –Data
  
return {theHeader, origList}
end readCSVAndParse

on dispTableUI(theHeader, origList, colMax)
  set {curDispW, curDispH} to (current application’s NSScreen’s mainScreen()’s frame()’s |size|()) as list
  
  
set curLen to length of first item of origList
  
set dRes to (curLen = colMax) as boolean
  
if dRes = true then
    set aMessage to "問題がなければ「OK」をクリックして実行してください" –Normal message
    
set aTitle to "CSVファイルの内容確認"
  else
    set aMessage to "CSVファイルのカラム数が期待どおりではありません。「Cancel」をクリックして実行を停止してください" –Error Message
    
set aTitle to "CSVファイルに異常あり"
  end if
  
  
using terms from script "Myriad Tables Lib"
    tell script "Myriad Tables Lib"
      set aDispBounds to my makeInitialBounds:(curDispW – 100) withHeight:(curDispH – 100)
      
set theTable to make new table with data origList column headings theHeader with title aTitle with prompt aMessage with row numbering, empty selection allowed and multiple lines allowed
      
      
modify table theTable initial position aDispBounds
      
      
–表を表示
      
set tRes to (display table theTable)
      
return {dRes, tRes}
    end tell
  end using terms from
end dispTableUI

on makeInitialBounds:(aTWidth as integer) withHeight:(aTHeight as integer)
  set aDispBounds to current application’s NSScreen’s mainScreen()’s frame()
  
set aWidth to (width of |size| of aDispBounds)
  
set aHeight to (height of |size| of aDispBounds)
  
  
set xPos to (aWidth div 2) – (aTWidth div 2)
  
set yPos to (aHeight div 2) – (aTHeight div 2)
  
  
return {xPos, yPos, aTWidth, aTHeight}
end makeInitialBounds:withHeight:

★Click Here to Open This Script 

Posted in file GUI Text | Tagged 10.11savvy 10.12savvy 10.13savvy NSScreen | Leave a comment

本気で使うといろいろ粗が見えてくるScript Debugger

Posted on 8月 13, 2018 by Takaaki Naganoya

込み入った案件で必要になって、Script Debugger 7を購入しました。Adobeの大型アプリケーションのオブジェクト階層を調査したい場合にはScript Debuggerを使わないのは自殺行為です。

その反面、Xcodeの外部エディタとして使うなら、まだASObjC Explorer 4のほうが使い勝手がいいし(Xcode上で外部エディタを指定してscriptを再編集するとxibファイルのトラブルなど諸問題が解決するのに、Script Debuggerだと解決しない)、クラッシュの頻度もややScript Debuggerのほうが高い気がします。

本気で組んだ仕事用のAppleScript相手だと、Script Debugger上で作って、Script Debugger上で動作させるだけなら問題はないのですが、アプレットを書き出して実行させるあたりで疑問符が出てきます。

AppleScript上で何かの予約語が存在していた場合に、「どのアプリケーション、どのScript Libraries」の用語辞書から使用したものなのかをusing terms from句で囲ってこまめに宣言しておかないと、書き出したAppleScriptアプレットを起動しようとしてもクラッシュします。

# しかも、Scriptのサイズが小さい場合にはクラッシュせず、大きくなるとクラッシュするという、、、

また、using terms from句で囲むさいにはuse宣言で代入したプロパティが使えず(using terms from bPlus とか)、using terms from script “BridgePlus”のように書かないとScript Debugger上で構文確認が通りません(こちらはAppleScript処理系そのものの動作の癖?)。

さらに、「anything」(≒”any”)という(Appleに)いい加減に実装されてきた予約語を、さまざまなライブラリで別々に(ちゃんと)実装していたりすると、Script Debugger上での構文確認時に「どのアプリケーションの予約語なのか分からないぞ」というワーニングメッセージが出ます。これ、ダイアログで表示するなら、リストから選択させるとかいった動作の方がいいと思います。

このあたり、Apple純正のスクリプトエディタやASOBjC Explorer 4(現在はScript Debuggerと合流)では確認していない現象ですが、Script Debuggerを使っているかぎりはこまめにusing terms fromで囲う必要があるようです。

Posted in 未分類 | Tagged 10.12savvy Script Debugger | Leave a comment

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

Posted on 8月 13, 2018 by Takaaki Naganoya

ごく一部の愛読者の皆様からのご要望を受け、2018年1月のBlog消滅以前の内容を1年ごとにまとめた「Blogアーカイブ本」のVol.3を販売開始しました。Vol.3は2010年1〜12月の内容をまとめています。全401ページ、2,000円。ファイル形式はPDFで、キーワードによる全文検索や印刷が行えます。

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

2014年以前の巻についてはCocoaの機能をほとんど使っていないので、Cocoa Scriptingについてはわからないとか、Cocoa Scriptingになじめない方には「Cocoaを使わないやりかた」が説明されている、現時点では数少ないまとまった参考文献になるはずです。

また、2000年代初頭にAppleScriptで開発した人工知能インタフェース「Newt On」プロジェクトについての当時のレポート記事、初期バージョンのNewt Onのソースリストなども掲載しています(さすがに古いバージョンのMac OS X上で構文確認する必要があったので、URLリンク入りのプログラムリストにはできませんでしたが……色分けリストでは掲載しています)。

続刊刊行スケジュールについては、「できた分から」としか言いようがありませんが、各巻のボリュームについては、

 vol.4:2011/1〜2012/12(仮組みページ数:372)
 vol.5:2013/1〜2014/12(仮組みページ数:276)
 vol.6:2015/1〜12(仮組みページ数:320)

といったところです。価格は一律2,000円です。当初は日本語版だけですが、英語版も出せるといいですね。Vol.5/6については、Cocoa Scriptingがわからないと手が出しづらいので、Cooca Scriptingの入門資料を添付することも検討中です。

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

–Newt On Projectアーカイブ部

#1 始動
#2 インテリジェントな環境を構築するもうひとつの要素〜SOAP
#3 Wordに見るインテリジェント処理の可能性
#4 ついに姿を現した「えせNewton」
#5 えせNewtonの正式名称が決定
#6 えせNewton、大地に立つ!
#7 えせNewton 改良強化新型の系譜
#8 コマンド、目的語、サブキーを認識
#9 Classic MacOS 9への挑戦
#10 ついに疑似対話が可能に
#11 えせNewton、Mac界に激震をもたらす?
#12 複数のコマンドを実装 メール出せます
#13 Newtonを超えた~Now, “Newt On” is beyond the Newton.
#14 Newt Onから見た日本語形態素解析事情
#15 Newt On一般向けバイナリ配布開始
ABUI “Newt On”とは?
Newt On Project 活動報告
用語解説
Newt On ロードマップ
#番外編 プロジェクトMac OS X~技術屋たち「Newtonよもう一度! 〜スタートレックの世界を夢見た男たち」

–Blogアーカイブ部

指定形式でスクリーンキャプチャを撮る
動的に演算子を指定してリストから要素を取り出す
lengthの同義語number of items
タイマー割り込み処理
指定されたファイルのparentにラベルとコメントを付ける
Aperture 3でAppleScript関連機能に大きな前進
AppleScriptで扱う「パス」について(1)
AppleScriptにおける「パス」について(3)
AppleScriptにおける「パス」について(4)
I/Oデータの地デジチューナー「m2TV」添付ソフトがAppleScriptに対応
AppleScript用語辞書の変更履歴が分かるよう「DICT」メニューを整備中
「AppleScriptの穴」、気がつけば3年目
m2TVの録画スケジュール情報を取得する
m2TVの録画ライブラリ情報を取得する
pdfinfoの結果をparseするv3
リストから指定のアイテムを削除する
SHA-1 digestを求める
次期SilverlightでAppleScriptのサポートが現実のものに?
iTunes 9.1で用語辞書に変更アリ
脳波ビジュアライザ「IBVA Ver.4」がAppleScriptに対応
Photoshop CS3で指定アクションセット内のアクション一覧を取得する
現在編集中のXcodeプロジェクトのビルドターゲットが生成したpreferenceファイルを削除する v3
ImageEventsで画像回転(時計回りに90度)
ImageEventsで画像回転(反時計回りに90度)
ImageEventsで画像の縦横サイズを取得する
ImageEventsで75%にリサイズ
ImageEventsでTIFF保存
ImageEventsで横幅400ピクセルに
4月29日のラジオ番組に参加します
Finder上で選択中の画像を横幅400ドットにリサイズ
指定のtarアーカイブを展開する
手書き文字認識アプリケーション「QuickScript」がバージョン3.0でAppleScriptに対応
マウント中のdiskimage中のファイルをすべて削除
Xcodeで表示中のScriptの各ハンドラ行数をカウント
ファイルのコピー(通常実行、非同期高速実行)
指定のリストから削除指定リストに入っているアイテムを削除する
deleteListに入っている数値に該当するものをリストから削除する
リストから、指定データが何アイテム目に登場するかを算出
指定のアプリケーションの起動を待つ
指定文字列のAppleScriptをAppleScriptエディタ上で実際に実行して結果を文字列として取得する
指定文字列のAppleScriptをAppleScriptエディタ上で実際に実行して結果を文字列として取得する 10.5_10.6
指定のzipアーカイブを展開してファイルを取り出す
指定フォルダ内をすべて削除し、そのフォルダも削除
iChatで文字チャットの相手に文字列を送信。長い場合にはテキストに書き出してzip圧縮して送信
リストをレコードに v2
iEPGのファイルから各種情報を取り出してみるテスト v2
iEPGのファイルから各種情報を取り出してみるテスト v3
iEPGのファイルから各種情報を取り出してみるテスト v4
Mail.appで選択しておいたメッセージに返信してsubjectと本文を加える
iPhotoに指定画像をインポートする
DateオブジェクトからYYYY-MM-DD-hh-mm-ssの形式の文字列を返す
数値の序数の文字列を返す
アドレスブックでmy cardがあるかどうか取得する
Photoshopで複数画像の「差の絶対値」を計算するテスト v3
Snow Leoaprdで追加になったsayコマンドのパラメータテスト3
ファイル作成日付を変更する
文字列から数字の部分を取り出してリスト化
指定矩形座標内に含まれる座標をピックアップ
現在のドキュメント上のアイテムをすべてグループ解除
GUI部品にAppleScriptを貼り付ける「UI Actions 2.0.0」
近似色を求めるサンプル
エイリアス書類からオリジナルファイルの情報を取得する
Script Objectのparseのじっけん v4
時刻文字列の差を数値で返す
改行のみで囲まれた行をリストで取り出す
現在のユーザーの権限を調べる v2
数値リストを連続部分に分解する
Elgatoのハードウェアエンコーダturbo.264 HDがAppleScriptに対応
指定年_月の初日(1日)がその年の何日目かを取得する
指定日がその年の何日目かを取得する
指定年月の最初のx曜日を返す
指定年月の最後のx曜日を返す
与えられた日付の「月」が異なるかどうかチェック
2つのdateの差を月単位で取得する
実体参照している文字列をデコードする
簡単な素因数分解
簡単な素因数分解v2
数字で指定した月の英語名称を返す
2つのdateの差を月単位で取得する。パラメータはdateオブジェクトではなくリストで
dateに対してincMonthNumか月足した結果の年、月を取得する
openハンドラでファイルパス以外を渡す
指定の数字の組み合わせのすべてのパターンをリストアップ
アプリのアイコンをJPEG画像化してデスクトップに書き出すv23
SkimでPDFをページごとに分割する
指定名称のムービーを指定開始-終了時間の間を取り出して指定名称で保存 v1
Font Bookでfont collectionを作成する
Font Bookで指定文字列ではじまるfont collectionをすべて削除する
指定のフォントファイルをFont Bookに追加して情報を取得する
指定のフォントをFont Bookから削除する v3
フォルダ差分コピー
指定フォルダ以下のファイルやフォルダからラベルを外す
Font Bookで選択中のフォントを削除(Font Containerなしフォント、および複数選択対応)
フォント情報をSystem Profiler経由で取得する
ひらがなカタカナ変換
iLife 11のAppleScript用語辞書の変更点
AppleScriptObjCでハマったこと
数字桁漢字まじり日本語的数値表現テキストをparseする
Mobiolaで静止画像をキャプチャする
Mobiolaで静止画像をキャプチャ、ファイル名指定つき
Mobiolaでビデオ録画を開始、停止
Finder上で選択中のフォルダをdiskimageに(パスワード指定つき)
入れ子のリストから、指定アイテムの値が連続して同じ値で続くブロックを検出する
Terminal.appで指定コマンドを実行する
指定フォルダ容量をMB単位で返す_v2
Mac添付の赤外線リモコンのon,off_v2

Posted in Books | 1 Comment

複数のアートボードを持つAI書類を、デスクトップにアートボードごとに分割して保存

Posted on 8月 11, 2018 by Takaaki Naganoya

Adobe Illustrator CC 2018(バージョン22.1)で、複数のアートボードを持つAdobe Illustrator書類をアートボードごとに分割保存するAppleScriptです。

オプションの指定方法にものすごく納得しづらいものを感じるものの、これで動くので仕方ないだろうかというところ。

AppleScript名:複数のアートボードを持つAI書類を、デスクトップにアートボードごとに分割して保存.scptd
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set dtPath to ((path to desktop) as string) & "template.ai"

tell application "Adobe Illustrator"
  tell front document
    set aCount to (count every artboard) as string
    
set sOpt to {class:Illustrator save options, save multiple artboards:true, artboard range:"1-" & aCount}
    
save as Illustrator in file dtPath with options sOpt
  end tell
end tell

★Click Here to Open This Script 

Posted in file File path | Tagged 10.11savvy 10.12savvy Illustrator | Leave a comment

オープン中のIllustrator書類をartboardごとに分割 v3

Posted on 8月 9, 2018 by Takaaki Naganoya

Adobe Illustrator CC 2018(バージョン22.1)で、オープン中の(複数のアートボードを持つ)書類を、アートボード単位で別書類に分けるAppleScriptの改修版です。

書類は(とりあえず)デスクトップに書き込まれます。前バージョンのように、アートボード外のオブジェクトが残るといったことはありません。

「exportSelectedArtwork」という長いコマンドを見つけて、ためしてみたら期待どおりの挙動であったために使ってみました。

……すると、なおのことAppleScriptからartworkのselectができないのか?(実行すると100% Illustratorがクラッシュする) artworkからnameの取得ができないのか?(実行するとエラーになる)というあたりが謎です。

artboardも選択状態になっている(はず)だと思って、そのまま実行してみたところ、artboardのサイズでは書き出されていないようです。少し別の方法を試す必要があり、自分は前バージョンのScriptにもどって作業を行っています。

AppleScript名:オープン中のIllustrator書類をartboardごとに分割 v3.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2018/08/07
–  Modified on: 2018/08/09
–  Copyright © 2018 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.5" — El Capitan (10.11) or later
use framework "Foundation"
use scripting additions

set dPath to (path to desktop) as string
set namesList to {}

tell application "Adobe Illustrator"
  tell front document
    set aCount to count every artboard
    
set aPath to (file path) as string
  end tell
  
  
repeat with i from 1 to aCount
    set aName to getArtboardName(i – 1) of me –index base correction (1 –> 0)
    
set outPath to dPath & aName & ".ai"
    
    
selectArtboard(i – 1) of me –index base correction (1 –> 0)
    
    
tell front document
      selectobjectsonactiveartboard
      
exportSelectedArtwork to file outPath
    end tell
  end repeat
end tell

–https://lists.apple.com/archives/applescript-users/2015/Jul/msg00104.html
on selectArtboard(theArtboardIndex as string)
  tell application "Adobe Illustrator"
    tell front document
      –Index is 0 based
      
do javascript ("app.activeDocument.artboards.setActiveArtboardIndex(" & theArtboardIndex & ")")
    end tell
  end tell
end selectArtboard

on getArtboardName(theArtboardIndex as string)
  tell application "Adobe Illustrator"
    tell front document
      –Index is 0 based
      
do javascript ("app.activeDocument.artboards[" & theArtboardIndex & "].name")
    end tell
  end tell
end getArtboardName

★Click Here to Open This Script 

Posted in file File path | Tagged 10.12savvy Illustrator | Leave a comment

オープン中のIllustrator書類をartboardごとに分割 v2

Posted on 8月 9, 2018 by Takaaki Naganoya

Adobe Illustrator CC 2018(バージョン22.1)で、オープン中の(複数のアートボードを持つ)書類を、アートボード単位で別書類に分けるAppleScriptです。

書類は(とりあえず)デスクトップに書き込まれます。

こういうコマンドが最初からあってもおかしくないところですが、存在していないようなので書いてみました。まずは、オープン中の書類のパスを取得し、各アートボードの名称を取得して書き出し時のファイル名として使用します。

元ファイルをクローズしては、デスクトップに新規名称でコピーし、コピーした書類をオープン、書き出し対象外のアートボードを順次選択してはアートボード上のオブジェクトを削除してアートボード自体も削除、すべて削除したら保存してクローズという動作を行います。

本来であれば高速化のために複数のアートボードを一括で削除することを考えるところですが、アートボードの削除だけであればできるものの、アートボード上のオブジェクトの削除が行えなくなってしまうので、順次削除に落ち着きました。また、本Scriptが本気でスピードを求められるようなハードな用途ではなく、文字や画像の流し込みテンプレートのメンテナンス用という「平和な用途」のために作成したものであるため、高速化処理については考慮していません。

最初からアートボード外に置かれたオブジェクトについては削除していません。あくまで自分用のツールなので作り込む必要性を感じません。気が向いたら削除するのではないでしょうか。

本Scriptの作成中にも、単にAppleScriptで命令を出しただけで派手にクラッシュしまくるAdobe Illustrator。バージョンが上がって見た目が変わっても、あの出来の悪いIllustratorであることに変わりはないのだと思い知らされました。

AppleScript名:オープン中のIllustrator書類をartboardごとに分割 v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2018/08/07
—
–  Copyright © 2018 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.5" — El Capitan (10.11) or later
use framework "Foundation"
use scripting additions

set dPath to (path to desktop) as string
set namesList to {}

tell application "Adobe Illustrator"
  tell front document
    set aCount to count every artboard
    
set aPath to (file path) as string
  end tell
  
  
repeat with i from 1 to aCount
    set aName to getArtboardName(i – 1) of me –index base correction (1 –> 0)
    
set the end of namesList to aName
  end repeat
  
  
close every document saving no
end tell

repeat with i from 1 to aCount
  
  
set aRes to retSerialListWithExclusion(1, aCount, i) of me
  
set aaRes to reverse of aRes –artboardをIndex値で指定するため、先頭から削除するとIndex値が変わる。そのため逆順に処理
  
  
set tmpName to contents of item i of namesList
  
  
set fromFile to POSIX path of aPath
  
set fromFilePOSIX to quoted form of POSIX path of fromFile
  
  
set toFile to (dPath & tmpName & ".ai")
  
set toFilePOSIX to quoted form of POSIX path of toFile
  
  
set shText to "cp " & fromFilePOSIX & " " & toFilePOSIX
  
do shell script shText
  
  
tell application "Adobe Illustrator"
    open file toFile
    
tell front document
      repeat with ii in aaRes
        set jj to ii as integer
        
selectArtboard(jj – 1) of me –index base correction (1 –> 0)
        
selectobjectsonactiveartboard
        
delete selection
        
delete artboard jj
      end repeat
      
      
close with saving
    end tell
  end tell
  
end repeat

–https://lists.apple.com/archives/applescript-users/2015/Jul/msg00104.html
on selectArtboard(theArtboardIndex as string)
  tell application "Adobe Illustrator"
    tell front document
      –Index is 0 based
      
do javascript ("app.activeDocument.artboards.setActiveArtboardIndex(" & theArtboardIndex & ")")
    end tell
  end tell
end selectArtboard

on getArtboardName(theArtboardIndex as string)
  tell application "Adobe Illustrator"
    tell front document
      –Index is 0 based
      
do javascript ("app.activeDocument.artboards[" & theArtboardIndex & "].name")
    end tell
  end tell
end getArtboardName

on retSerialListWithExclusion(aFromNum as integer, aToNum as integer, anEXnum as integer)
  set outList to {}
  
repeat with i from aFromNum to aToNum
    if i = anEXnum then
      —
    else
      set the end of outList to i
    end if
  end repeat
  
  
return outList
end retSerialListWithExclusion

★Click Here to Open This Script 

Posted in file File path shell script | Tagged 10.12savvy Illustrator | Leave a comment

WordPressの指定IDの記事にリンクされているapplescriptからCocoa Classのproperty宣言を抽出 v3

Posted on 8月 5, 2018 by Takaaki Naganoya

本BlogのようなWordPressで運用されており、AppleScriptのURLリンクを記事に埋め込んでいるWordPressに対して、XML-RPC経由で指定IDの記事本文を取得し、埋め込まれているURLリンクからAppleScriptのソースコードを取得して、メモリー上でコンパイルして書式つきテキストに変換し、AppleScript構文書式をもとにpropertyラベルを抽出、そのうちCocoa Classのみをリストで取得するAppleScriptです。

本Blogに投稿した記事から宣言しているCocoa Classを抽出し、自動でタグ付けするために準備したものです。1記事に対して複数のAppleScriptが掲載されている場合にも対応しています。

HTMLReader.frameworkを用いてBlog本文からのリンク抽出、リンクURL抽出を行っています。

–> HTMLReader.framework(To ~/Library/Frameworks/)

本Sample Scriptで指定したIDの記事のproperty部分はこのようになっており、

本Scriptの実行によって抽出されたCocoa Class(単なる変数的なproperty項目や、Enumは対象外のため排除)は、

–> {“NSString”, “NSArray”, “OSAScript”, “NSPredicate”, “OSALanguage”, “NSDictionary”, “OSALanguageInstance”, “NSBundle”, “NSUnarchiver”}

のようになります。自分の環境でMacBook Proを有線ネットワーク接続した状態で、3.3〜3.4秒程度かかっています。大量の記事を処理する場合には本AppleScriptの並列処理を行うと処理時間の大幅な短縮が期待できます(MacのCPUがサーマルスロットリングで速度低下しなければ)。

また、負荷が集中している特定コアの動作周波数を上げ、他のコアの動作周波数を落とすTurbo Boostが有効な状態で並列処理を実行すると、並列処理を行う意義そのものが低下してしまうため、Turbo-Boost-Switcherのようなツールの併用が必要と思われます。

AppleScript名:WordPressの指定IDの記事にリンクされているapplescriptからCocoa Classのproperty宣言を抽出 v3
— Created 2018-07-30 by Takaaki Naganoya
— Modified 2018-08-05 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "OSAKit"
use framework "HTMLReader" –https://github.com/nolanw/HTMLReader

property |NSURL| : a reference to current application’s |NSURL|
property NSArray : a reference to current application’s NSArray
property NSString : a reference to current application’s NSString
property NSBundle : a reference to current application’s NSBundle
property NSThread : a reference to current application’s NSThread
property OSAScript : a reference to current application’s OSAScript
property NSPredicate : a reference to current application’s NSPredicate
property NSTextView : a reference to current application’s NSTextView
property NSDictionary : a reference to current application’s NSDictionary
property NSUnarchiver : a reference to current application’s NSUnarchiver
property OSALanguage : a reference to current application’s OSALanguage
property OSAScriptView : a reference to current application’s OSAScriptView
property NSMutableArray : a reference to current application’s NSMutableArray
property OSAScriptController : a reference to current application’s OSAScriptController
property NSMutableDictionary : a reference to current application’s NSMutableDictionary
property OSALanguageInstance : a reference to current application’s OSALanguageInstance
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding

set postID to 3864
set {myUser, myPass} to getAcountData() of me
set aURL to "http://piyocast.com/as/xmlrpc.php"
set cocoaClassList to getCocoaPropListFromPost(aURL, postID, myUser, myPass) of me
–>  {"NSString", "NSBundle", "NSPredicate", "NSDictionary", "NSMutableArray", "NSMutableDictionary"}

–指定Blogの指定IDの記事にURLリンクされているAppleScriptから、Cocoa Classのpropertyのみ取得する
on getCocoaPropListFromPost(aURL, postID, myUser, myPass)
  –AppleScriptの構文色分け設定ファイルを読み込んで、重複色のチェックを実施  
  
set cList to getAppleScriptSourceColors() of me
  
set cRes to chkASLexicalFormatColorConfliction(cList) of me –構文色分けの重複色チェック
  
if cRes = false then error "There is some duplicate(s) color among AppleScript’s lexical color settings"
  
  
–WordPressの指定Post IDの記事を取得してリンクされているURLからURL Schemeでフィルタして、リンクされているAppleScriptのソースを取得
  
set aScheme to "applescript://"
  
set sourceList to getASSouceLinkedInWordPressPost(postID, aURL, aScheme, myUser, myPass) of me
  
  
–AppleScriptのソースをRAM上でコンパイル(構文確認)して、構文色分けしたRTFを取得。RTFの書式情報をparseしてattribute runsと同様のrecordを生成
  
–構文色分けをもとにproperty項目を抽出し、Cocoa Classに該当するもののみを抽出
  
set outList to {}
  
repeat with i in sourceList
    set j to contents of i
    
set anAttrStr to compileASandReturnAttributedString(j) of me
    
set attrRes to getAttributeRunsFromAttrString(anAttrStr) of me
    
set propNames to getPropertyNamesCocoaOnly(cList, attrRes) of me
    
    
if propNames is not equal to {} then
      set outList to outList & propNames
    end if
  end repeat
  
  
–1D Listのユニーク化(重複要素の排除)
  
set aArray to NSArray’s arrayWithArray:outList
  
set bArray to aArray’s valueForKeyPath:"@distinctUnionOfObjects.self"
  
set bList to bArray as list of string or string –as anything
  
  
return bList
end getCocoaPropListFromPost

–Property名称を取得する
on getPropertyNamesCocoaOnly(cList, aRec)
  script spdHnd
    property aRec : {}
  end script
  
  
set (aRec of spdHnd) to aRec
  
  
set targAttr to contents of item 7 of cList –ハンドラあるいは変数
  
set tmpCoStr to ((redValue of targAttr) as string) & " " & ((greenValue of targAttr) as string) & " " & ((blueValue of targAttr) as string)
  
  
set ontoColItem to contents of item 3 of cList –スクリプティング予約語(on/to)
  
set ontoCoStr to ((redValue of ontoColItem) as string) & " " & ((greenValue of ontoColItem) as string) & " " & ((blueValue of ontoColItem) as string)
  
  
  
–変数あるいはハンドラ名称をリストアップ(variables & handler)
  
set tmp1Array to NSArray’s arrayWithArray:(aRec of spdHnd)
  
set thePred0 to NSPredicate’s predicateWithFormat_("colorStr == %@", tmpCoStr)
  
set dArray to (tmp1Array’s filteredArrayUsingPredicate:thePred0) as list
  
  
–改行を含むデータをリストアップ(text data contains return)
  
set thePred1 to NSPredicate’s predicateWithFormat_("stringVal CONTAINS %@", return)
  
set eArray to ((tmp1Array’s filteredArrayUsingPredicate:thePred1)’s valueForKeyPath:"itemIndex") as list
  
  
set the beginning of eArray to 0 –ハンドラ宣言部がTopに来る場合に備える
  
  
–"property"(プロパティ宣言)の項目をリストアップ 文字と色で抽出
  
set thePred2 to NSPredicate’s predicateWithFormat_("stringVal == %@ && colorStr == %@ ", "property", ontoCoStr)
  
set fArray to ((tmp1Array’s filteredArrayUsingPredicate:thePred2)’s valueForKeyPath:"itemIndex") as list
  
  
set handlerList to {}
  
  
–property ではじまるハンドラの抽出
  
repeat with i in eArray –改行を含むテキストのアイテム番号リスト
    set j to (contents of i) as integer
    
repeat with ii in fArray –"on"の項目リスト
      set jj to (contents of ii) as integer
      
      
set handlerStr to missing value
      
      
if (j + 1) = jj then
        set handlerStr to stringVal of (item (jj + 2) of ((aRec of spdHnd) as list))
      else if (j + 2) = jj then
        set handlerStr to stringVal of (item (jj + 2) of ((aRec of spdHnd) as list))
      end if
      
      
set tmpStr to repChar(handlerStr, "|", "") of me
      
      
if tmpStr is not in {"error", missing value} and tmpStr is not in handlerList then
        –抽出したProperty宣言がCocoa Classのものかどうか判定
        
if searchClassInFrameworks(tmpStr) of me is not equal to false then
          set the end of handlerList to tmpStr
        end if
      end if
      
    end repeat
  end repeat
  
  
return handlerList
end getPropertyNamesCocoaOnly

–RAM上にスクリプトエディタと同じ部品を組み立て(非表示)、AppleScriptのソーステキストからObjectを生成し、Attributed Stringデータを返す
on compileASandReturnAttributedString(theSource as string)
  set targX to 1024 –View Width
  
set targY to 2048 –View Height
  
  
set osaCon to current application’s OSAScriptController’s alloc()’s init()
  
set osaView to current application’s OSAScriptView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, targX, targY))
  
  
set resView to NSTextView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, targX, targY))
  
resView’s setRichText:true
  
resView’s useAllLigatures:true
  
  
osaCon’s setScriptView:osaView
  
osaCon’s setLanguage:(OSALanguage’s languageForName:"AppleScript")
  
osaCon’s setResultView:resView
  
  
osaView’s setString:theSource
  
osaCon’s compileScript:(missing value) –Compile(構文確認)
  
  
set aRes to (osaView’s attributedString())
  
  
return aRes
end compileASandReturnAttributedString

–Attributed StringをDictionary化
on getAttributeRunsFromAttrString(theStyledText)
  script aSpd
    property styleList : {}
  end script
  
  
set (styleList of aSpd) to {} —for output
  
  
set thePureString to theStyledText’s |string|() –pure string from theStyledText
  
  
set theLength to theStyledText’s |length|()
  
set startIndex to 0
  
set itemCount to 1
  
  
repeat until (startIndex = theLength)
    set {theAtts, theRange} to theStyledText’s attributesAtIndex:startIndex longestEffectiveRange:(reference) inRange:{startIndex, theLength – startIndex}
    
    
–String  
    
set aText to (thePureString’s substringWithRange:theRange) as string
    
    
–Color
    
set aColor to (theAtts’s valueForKeyPath:"NSColor")
    
if aColor is not equal to missing value then
      set aSpace to aColor’s colorSpace()
      
      
set aRed to (aColor’s redComponent()) * 255
      
set aGreen to (aColor’s greenComponent()) * 255
      
set aBlue to (aColor’s blueComponent()) * 255
      
      
set colList to {aRed as integer, aGreen as integer, aBlue as integer} –for comparison
      
set colStrForFind to (aRed as integer as string) & " " & (aGreen as integer as string) & " " & (aBlue as integer as string) –for filtering
    else
      set colList to {0, 0, 0}
      
set colStrForFind to "0 0 0"
    end if
    
    
–Font
    
set aFont to (theAtts’s valueForKeyPath:"NSFont")
    
if aFont is not equal to missing value then
      set aDFontName to aFont’s displayName()
      
set aDFontSize to aFont’s pointSize()
    end if
    
    
set the end of (styleList of aSpd) to {stringVal:aText, colorStr:colStrForFind, colorVal:colList, fontName:aDFontName as string, fontSize:aDFontSize, itemIndex:itemCount}
    
set startIndex to current application’s NSMaxRange(theRange)
    
    
set itemCount to itemCount + 1
  end repeat
  
  
return (styleList of aSpd)
  
end getAttributeRunsFromAttrString

–指定クラスがいずれかのCocoa Frameworkに所属しているかを検索
on searchClassInFrameworks(aTarget)
  set aClass to current application’s NSClassFromString(aTarget)
  
if aClass = missing value then return false
  
set theComponenents to (NSBundle’s bundleForClass:aClass)’s bundleURL’s pathComponents()
  
set thePred to NSPredicate’s predicateWithFormat:"pathExtension == ’framework’"
  
set aRes to (theComponenents’s filteredArrayUsingPredicate:thePred)’s firstObject() as list of string or string
  
return aRes
end searchClassInFrameworks

–指定Post IDのWordPress記事から、指定SchemeのURLを抽出し、AS Sourceをdecodeしてproperty行のみ抽出
on getASSouceLinkedInWordPressPost(postID, aURL, aScheme, myUser, myPass)
  –call xmlrpc命令に対するURLの間接指定を有効にするために、AppleScriptの構文解釈機能をダミーURLでだます
  
using terms from application "http://piyocast.com/as/xmlrpc.php" –URLと判定されればなんでもいい
    tell application aURL
      set wRes to (call xmlrpc {method name:"wp.getPost", parameters:{"1", myUser, myPass, postID as string}})
    end tell
  end using terms from
  
  
set aBody to post_content of wRes –Blog本文
  
  
–記事中でリンクしているURLを取得し、指定のURL Schemeでフィルタする
  
set urlList to filterURLLinksByScheme(aBody, aScheme) of me
  
  
set propList to {}
  
  
repeat with i in urlList
    set j to contents of i
    
set urlRec to parseQueryDictFromURLString(j) of me
    
set tmpScript to (urlRec’s |script|) as string –Get AppleScript Source
    
    
set propList to propList & tmpScript
  end repeat
  
  
return propList
end getASSouceLinkedInWordPressPost

on parseQueryDictFromURLString(aURLStr as string)
  if aURLStr = "" then error "No URL String"
  
  
set aURL to |NSURL|’s URLWithString:aURLStr
  
set aQuery to aURL’s query() –Get Query string part from URL
  
if aQuery’s |length|() = 0 then return false
  
  
set aDict to NSMutableDictionary’s alloc()’s init()
  
set aParamList to (aQuery’s componentsSeparatedByString:"&") as list
  
  
repeat with i in aParamList
    set j to contents of i
    
if length of j > 0 then
      set tmpStr to (NSString’s stringWithString:j)
      
set eList to (tmpStr’s componentsSeparatedByString:"=")
      
set anElement to (eList’s firstObject()’s stringByReplacingPercentEscapesUsingEncoding:(NSUTF8StringEncoding))
      
set aValStr to (eList’s lastObject()’s stringByReplacingPercentEscapesUsingEncoding:(NSUTF8StringEncoding))
      (
aDict’s setObject:aValStr forKey:anElement)
    end if
  end repeat
  
  
return aDict
end parseQueryDictFromURLString

–指定のHTML文字列から、Link URLを抽出し、schemeで再抽出する
on filterURLLinksByScheme(aBody, aScheme)
  set conType to "text/html"
  
  
–HTML文字列をいったんNSDataにしているのは、HTMLReader.frameworkの仕様のため
  
set aData to (current application’s NSString’s stringWithString:aBody)’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aHTML to current application’s HTMLDocument’s documentWithData:aData contentTypeHeader:conType
  
  
set aTextArray to ((aHTML’s nodesMatchingSelector:"a")’s textContent) as list –リンク文字
  
set aLinkList to ((aHTML’s nodesMatchingSelector:"a")’s attributes’s valueForKeyPath:"href") as list –URL文字列
  
  
set outList to {}
  
repeat with i in aLinkList
    set j to contents of i
    
if j begins with aScheme then
      set the end of outList to j
    end if
  end repeat
  
  
return outList
end filterURLLinksByScheme

–文字置換
on repChar(origText as string, targChar as string, repChar as string)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to targChar
  
set tmpList to text items of origText
  
set AppleScript’s text item delimiters to repChar
  
set retText to tmpList as string
  
set AppleScript’s text item delimiters to curDelim
  
return retText
end repChar

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

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

–AS書式で配色に重複がないかどうかチェック
on chkASLexicalFormatColorConfliction(aList)
  set anArray to current application’s NSArray’s arrayWithArray:aList
  
set bList to (anArray’s valueForKeyPath:"redValue.stringValue") as list
  
set cList to (anArray’s valueForKeyPath:"greenValue.stringValue") as list
  
set dList to (anArray’s valueForKeyPath:"blueValue.stringValue") as list
  
  
set colStrList to {}
  
repeat with i from 1 to (length of bList)
    set bItem to contents of item i of bList
    
set cItem to contents of item i of cList
    
set dItem to contents of item i of dList
    
set the end of colStrList to bItem & " " & cItem & " " & dItem
  end repeat
  
  
set aRes to returnDuplicatesOnly(colStrList) of me
  
if aRes is equal to {} then
    return true –重複が存在しなかった場合
  else
    return false –重複があった場合
  end if
end chkASLexicalFormatColorConfliction

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

on getAcountData()
  return {"xxxxxxxx_xx", "XXXXXXXXXXXXXXXXXXXXXXXX"} –user name, password
end getAcountData

★Click Here to Open This Script 

Posted in list OSA RTF Text URL XML-RPC | Tagged 10.11savvy 10.12savvy 10.13savvy NSArray NSBundle NSDictionary NSMutableArray NSMutableDictionary NSPredicate NSString NSTextView NSThread NSUnarchiver OSALanguage OSALanguageInstance OSAScript OSAScriptController OSAScriptView | Leave a comment

Google Drive File StreamのドライブでSpotlight Indexを生成

Posted on 8月 4, 2018 by Takaaki Naganoya

Google Drive File Stream上でSpotlight Indexを生成するAppleScriptです。

Google Driveには、Gmailのオマケでついてくる個人のデバイス間で情報のシンクロを行う目的のPersonal版(DropboxのGoogle版的なもの)と、企業内やグループ内でファイル共有を行うG SuiteのGoodle Drive File Streamがあり、後者についてはGoogleによる「Google Drive File Stream」ツールが提供され、GoogleDriveをデスクトップにマウントできます。

実際にGoogle Drive File Streamを使ってみたところ、デフォルト状態だとSpotlight検索が効きませんでした。

そこで、Index生成してみたものの…既存のファイルについてはSpotlight検索できませんでした。Index生成後に、新規追加したファイルについてはSpotlight検索が有効でした。

後日談:ただ、Google Drive File Streamに対してSpotlight Indexを常時生成するようにすると、CPUに対する負荷が大きくなるため、実際の運用ではSpotlightを無効にして運用するようにしました。

AppleScript名:Google Drive File Streamでインデックス生成
do shell script "mdutil -E /Volumes/GoogleDrive/" with administrator privileges

★Click Here to Open This Script 

自分が試したのは、Google Drive File Stream内の「マイドライブ」領域のみで、

「グループドライブ」領域についてはまだテストできていません。

既存のファイルについては、mdimportコマンドでインデックス作成すれば大丈夫だと思っていますが、実際に試してみると予想外の挙動を行うのかもしれません。

AppleScript名:GDFS上でSpotlight検索
— Created 2016-06-17 by Takaaki Naganoya
— 2016 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

property NSArray : a reference to current application’s NSArray
property NSPredicate : a reference to current application’s NSPredicate
property NSSortDescriptor : a reference to current application’s NSSortDescriptor
property NSMetadataQuery : a reference to current application’s NSMetadataQuery
property NSNotificationCenter : a reference to current application’s NSNotificationCenter
property NSMetadataQueryDidUpdateNotification : a reference to current application’s NSMetadataQueryDidUpdateNotification
property NSMetadataQueryDidFinishGatheringNotification : a reference to current application’s NSMetadataQueryDidFinishGatheringNotification

property searchRes : {}

set origPath to POSIX path of (choose folder)
set aList to spotlightSearch(origPath, "kMDItemContentType == ’public.png’") of me

on spotlightSearch(origPath, aMDfindParam)
  
  
set my searchRes to {} –initialize
  
initiateSearchForFullPath(aMDfindParam, origPath) –Predicate & Scope Directory
  
  
–Waiting for the result
  
repeat while my searchRes = {}
    delay 0.01
  end repeat
  
  
set anObj to my searchRes’s firstObject() –Pick up the first one for test
  
if anObj = missing value then return {} –No Result
  
  
set resArray to {}
  
repeat with anItem in my searchRes
    set j to contents of anItem
    
set aPath to (j’s valueForAttribute:"kMDItemPath") as string
    
set the end of resArray to aPath
  end repeat
  
  
return resArray
  
end spotlightSearch

on initiateSearchForFullPath(aQueryStrings, origPath)
  
  
set aSearch to NSMetadataQuery’s alloc()’s init()
  
  
NSNotificationCenter’s defaultCenter()’s addObserver:(me) selector:"queryDidUpdate:" |name|:(NSMetadataQueryDidUpdateNotification) object:aSearch
  
NSNotificationCenter’s defaultCenter()’s addObserver:(me) selector:"initalGatherComplete:" |name|:(NSMetadataQueryDidFinishGatheringNotification) object:aSearch
  
  
set aPredicate to NSPredicate’s predicateWithFormat:aQueryStrings
  
aSearch’s setPredicate:aPredicate
  
  
set aScope to NSArray’s arrayWithObjects:{origPath}
  
aSearch’s setSearchScopes:aScope
  
  
set sortKeys to NSSortDescriptor’s sortDescriptorWithKey:"kMDItemFSName" ascending:true
  
aSearch’s setSortDescriptors:(NSArray’s arrayWithObject:sortKeys)
  
  
aSearch’s startQuery()
  
end initiateSearchForFullPath

on queryDidUpdate:sender
  log sender
  
–> (NSConcreteNotification) NSConcreteNotification 0x7fa618450820 {name = NSMetadataQueryDidFinishGatheringNotification; object = <NSMetadataQuery: 0x7fa6172c6ca0>}
end queryDidUpdate:

on initalGatherComplete:sender
  set anObject to sender’s object
  
anObject’s stopQuery()
  
NSNotificationCenter’s defaultCenter()’s removeObserver:me |name|:(NSMetadataQueryDidUpdateNotification) object:anObject
  
NSNotificationCenter’s defaultCenter()’s removeObserver:me |name|:(NSMetadataQueryDidFinishGatheringNotification) object:anObject
  
  
set my searchRes to anObject’s results()
end initalGatherComplete:

★Click Here to Open This Script 

Posted in drive file shell script Spotlight | Tagged 10.12savvy NSArray NSMetadataQuery NSNotificationCenter NSPredicate NSSortDescriptor | Leave a comment

WordPressの指定IDの記事にリンクされているapplescriptからCocoa Classのproperty宣言を抽出

Posted on 7月 30, 2018 by Takaaki Naganoya

WordPressで稼働しているBlog(AppleScriptの穴)の、指定記事IDの本文を取得し、本文内でリンクしているURLのうち指定schemeのものを抽出し、URLリンクされているAppleScriptのソースをデコードしてproperty宣言文のうちCocoa Classの宣言を行っているものを抽出するAppleScriptです。

HTMLReader.frameworkを用いてBlog本文からのリンク抽出、リンクURL抽出を行っています。

–> HTMLReader.framework(To ~/Library/Frameworks/)

本Blogで、Tagの運用を変更しようと思い立ち、手作業で修正をはじめました。アプリケーション名のほかにCocoa Class名をTagにしようという試みです。

ただ、数個の記事のTag付け直しを行っただけで「手作業では終わらない」ことが判明。2月に再構築をはじめて1,000本ぐらいの記事をアップしているので、手作業ではとても無理です

本Blogの記事にURLリンクされているAppleScriptソースプログラムを(XML-RPC経由で)AppleScriptから自動で取得し、

その中のproperty宣言文を抽出して、

Cocoa Classの宣言文のみをリストアップして、

Blog記事のTagに自動で指定できないか、と試してみたものです。

現時点で、

  (1)指定Blog記事の本文を取得
  (2)(1)から指定URL SchemeのリンクURLを抽出
  (3)(2)のURL EncodeされているAppleScriptソースをDecode
  (4)property宣言文のみ抽出
  (5)property宣言ラベルがCocoa Classのものかをチェックして抽出

というところまでできています。本プログラムは、BlogのUser NameとPasswordが必要なので、リストのまま動かしてもエラーになり動作しません。同様にWordPressで運用されているBlogがあれば、そちらで試してみるのもよいでしょう。

XML-RPCでWordPressと通信するのには、記事アップロード自動化に使ったFrameworkもありますが、ためしにAppleScript標準搭載のcall xmlrpcコマンドを使ってみました。記事新規投稿コマンドだとクラッシュを起こしますが、この程度の用途ならクラッシュせずに使えるようです。

また、property文の抽出は構文要素を考慮していないため、コメントアウトされているものも拾ってくる可能性があります(単に行頭のproperty宣言文を拾っているだけなので、複数行コメントになっているものは拾われてくることでしょう)。

(*
property NSArray: a reference to current application’s NSArray
property NSString: a reference to current application’s NSString
*)

これを防ぐために、URLリンクされたAppleScriptをデコードした後で、いったんAppleScriptとして構文確認(コンパイル)を実施して、実際のAppleScriptとして評価すべきなのでしょう。

AppleScript名:WordPressの指定IDの記事にリンクされているapplescriptからCocoa Classのproperty宣言を抽出 v2
— Created 2018-07-30 by Takaaki Naganoya
— Modified 2018-07-31 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "HTMLReader" –https://github.com/nolanw/HTMLReader

property |NSURL| : a reference to current application’s |NSURL|
property NSString : a reference to current application’s NSString
property NSBundle : a reference to current application’s NSBundle
property NSPredicate : a reference to current application’s NSPredicate
property NSDictionary : a reference to current application’s NSDictionary
property NSMutableArray : a reference to current application’s NSMutableArray
property NSMutableDictionary : a reference to current application’s NSMutableDictionary
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding

–PostID
set postID to 3826
set aScheme to "applescript://"

–WordPressの指定Post IDの記事を取得してリンクされているURLからURL Schemeでフィルタして、リンクされているAppleScriptのソースを
–取得し、AS Sourceからproperty宣言文のみ抽出
set pList to getASSouceLinkedInWordPressPost(postID, aScheme) of me
–>  {"property NSBundle : a reference to current application’s NSBundle", "property |NSURL| : a reference to current application’s |NSURL|", "property HTMLDocument : a reference to current application’s HTMLDocument", "property NSMutableDictionary : a reference to current application’s NSMutableDictionary", "property NSPredicate : a reference to current application’s NSPredicate", "property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding", "property NSMutableSet : a reference to current application’s NSMutableSet", "property NSRegularExpressionSearch : a reference to current application’s NSRegularExpressionSearch", "property NSString : a reference to current application’s NSString", "property NSSortDescriptor : a reference to current application’s NSSortDescriptor"}

–property宣言文リストから、propetyがCocoa Classの宣言であるものだけを抽出
set p2List to filterPropertySentenseWhetherCocoaOrNot(pList) of me
–>  {"NSBundle", "HTMLDocument", "NSMutableDictionary", "NSPredicate", "NSMutableSet", "NSString", "NSSortDescriptor"}

on filterPropertySentenseWhetherCocoaOrNot(pList)
  set outList to {}
  
  
repeat with i in pList
    set j to contents of i
    
set j2 to repChar(j, "|", "") of me
    
    
–Parse String Into Words by Space
    
set aTmpStr to (NSString’s stringWithString:j2)
    
set wList to (aTmpStr’s componentsSeparatedByString:" ") as list
    
    
if wList contains {"a", "reference", "to", "current", "application’s"} then
      –通常のクラス名の場合(クラス名以外のpropertyの場合もある)
      
set aTarg to contents of item 2 of wList
      
      
–property値がCocoa Classかどうかを判定    
      
set fRes to searchClassInFrameworks(aTarg) of me
      
      
if fRes is not equal to false then
        set the end of outList to aTarg
      end if
    end if
  end repeat
  
  
return outList
end filterPropertySentenseWhetherCocoaOrNot

–指定クラスがいずれかのCocoa Frameworkに所属しているかを検索
on searchClassInFrameworks(aTarget)
  set aClass to current application’s NSClassFromString(aTarget)
  
if aClass = missing value then return false
  
set theComponenents to (NSBundle’s bundleForClass:aClass)’s bundleURL’s pathComponents()
  
set thePred to NSPredicate’s predicateWithFormat:"pathExtension == ’framework’"
  
set aRes to (theComponenents’s filteredArrayUsingPredicate:thePred)’s firstObject() as list of string or string
  
return aRes
end searchClassInFrameworks

–指定Post IDのWordPress記事から、指定SchemeのURLを抽出し、AS Sourceをdecodeしてproperty行のみ抽出
on getASSouceLinkedInWordPressPost(postID, aScheme)
  set {myUser, myPass} to getAcountData() of me
  
  
tell application "http://piyocast.com/as/xmlrpc.php"
    set wRes to (call xmlrpc {method name:"wp.getPost", parameters:{"1", myUser, myPass, postID as string}})
  end tell
  
set aBody to post_content of wRes –Blog本文
  
  
–記事中でリンクしているURLを取得し、指定のURL Schemeでフィルタする
  
set urlList to filterURLLinksByScheme(aBody, aScheme) of me
  
  
set propList to {}
  
  
repeat with i in urlList
    set j to contents of i
    
set urlRec to parseQueryDictFromURLString(j) of me
    
set tmpScript to (urlRec’s |script|) as string –Get AppleScript Source
    
    
set tList to paragraphs of tmpScript
    
set pList to filterListUsingPredicate(tList, "SELF BEGINSWITH[c] %@", "property") –後方一致
    
    
set propList to propList & pList
  end repeat
  
  
return propList
end getASSouceLinkedInWordPressPost

on filterListUsingPredicate(aList as list, aPredicateStr as string, targStr as string)
  set setKey to current application’s NSMutableSet’s setWithArray:aList
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat_(aPredicateStr, targStr)
  
set aRes to (setKey’s filteredSetUsingPredicate:aPredicate)
  
set bRes to aRes’s allObjects()
  
set cRes to bRes as {list, list of string or string}
  
return cRes
end filterListUsingPredicate

on parseQueryDictFromURLString(aURLStr as string)
  if aURLStr = "" then error "No URL String"
  
  
set aURL to |NSURL|’s URLWithString:aURLStr
  
set aQuery to aURL’s query() –Get Query string part from URL
  
if aQuery’s |length|() = 0 then return false
  
  
set aDict to NSMutableDictionary’s alloc()’s init()
  
set aParamList to (aQuery’s componentsSeparatedByString:"&") as list
  
  
repeat with i in aParamList
    set j to contents of i
    
if length of j > 0 then
      set tmpStr to (NSString’s stringWithString:j)
      
set eList to (tmpStr’s componentsSeparatedByString:"=")
      
set anElement to (eList’s firstObject()’s stringByReplacingPercentEscapesUsingEncoding:(NSUTF8StringEncoding))
      
set aValStr to (eList’s lastObject()’s stringByReplacingPercentEscapesUsingEncoding:(NSUTF8StringEncoding))
      (
aDict’s setObject:aValStr forKey:anElement)
    end if
  end repeat
  
  
return aDict
end parseQueryDictFromURLString

–指定のHTML文字列から、Link URLを抽出し、schemeで再抽出する
on filterURLLinksByScheme(aBody, aScheme)
  set conType to "text/html"
  
  
–HTML文字列をいったんNSDataにしているのは、HTMLReader.frameworkの仕様のため
  
set aData to (current application’s NSString’s stringWithString:aBody)’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aHTML to current application’s HTMLDocument’s documentWithData:aData contentTypeHeader:conType
  
  
set aTextArray to ((aHTML’s nodesMatchingSelector:"a")’s textContent) as list –リンク文字
  
set aLinkList to ((aHTML’s nodesMatchingSelector:"a")’s attributes’s valueForKeyPath:"href") as list –URL文字列
  
  
set outList to {}
  
repeat with i in aLinkList
    set j to contents of i
    
if j begins with aScheme then
      set the end of outList to j
    end if
  end repeat
  
  
return outList
end filterURLLinksByScheme

–文字置換
on repChar(origText as string, targChar as string, repChar as string)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to targChar
  
set tmpList to text items of origText
  
set AppleScript’s text item delimiters to repChar
  
set retText to tmpList as string
  
set AppleScript’s text item delimiters to curDelim
  
return retText
end repChar

on getAcountData()
  return {"xxxxxxxx_xx", "XXXXXXXXXXXXXXXXXXXXXXXX"}
end getAcountData

★Click Here to Open This Script 

Posted in list Network Record URL XML-RPC | Tagged 10.11savvy 10.12savvy 10.13savvy NSArray NSBundle NSString NSURL | Leave a comment

Finder上で選択中の画像のうち、最小のものに合わせて各画像の左上を原点にサイズ統一

Posted on 7月 27, 2018 by Takaaki Naganoya

Finderで選択中の画像のうち、最小のものに合わせて各画像の左上を原点にサイズを統一するAppleScriptです。

Finderで選択中のファイルから画像のみ抽出し、そのうちサイズが最小のものに合わせて他の画像をトリミングし、変更したものをデスクトップフォルダに出力します。


▲大きさを揃える画像をFinder上で選択


▲処理前の画像。大きさがまちまち


▲処理後の画像。大きさが最小の画像に合わせてそろっている

スクリーンショット画像を複数撮った場合に、厳密に同じサイズに固定することは(各種スクリーンショット作成ユーティリティを使わないと)行いづらいところです。

そこで、最小の画像を計算で求めて、それに合わせて自動トリミングするようにしてみました。Cocoaの機能を用いて画像処理しているため、Photoshopは必要ありません。

最小の画像を求めるのに、幅+高さの値でソートして最小のものを求めています(widthとheightによる2 key sortではなく1 Keyで済ませたかったので)。

Blogや書籍用の掲載画面図の作成用、といったところでしょうか。Retina画面で撮ったスクリーンショットと非Retina画面のスクリーンショットが混在するとうまく動きません(スクリーンショット画像からはRetina環境で撮った画像であるかどうかを取得できません)。

スクリーンショットの画像からRetina/非Retina環境で撮ったかを判定するのは、(Retina対応機であるかをMachine IDから取得したあとで)Syslogにアクセスしてスクリーンが接続されたか、取り外されたかといった状態を追っていくしかないのかも。

本ScriptをmacOS 10.13.6上で動作確認して驚いたのですが、いままでRecordが返ってくるべき箇所でlistが返ってくる盛大なバグが直って、本ScriptがmacOS 10.13用に書き換えずに動きました(動かないことを確認しようとして動いたので驚いた)。

AppleScript名:Finder上で選択中の画像のうち、最小のものに合わせて各画像の左上を原点にサイズ統一 v2
— Created 2018-07-23 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "QuartzCore"

property |NSURL| : a reference to current application’s |NSURL|
property NSUUID : a reference to current application’s NSUUID
property NSArray : a reference to current application’s NSArray
property NSString : a reference to current application’s NSString
property NSImage : a reference to current application’s NSImage
property NSScreen : a reference to current application’s NSScreen
property NSZeroRect : a reference to current application’s NSZeroRect
property NSPredicate : a reference to current application’s NSPredicate
property NSPNGFileType : a reference to current application’s NSPNGFileType
property NSMutableArray : a reference to current application’s NSMutableArray
property NSCompositeCopy : a reference to current application’s NSCompositeCopy
property NSGraphicsContext : a reference to current application’s NSGraphicsContext
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep
property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey
property NSCalibratedRGBColorSpace : a reference to current application’s NSCalibratedRGBColorSpace

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

–指定のAlias listのうち画像のみ抽出
set filRes1 to filterAliasListByUTI(selList, "public.image") of me
if filRes1 = {} then
  tell current application
    –Error Message (No Selection)
    
display dialog "Finder上で選択されているファイルはありません。" buttons {"OK"} default button 1 with icon 1 with title "画像リサイズ処理できません"
  end tell
  
return
end if

–各種情報を入れたArrayを作成
set anArray to NSMutableArray’s new()
repeat with i in selList
  set imgPath to (POSIX path of i)
  
  
set aImage to makeNSImageFromFile(i) of me
  
set sizeInfo to |size|() of aImage
  
set sizeInfo to sizeInfo & {aImg:aImage, total:(width of sizeInfo) + (height of sizeInfo), myPath:imgPath}
  (
anArray’s addObject:sizeInfo)
end repeat

–最小のサイズの画像の算出
set aRes to anArray’s valueForKeyPath:("@min.total")
set bRes to first item of (filterRecListByLabel(anArray, "total == " & aRes as string) of me) –最小サイズの画像

–最小サイズ画像のwidthとheight
set minWidth to bRes’s width
set minHeight to bRes’s height

–環境情報の取得
set aPath to POSIX path of (path to desktop)
set retinaF to (NSScreen’s mainScreen()’s backingScaleFactor()) as real
–>  2.0 (Retina) / 1.0 (Non Retina)

set cRes to filterRecListByLabel(anArray, "total != " & aRes as string) of me –最小サイズ以外の画像

repeat with i in cRes
  set j to contents of i
  
set anImage to aImg of j
  
set fRes to myPath of j
  
  
set cropedImage to (my cropNSImageBy:{0, 0, minWidth, minHeight} fromImage:anImage) –v1で間違っていた
  
  
–Retina環境対策
  
if retinaF > 1.0 then
    set cropedImage to (my resizedImage:cropedImage toScale:(1.0))
  end if
  
  
–ファイル書き込み
  
set fRes to retUUIDfilePathFromDir(aPath, "png") of me
  
set sRes to saveNSImageAtPathAsPNG(cropedImage, fRes) of me
end repeat

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

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

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

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

on cropNSImageTo:{x1, y1, x2, y2} fromImage:theImage
  set newWidth to x2 – x1
  
set newHeight to y2 – y1
  
set theSize to (theImage’s |size|()) as record
  
set oldHeight to height of theSize
  
  
— transpose y value for Cocoa coordintates
  
set y1 to oldHeight – newHeight – y1
  
set newRect to {{x:x1, y:y1}, {width:newWidth, height:newHeight}}
  
theImage’s lockFocus()
  
set theRep to NSBitmapImageRep’s alloc()’s initWithFocusedViewRect:newRect
  
theImage’s unlockFocus()
  
  
set outImage to NSImage’s alloc()’s initWithSize:(theRep’s |size|())
  
outImage’s addRepresentation:theRep
  
  
return outImage
end cropNSImageTo:fromImage:

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

–NSImageを指定の大きさでトリミング
on cropNSImageBy:{x1, y1, newWidth, newHeight} fromImage:theImage
  set theSize to (theImage’s |size|()) as record
  
set oldHeight to height of theSize
  
  
— transpose y value for Cocoa coordintates
  
set y1 to oldHeight – newHeight – y1
  
set newRect to {{x:x1, y:y1}, {width:newWidth, height:newHeight}}
  
theImage’s lockFocus()
  
set theRep to NSBitmapImageRep’s alloc()’s initWithFocusedViewRect:newRect
  
theImage’s unlockFocus()
  
  
set outImage to NSImage’s alloc()’s initWithSize:(theRep’s |size|())
  
outImage’s addRepresentation:theRep
  
  
return outImage
end cropNSImageBy:fromImage:

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

–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

on resizedImage:aSourceImg toScale:imgScale
  if (aSourceImg’s isValid()) as boolean = false then error "Invalid NSImage"
  
  
set aSize to aSourceImg’s |size|()
  
–>  {​​​​​width:32.0, ​​​​​height:32.0​​​}
  
  
set aWidth to (aSize’s width) * imgScale
  
set aHeight to (aSize’s height) * imgScale
  
  
set aRep to NSBitmapImageRep’s alloc()’s initWithBitmapDataPlanes:(missing value) pixelsWide:aWidth pixelsHigh:aHeight bitsPerSample:8 samplesPerPixel:4 hasAlpha:true isPlanar:false colorSpaceName:(NSCalibratedRGBColorSpace) bytesPerRow:0 bitsPerPixel:0
  
  
set newSize to {width:aWidth, height:aHeight}
  
aRep’s setSize:newSize
  
  
NSGraphicsContext’s saveGraphicsState()
  
NSGraphicsContext’s setCurrentContext:(NSGraphicsContext’s graphicsContextWithBitmapImageRep:aRep)
  
  
aSourceImg’s drawInRect:(current application’s NSMakeRect(0, 0, aWidth, aHeight)) fromRect:(NSZeroRect) operation:(NSCompositeCopy) fraction:(1.0)
  
  
NSGraphicsContext’s restoreGraphicsState()
  
  
set newImg to NSImage’s alloc()’s initWithSize:newSize
  
newImg’s addRepresentation:aRep
  
  
return newImg
end resizedImage:toScale:

★Click Here to Open This Script 

Posted in file Image | Tagged 10.11savvy 10.12savvy 10.13savvy Finder NSArray NSBitmapImageRep NSImage NSMutableArray NSPredicate NSScreen NSString NSURL NSUUID | 1 Comment

先頭からn個目までのターゲット文字を個別置換

Posted on 7月 25, 2018 by Takaaki Naganoya

置換ターゲット文字が複数存在する場合に、先頭からn個目までの置換ターゲットを個別に文字指定して置換するAppleScriptです。


▲行頭のスペースは削除(ヌル文字列に置換)、2個目のスペースはtabに置換したい


▲置換ずみ

Cocoaの機能を使って(作りためたサブルーチンを流用して)書いてみたら、トンでもなく長くなってしまったので、あらためてOLD Style AppleScriptの機能範囲だけでコンパクトに書き直したものです。

このぐらいの(↑)のどかな分量のデータに対してシーケンシャルに(文字を1文字ずつ取り出して比較&置換)処理を行うものなので、高速化などは一切考慮していません。大規模データにはまったく別のアプローチを行うことをおすすめします。

AppleScript名:先頭からn個目までのターゲット文字を個別指定した文字に置換
— Created 2018-07-23 by Takaaki Naganoya
— 2018 Piyomaru Software
— This script runs on OS X 10.10 or later
use scripting additions
use framework "Foundation"

set origStr to " aaaaa bbbb cccccc dddddd"
set repTarget to " "
set repList to {"", tab} –1個めのスペースは削除、2個めのスペースはtabに置換
set rStr to repLimitedOrderStrByList(origStr, repTarget, repList) of me

on repLimitedOrderStrByList(allText as string, targChar as string, repList)
  set repParam to length of repList
  
set itemCounter to 1
  
set outStr to ""
  
  
set bList to characters of allText
  
  
repeat with ii in bList
    set jj to contents of ii
    
if jj = targChar then
      
      
if repParam > 0 then
        set aRepStr to contents of item itemCounter of repList
        
set outStr to outStr & aRepStr
        
set repParam to repParam – 1
        
set itemCounter to itemCounter + 1
      else
        set outStr to outStr & jj
      end if
      
    else
      set outStr to outStr & jj
    end if
  end repeat
  
  
return outStr
end repLimitedOrderStrByList

★Click Here to Open This Script 

Posted in Text | Leave a comment

AppleScriptイベント「Think AppleScript」(仮称)を開催します

Posted on 7月 23, 2018 by Takaaki Naganoya

MOSAとの共催により、AppleScriptに関するイベント、「Think AppleScript」(仮称)を開催する予定です。

MOSA+Piyomaru Software共催
AppleScriptイベント「Think AppleScript」(仮称)

開催日時:2018年9月26日(水)19:00〜22:00(予定)
開催場所(予定):池袋Open Office FOREST
東京都豊島区東池袋3-7-9 AS ONE 東池袋ビル3階
参加費用:3階受付にて、個別にナイトドロップイン(1.000円)のチケットをご購入ください

・AppleScriptについてのイベントです。情報共有、質疑応答などを目的とします
・AppleScriptの歴史と位置づけ、拡大する利用範囲についてのご紹介
・海外の動向などのご紹介
・事例紹介など
・来場者からの質問をみんなで考える「Q&A」
・AppleScriptに関するものであれば、著作、Blog、製品、導入事例などどんどん紹介してください! 大歓迎です!(事前に言っていただければ時間枠など最大限配慮いたします。すでに知り合い筋に事例の発表を依頼しています)
→ ただし、出席者からの内容についての質問は可能なかぎりお答えください

受付フォームについてはconnpass上に作成いたします(まだ間に合っていません)。

定期的に(3か月に一度ぐらい?)開催できるといいですね、、、、

Posted in イベント(Event) | Leave a comment

note.muで指定のユーザーのノートを取得する

Posted on 7月 22, 2018 by Takaaki Naganoya

note.muの非公開REST API(でも、みんな知っている)を呼び出して、指定ユーザーのノート(投稿記事)を取得するAppleScriptです。

使い慣れたNSURLConnectionがmacOS 10.11で非推奨APIになって久しく、頻繁に使っているREST API呼び出し処理がいきなり動かなくなるのは困るため、NSURLSessionを用いてREST APIを呼び出すよう徐々に変更しています。

当初、REST APIの呼び出し部分は共通ルーチン化して、さまざまなREST APIを共通ルーチンで処理できるとよいだろうかと思っていました。実際にさまざまなREST APIを呼び出してみると、APIごとに意外なほど癖があって、なかなか「すべてのREST APIの共通処理ルーチン」というところまで共通化する段階までには至っていないところ。

左がNSURLSessionを用いた呼び出し、右がNSURLConnectionを用いた呼び出しを行なったものです。せっかくNSURLSessionを使ってみてはいるものの、同一の処理でもNSURLConnectionの方が40%ぐらい高速です。同一ネットワーク環境(iPhone経由のテザリング接続)でNSURLConnectionが0.4秒ぐらい、NSURLSessionでだいたい0.5から0.7秒といったところ。有線ネットワーク接続だともう少し速度が改善するかもしれません。

NSURLSessionに明示的な同期処理が存在しないため、NSURLSessionが受けわたすdelegateイベントをAppleScript側でループしつつ待っており、NSURLConnectionで素直に同期処理メソッドを呼び出すよりもオーバーヘッドが大きくなっているものと推測しています。

NSURLSessionでREST APIを呼び出すあたりの処理をまるごと独立したFrameworkにでも追い出すとよいのではないか、といったところです。

AppleScript名:(GET)指定のユーザーのノート v2
— Created 2018-06-16 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

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

property retData : missing value

set retData to missing value

set reqURLStr to "https://note.mu/api/v1/notes"
set aRec to {urlname:"140software"} –note ID
set aURL to retURLwithParams(reqURLStr, aRec) of me

set aRESTres to callRestGETAPIAndParseResults(aURL) of me

on callRestGETAPIAndParseResults(reqURLStr)
  set aURL to |NSURL|’s URLWithString:reqURLStr
  
set aRequest to NSMutableURLRequest’s requestWithURL:aURL
  
aRequest’s setHTTPMethod:"GET"
  
aRequest’s setTimeoutInterval:10
  
aRequest’s setValue:"gzip" forHTTPHeaderField:"Content-Encoding"
  
aRequest’s setValue:"application/json; charset=UTF-8" forHTTPHeaderField:"Content-Type"
  
  
set aConfig to NSURLSessionConfiguration’s defaultSessionConfiguration()
  
set aSession to NSURLSession’s sessionWithConfiguration:aConfig delegate:(me) delegateQueue:(missing value)
  
set aTask to aSession’s dataTaskWithRequest:aRequest
  
  
aTask’s resume() –Start URL Session
  
  
repeat 10000 times
    if retData is not equal to missing value then exit repeat
    
current application’s NSThread’s sleepForTimeInterval:("0.001" as real) –delay 0.001
  end repeat
  
  
retData
end callRestGETAPIAndParseResults

on URLSession:tmpSession dataTask:tmpTask didReceiveData:tmpData
  set aStat to (tmpTask’s state()) as list of string or string
  
  
set resStr to NSString’s alloc()’s initWithData:tmpData encoding:(NSUTF8StringEncoding)
  
set jsonString to NSString’s stringWithString:(resStr)
  
  
set jsonData to jsonString’s dataUsingEncoding:(NSUTF8StringEncoding)
  
set aJsonDict to NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
  
set retData to aJsonDict as list of string or string
end URLSession:dataTask:didReceiveData:

on retURLwithParams(aBaseURL, aRec)
  set aDic to current application’s NSMutableDictionary’s dictionaryWithDictionary:aRec
  
set aKeyList to (aDic’s allKeys()) as list
  
set aValList to (aDic’s allValues()) as list
  
set aLen to length of aKeyList
  
  
set qList to {}
  
repeat with i from 1 to aLen
    set aName to contents of item i of aKeyList
    
set aVal to contents of item i of aValList
    
set the end of qList to (current application’s NSURLQueryItem’s queryItemWithName:aName value:aVal)
  end repeat
  
  
set aComp to current application’s NSURLComponents’s alloc()’s initWithString:aBaseURL
  
aComp’s setQueryItems:qList
  
set aURL to (aComp’s |URL|()’s absoluteString()) as text
  
  
return aURL
end retURLwithParams

★Click Here to Open This Script 

Posted in JSON list REST API URL | Tagged 10.11savvy 10.12savvy 10.13savvy NSJSONSerialization NSMutableURLRequest NSString NSURL NSURLSession NSURLSessionConfiguration NSUTF8StringEncoding | 1 Comment

色付き単色画像を作成する(自由色指定&色名推定)

Posted on 7月 17, 2018 by Takaaki Naganoya

指定画像を任意の色で単色化し、指定色名をファイル名に反映させてファイル出力するAppleScriptです。

もとは、「色付き単色画像を作成する」AppleScriptに、

 ・choose colorによるユーザー選択色を反映
 ・choose colorで指定した色のざっくりとした色名検出

などの機能をつなぎ合わせたものです。

日本地図の白地図からカラーバリエーション画像を出力する際に作成しました。線が黒で書かれている白地図(白地図というのはそういうものですが)から、さまざまな色のバリエーションを作成。その際に、どのような色を指定したかをファイル名に反映させておいたほうが便利だったので、そのようにしてみました。

GPUImage.frameworkを利用しています。

–> GPUImage.framework (To ~/Library/Frameworks/)

色名推定のロジックもけっこうしっくりきていますが、明度も反映して、明るいものは「light-」、暗いものは「dark-」と出力させてもいいような気がします。ただし、「dark-orange」はBrownのことですし、ほかにも色名を別途振り直したほうがいいパターンもあるように思われます。

AppleScript名:色付き単色画像を作成する(自由色指定&色名推定)
— Created 2017-02-11 by Takaaki Naganoya
— Modified 2018-07-15 by Takaaki Naganoya
— 2017-2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "GPUImage" –https://github.com/BradLarson/GPUImage

property NSUUID : a reference to current application’s NSUUID
property NSColor : a reference to current application’s NSColor
property NSString : a reference to current application’s NSString
property NSImage : a reference to current application’s NSImage
property NSBezierPath : a reference to current application’s NSBezierPath
property NSPNGFileType : a reference to current application’s NSPNGFileType
property GPUImagePicture : a reference to current application’s GPUImagePicture
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep

–Select Image File
set aFile to POSIX path of (choose file of type {"public.image"} with prompt "Select image")

–Select Color
set {rCol, gCol, bCol} to choose color

set fillColorR to makeNSColorFromRGBAval(rCol, gCol, bCol, 65535, 65535) of me
set fillColorRName to retColorDomainNameFromNSColor(fillColorR) of me –だいたいの色名称を計算

set imgRes to makeMonoColoredImage(aFile, fillColorR) of me
set fRes to retUUIDandKeyfilePath(aFile, fillColorRName, "png") of me
set bRes to saveNSImageAtPathAsPNG(imgRes, fRes) of me

— return "UUID_aKey.aEXT" full path
on retUUIDandKeyfilePath(aPath, aKey, aEXT)
  set aUUIDstr to ((NSUUID’s UUID()’s UUIDString()) as string) & "_" & aKey
  
set aPath to ((NSString’s stringWithString:aPath)’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:aEXT
  
return aPath
end retUUIDandKeyfilePath

on makeMonoColoredImage(aFile, NScolorObj)
  set aImage to NSImage’s alloc()’s initWithContentsOfFile:aFile
  
return makeColoredNSImageWithColor(aImage, NScolorObj) of me –色付き単色画像を作成する
end makeMonoColoredImage

on makeColoredNSImageWithColor(aImage, fillColor)
  set aSize to aImage’s |size|()
  
set aWidth to width of aSize
  
set aHeight to height of aSize
  
set newNSImage to makeNSImageWithFilledWithColor(aWidth, aHeight, fillColor)
  
set grayImage to filterWithNSImage(aImage, "GPUImageGrayscaleFilter") of me
  
set compImage to composeImageWithBlendFilter(grayImage, newNSImage, "GPUImageScreenBlendFilter") of me
  
return compImage
end makeColoredNSImageWithColor

on filterWithNSImage(aNSImage, filterName as string)
  set aClass to current application’s NSClassFromString(filterName)
  
set aImageFilter to aClass’s alloc()’s init()
  
set aProcImg to (aImageFilter’s imageByFilteringImage:aNSImage)
  
return aProcImg
end filterWithNSImage

on composeImageWithBlendFilter(aImage, bImage, filterName)
  set aClass to current application’s NSClassFromString(filterName)
  
set blendFilter to aClass’s alloc()’s init()
  
set pictureA to GPUImagePicture’s alloc()’s initWithImage:aImage
  
pictureA’s addTarget:blendFilter
  
pictureA’s processImage()
  
set imgRes to blendFilter’s imageByFilteringImage:bImage
  
return imgRes
end composeImageWithBlendFilter

–指定サイズの画像を作成し、指定色で塗ってNSImageで返す
on makeNSImageWithFilledWithColor(aWidth, aHeight, fillColor)
  –Imageの作成  
  
set curSize to current application’s NSMakeSize(aWidth, aHeight)
  
set anImage to NSImage’s alloc()’s initWithSize:curSize
  
  
anImage’s lockFocus() –描画開始
  
  
set theRect to {{x:0, y:0}, {height:aHeight, width:aWidth}}
  
set theNSBezierPath to NSBezierPath’s bezierPath
  
theNSBezierPath’s appendBezierPathWithRect:theRect
  
  
fillColor’s |set|() –色設定
  
theNSBezierPath’s fill() –ぬりつぶし
  
  
anImage’s unlockFocus() –描画ここまで
  
  
–生成した画像のRaw画像を作成
  
set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to NSBitmapImageRep’s imageRepWithData:imageRep
  
  
set newImg to NSImage’s alloc()’s initWithSize:curSize
  
newImg’s addRepresentation:aRawimg
  
return newImg
end makeNSImageWithFilledWithColor

–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

–NSColor(内容はRGBAカラー)からだいたいの色名を推測
on retColorDomainNameFromNSColor(aCol)
  set hueVal to aCol’s hueComponent()
  
set satVal to aCol’s saturationComponent()
  
set brightVal to aCol’s brightnessComponent()
  
  
if satVal ≤ 0.01 then set satVal to 0.0
  
  
set colName to ""
  
  
if satVal = 0.0 then
    if brightVal ≤ 0.2 then
      set colName to "black"
    else if (brightVal > 0.95) then
      set colName to "white"
    else
      set colName to "gray"
    end if
  else
    if hueVal ≤ (15.0 / 360) or hueVal ≥ (330 / 360) then
      set colName to "red"
    else if hueVal ≤ (45.0 / 360) then
      set colName to "orange"
    else if hueVal < (70.0 / 360) then
      set colName to "yellow"
    else if hueVal < (150.0 / 360) then
      set colName to "green"
    else if hueVal < (190.0 / 360) then
      set colName to "green(cyan)"
    else if (hueVal < 250.0 / 360.0) then
      set colName to "blue"
    else if (hueVal < 290.0 / 360.0) then
      set colName to "purple"
    else
      set colName to "red(magenta)"
    end if
  end if
  
  
return colName
end retColorDomainNameFromNSColor

on makeNSColorFromRGBAval(redValue as integer, greenValue as integer, blueValue as integer, alphaValue as integer, aMaxVal as integer)
  set aRedCocoa to (redValue / aMaxVal) as real
  
set aGreenCocoa to (greenValue / aMaxVal) as real
  
set aBlueCocoa to (blueValue / aMaxVal) as real
  
set aAlphaCocoa to (alphaValue / aMaxVal) as real
  
set aColor to NSColor’s colorWithCalibratedRed:aRedCocoa green:aGreenCocoa blue:aBlueCocoa alpha:aAlphaCocoa
  
return aColor
end makeNSColorFromRGBAval

★Click Here to Open This Script 

Posted in Color file Image | Tagged 10.11savvy 10.12savvy 10.13savvy NSBezierPath NSBitmapImageRep NSColor NSImage NSString NSUUID | Leave a comment

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

Posted on 7月 16, 2018 by Takaaki Naganoya

ごく一部の愛読者の皆様からのご要望を受け、2018年1月のBlog消滅以前の内容を1年ごとにまとめた「Blogアーカイブ本」のVol.2を販売開始しました。Vol.2は2009年1〜12月の内容をまとめています。全367ページ、2,000円。ファイル形式はPDFで、キーワードによる全文検索や印刷が行えます。

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

XcodeプロジェクトのダウンロードリンクやYouTubeのムービーへのリンクもきちんと反映し直しています。

続刊のボリューム感については、(最低でも)こんな感じです。

 vol.3:2010/1〜12(仮組みページ数:247)
 vol.4:2011/1〜2012/12(仮組みページ数:372)
 vol.5:2013/1〜2014/12(仮組みページ数:276)
 vol.6:2015/1〜12(仮組みページ数:320)

■Vol.2 掲載AppleScript(全184本)

Photoで特定のアルバムに入っている写真の枚数をカウントする
iPhotoで写真のファイル名に合致する写真を取得する
iPhotoで、複数名称による写真指定を行う例(できない)
Numbersでオープン中のドキュメントを数える
Numbersでウィンドウを数える(動作がおかしい)
Numbersでウィンドウの情報を取得する
Numbersのアプリケーションのプロパティを取得する
Numbersで書類を保存する
pdfinfoを使ってPDFのページ数をかぞえる
Numbersで統合された選択セルを元にもどす
CaminoでWindow 1の情報を取得する
Caminoで新規ウインドウで指定URLをオープン
CaminoでBookmarkを操作するテスト(駄目)
変数やサブルーチン名称に日本語を使用する
QuickTime Playerがバージョン7.6にアップデート
Xcodeでオープン中のプロジェクトで、ビルドターゲット「deployment」を使用してクリーニング実行後、ビルドを行う
入れ子のリストをフラット化v01
入れ子のリストをフラット化v02
入れ子のリストをフラット化v03
指定階層下で、指定クリエータコードのファイルを取得
SkimでPDFの各種情報を取得する
Skimで注釈(note)を削除する
Numbersで選択範囲を取得
Nunbersで選択範囲の値を取得
Numbersで指定範囲を選択
Preview.appで最低限のScript命令実行機能をイネーブルに
Excel 2008でX軸方向に右端から、データが存在しているセルをサーチ
GUI Scriptingによる記述(1)
Shade 10でレンダリングを行う
GUI Scriptingによる記述(2)
GUI Scriptingによる記述(3)
pdfinfoの結果をparseするv2
Shade 10でドキュメントを保存する
Shade 10で新規ドキュメントを作成
Shade 10でsceneをDXF形式で書き出す
リスト中で重複を検出する(大文字小文字を同一視)
Font Bookで指定フォントのファイルがどこに置かれているかを検知する
diskutilitiesで起動HDDのユーザー権限修復
Font Bookで指定typefaceの詳細な情報を取得する
アプリケーションに命令を行う記述方法で最短のもの
Safariのダウンロードフォルダを求めるv1
Safariのダウンロードフォルダを求めるv2
Safariのダウンロードフォルダを求めるv3
Safariのダウンロードフォルダを求めるv4
アドレスブックで表示中のPersonに画像をTIFF変換して読み込み
アプレットをコピーしてリネーム v2
指定文字列ではじまるプロセスをすべて終了させる
指定ファイルがバンドル形式のアプレットかどうかチェック
ソート用のカラムを生成する
複数リストの合成
version テスト
指定名称のプログラムを強制終了させる
数値を「時間」「分」でフォーマットしたテキストで返す
MacJournalでアプリのプロパティを取得
MacJournalで書類のプロパティを取得
MacJournalでキーワード検索状態を解除
MacJournalで選択中のjournal entryを取得する
MacJournalでjournalを選択UIを表示しつつ表示
MacJournalで任意のjournalをロックする(未遂)
国民の祝日を求めるv2
リスト中から重複項目をリストアップする
現在日時から曜日を番号で返す
リスト内のアイテムへの項目追加
contains/is inによる存在確認は、入れ子のリストに使えない
Photoshop Elements 6のAS辞書はPhotoshop CS3と同じ
入れ子のリスト内のis in/containsによる存在確認
某氏のtwitter上の発言を集めてテキスト化
twitter検索結果のJSONをparseする
6/13にTMUGのMeetingで新作「Moving Agency」をデモ
FireFoxでオープン中のURLを取得する
FireFoxでオープンしているURLを取得。Leopard対応版
郵便専門ネットでバージョン番号を取得
郵便専門ネットでXML-RPC経由でJISコード(5桁、6桁どちらでも)から、その市区町村に属している郵便番号のリストを取得
郵便専門ネットで道府県のコード(地方公共団体コードの先頭2文字)から都道府県名を返す
郵便専門ネットでXML-RPC経由で郵便番号に対応する世界測地系(WGS84)の緯度経度コード(Geocode)を返す
郵便専門ネットで一度に取得できるデータ件数を返す
郵便専門ネットでXML-RPC経由で引数に都道府県のJISコード(JISコードの先頭2文字)を渡すと、その都道府県に属しているJISコードを取得
郵便専門ネットでXML-RPC経由で郵便番号から住所を返す
郵便専門ネットで郵便番号の存在チェック
郵便専門ネットで引数に指定した郵便番号で何件ヒットするのかをint型で返す
郵便専門ネットでXML-RPC経由で郵便番号を6桁(チェックデジット付き)の全国地方公共団体コード/JISコード/市町村コードに変換
WordPress.comが受け取るXML-RPCのメソッド名一覧を取得する
ファイルの安全な書き出し
AppleScript Studioを念頭に置いたライブラリ整備
WordPressのBlogに画像ファイルをアップロード
Safariで表示中のページ内容をMacJournalの現在選択中のJournalにペースト
Diary++Xでアプリの情報を取得
Diary++Xでドキュメントの情報を取得
Diary++Xで指定カテゴリ内のアーティクルを取得する
XcodeでクリーニングしてビルドしてZip圧縮
指定月の第x指定曜日に該当する日付を求める(曜日数値指定対応)
国民の祝日を求める v4
指定年月の祝日の日を数値のリストで返す
Twitterrifficで選択中の発言の時間をGrowlで表示。アイコン付きで
URL Access Scriptingにファイル名の32文字制限が
Twitterifficで選択中の発言の時間をGrowlで表示。アイコン付きで v3
AppleScriptで開発を行うユーザーアカウントにATOKは禁物
Google Chrome BetaがAppleScriptに非対応
国民の祝日を求め__指定期間に該当するものを返す
もんのすごいざっくりな元号計算ルーチン
指定月のうち、日曜日に該当するものを日付だけ返す
1年間の各週の開始日と終了日を求める(月曜日はじまりカレンダー)
ファイル名文字列から拡張子のみ取得する
日曜日はじまりのカレンダーで指定月が何週分あるか行数を数える
指定年の各月の開始日と終了日を算出する
指定フォルダ内の指定種別(kind)のファイル一覧を取得
指定アプリケーションのAppleScript予約語をリストアップ
メールの返信文1行目のテキストからメールアドレスを抽出する v1
メールの返信文1行目のテキストからメールアドレスを抽出する v2
メールアドレスチェック
Snow Leoaprdでスクリプトエディタが「AppleScriptエディタ」に
Snow LeoaprdのAppleScriptに関するリリースノート
Snow LeopardのAppleScriptに関するリリースノート(2)
指定フォルダ内の指定種別(kind)のファイル一覧を取得
指定アプリケーションのAppleScript予約語をリストアップ
メールの返信文1行目のテキストからメールアドレスを抽出する v1
メールの返信文1行目のテキストからメールアドレスを抽出する v2
メールアドレスチェック
Snow Leoaprdでスクリプトエディタが「AppleScriptエディタ」に
Snow LeoaprdのAppleScriptに関するリリースノート
Snow LeopardのAppleScriptに関するリリースノート(2)
リスト中の要素の存在確認(10.6以降)
10.6でtext item delimitersがリストで指定可能に
QuickTime PlayerのXと7を区別して命令を発行する
Diary++Xで最近の日記本文をもとに今日の日記を新規作成する
Diary++Xで最近の日記本文をもとに今日の日記を新規作成する v2
9/19にホスティングサービス側の都合で5分間ダウン
Diary++Xで最近の日記本文をもとに今日の日記を新規作成する v3
Sin Cos演算ルーチン
AppleScriptObjCのドキュメント公開が開始される
リスト中の要素の存在確認(10.6以降)
10.6でtext item delimitersがリストで指定可能に
QuickTime PlayerのXと7を区別して命令を発行する
Diary++Xで最近の日記本文をもとに今日の日記を新規作成する
Diary++Xで最近の日記本文をもとに今日の日記を新規作成する v2
9/19にホスティングサービス側の都合で5分間ダウン
Diary++Xで最近の日記本文をもとに今日の日記を新規作成する v3
Sin Cos演算ルーチン
AppleScriptObjCのドキュメント公開が開始される
Mail.appの指定メールボックス内に任意のメールボックスを新規作成 v2
テキストによるプログレスインジケータ作成 v2
LateNight SoftwareのMark Alldrittが自社製OSAXの64ビット非対応について言及
whoseによるフィルタ参照
Cyberduck 3.3b4がAppleScriptに非対応
全角文字から半角文字への置換
System EventsでDockの設定を取得、変更する
Diary++X v1.1以降で日付を指定して日記アーティクルを作成
Xcode 3.2.1でAS用語辞書が大幅拡充
URL形式の文字エスケープを行う
リスト中に入っている指定要素をサーチして、合致した出現アイテム番号を返す
指定文字列の中に特定の文字が何回出現するかをカウントして返す
InDesign CS3のuser interaction levelを取得、設定する
テキスト中の任意の順番の文字取り出し Mac OS X 10.4.11への対応
Xcode 3.2.1でアプリケーションの情報を取得する
Xcode 3.2.1でプロジェクトの属性情報を取得する
10.5以降でRemote AppleEvent操作時にdisplay dialog等を使えない
AppleScriptの文字列比較(1)
AppleScriptの文字列比較(2)~considering, ignoring
AppleScriptの文字列比較(3)~濁点/半濁点の考慮/無視指定
AppleScriptの文字列比較(4)~日本語の大文字/小文字
AppleScriptの文字列比較(5)~句読点の考慮/無視
等号つき不等号の同義語
System EventsでScreen Saverの設定にアクセスする
Web共有がオンになっているかどうかを検出する
AppleScriptObjC-Dev MLが新設された
System Events経由でQuickTimeムービーにアクセスする2
System Events経由でQuickTimeムービーのannotationにアクセスする
擬似的にPropertyファイルを使ってカウントアップ
cyberduckでファイルのアップロード
AppleScriptObjc 3分間クッキング
指定の大きさでカラのリストを作成する
クリップボードに入っている情報の改行を外してクリップボードに書き戻す
PlistファイルをParseして返す
選択したアプリケーションのInfo.plistを読んで、実行バイナリの名称を取得する
オブジェクトの複数同時指定
指定フォルダ中のファイルを消してフォルダだけ残す
指定フォルダの中のフォルダをオープン
Excel選択範囲から各種文字列長のデータをピックアップ v6
Photoshop CS3で指定エリアを切り出して新規保存
指定値を構成するペアの全パターンのリストを求める
連続する文字(たぶんスペース)を1つにまとめる
指定文字列の中に指定文字が何回出現するかカウントする
伏せ字文字列を返す
指定日に在任中の内閣総理大臣の氏名を取得 v2

Posted in 未分類 | Leave a comment

日本測地系から世界測地系への座標変換

Posted on 7月 14, 2018 by Takaaki Naganoya

日本測地系の緯度・経度情報から世界測地系の緯度・経度情報に変換するAppleScriptです。

AppleScriptに35種類の関数計算機能を付加する「calcLibAS」の計算精度を確認するための実例でもあります。だいたい期待の精度は出せている感じです。

より精度を求められるような用途には、AppleScriptの数値変数自体が浮動小数点演算で10桁の計算精度しかないので、数値計算自体を外部にすべて出してしまうか、より精度の高い変数型を作ってしまうか(文字列で扱うようにすれば問題なさそう)というところでしょうか。

「日本測地系から世界測地系への座標変換(近似式)」のほうはObjective-Cから、「日本測地系から世界測地系への直行座標変換」のほうはRubyからAppleScriptに書き換えてみたものです。

Rubyのプログラムが割と単調だったので、読んでいて疲れてしまいました。変数名の付け方が途中で変わっているのは、「とりあえず動けばいい」ぐらいで組んでいたのと、変数名にいちいち「Local」とか付けるのに疲れたからです。

Piyomaru Script Assistantで変数名のみ一括置換してもいいわけですが、それはそれ、、、

AppleScript名:日本測地系から世界測地系への座標変換(近似式)
— Created 2018-07-13 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set jpLat to 42.16593046887
set jpLng to 142.771877437246
set {wdLat, wdLng, wdH} to tky2wgsLinea(jpLat, jpLng, 0) of me –日本測地系から世界測地系に換算
–>  {​​​​​42.168515890674, ​​​​​142.768119997121, ​​​​​0​​​}

set {latJ, lonJ, heightJ} to wgs2tkyLinea(wdLat, wdLng, wdH) of me –世界測地系から日本測地系に換算
–>  {​​​​​42.16593052955, ​​​​​142.77187743437, ​​​​​0​​​}

–日本測地系から世界測地系に換算
–http://d.hatena.ne.jp/iRSS/20111112/1321113232
on tky2wgsLinea(latJ, lonJ, heightJ)
  set heightW to heightJ
  
set lonW to lonJ – latJ * 4.6038E-5 – lonJ * 8.3043E-5 + 0.01004
  
set latW to latJ – latJ * 1.0695E-4 + lonJ * 1.7464E-5 + 0.0046017
  
return {latW, lonW, heightW}
end tky2wgsLinea

–世界測地系から日本測地系に換算
–https://altarf.net/computer/技術的なポエム/3332
on wgs2tkyLinea(latW, lonW, heightW)
  set heightJ to heightW
  
set latJ to (latW * 1.000106961) – (lonW * 1.7467E-5) – 0.004602017
  
set lonJ to (lonW * 1.000083049) + (latW * 4.6047E-5) – 0.010041046
  
return {latJ, lonJ, heightJ}
end wgs2tkyLinea

★Click Here to Open This Script 

AppleScript名:日本測地系から世界測地系への直行座標変換
— Created 2018-07-13 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use math : script "calcLibAS" –http://piyocast.com/as/archives/3523

set jpLat to 42.16593046887
set jpLng to 142.771877437246

set {wdLat, wdLng, wdH} to JapanGeodeticSystem’s convertIntoWgs(jpLat, jpLng)
–>  {​​​​​42.168504277889, ​​​​​142.768075650137, ​​​​​61.914452206343​​​}

–https://altarf.net/computer/ruby/3347
–日本測地系から世界測地系に換算
script JapanGeodeticSystem
  –ラジアン(度)
  
property rdNum : pi / 180
  
  
–日本測地系の定数(ベッセル楕円体)
  
property rJP : 6.377397155E+6 –赤道半径
  
property fJP : 1 / 299.1528128 –扁平率
  
property e2JP : (2 * fJP) – (fJP * fJP) –第一離心率
  
  
–世界測地系の定数(WGS84)
  
property rWS : 6.378137E+6 –赤道半径
  
property fWS : 1 / 298.257223563 –扁平率
  
property e2WS : (2 * fWS) – (fWS * fWS) –第一離心率
  
  
–並行移動量(m)
  
property dxNum : -148
  
property dyNum : 507.0
  
property dzNum : 681.0
  
  
–楕円体高
  
property heightNum : 0
  
  
  
–日本測地系から世界測地系に変換する
  
on convertIntoWgs(aLat, aLong)
    set {x, y, z} to llh2xyz(aLat, aLong, heightNum, rJP, e2JP, rdNum) of me
    
    
set x to x + dxNum
    
set y to y + dyNum
    
set z to z + dzNum
    
    
set {lat1, lng1, h1} to xyz2llh(x, y, z, rWS, e2WS, rdNum) of me
    
return {lat1, lng1, h1}
  end convertIntoWgs
  
  
  
–座標系の変換(緯度経度 -> xyz)
  
on llh2xyz(latLocal, lngLocal, hLocal, aLocal, e2Local, rdLocal)
    set latLocal to latLocal * rdLocal
    
set lngLocal to lngLocal * rdLocal
    
    
set sbNum to calcSin(latLocal) of math
    
set cbNum to calcCos(latLocal) of math
    
    
set rnLocal to aLocal / (calcSqrt(1 – e2Local * sbNum * sbNum) of math)
    
    
set xLocal to (rnLocal + hLocal) * cbNum * (calcCos(lngLocal) of math)
    
set yLocal to (rnLocal + hLocal) * cbNum * (calcSin(lngLocal) of math)
    
set zLocal to (rnLocal * (1 – e2Local) + hLocal) * sbNum
    
    
return {xLocal, yLocal, zLocal}
  end llh2xyz
  
  
  
–座標系の変換(xyz -> 緯度経度)
  
on xyz2llh(x, y, z, a, e2, rdLocal)
    set bda to calcSqrt(1 – e2) of math
    
set p to calcSqrt(x * x + y * y) of math
    
set t to calcAtan2(z, p * bda) of math
    
set stNum to calcSin(t) of math
    
set ctNum to calcCos(t) of math
    
set b to calcAtan2(z + e2 * a / bda * stNum * stNum * stNum, p – e2 * a * ctNum * ctNum * ctNum) of math
    
    
set l to calcAtan2(y, x) of math
    
set sb to calcSin(b) of math
    
set rn to a / (calcSqrt(1 – e2 * sb * sb) of math)
    
set h to p / (calcCos(b) of math) – rn
    
set l1 to b / rdLocal
    
set l2 to l / rdLocal
    
return {l1, l2, h}
  end xyz2llh
  
end script

★Click Here to Open This Script 

Posted in geolocation | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

noteのオンラインマガジン「猛者」に新規Noteを寄稿(4)

Posted on 7月 11, 2018 by Takaaki Naganoya

オンラインマガジンApp Engineer Journal “猛者”(モサ)に「Appleを倒すメーカーを作ってみよう」「Apple Watchの打倒のしかた(上)」を寄稿しました。

Posted in 未分類 | Leave a comment

Post navigation

  • Older posts
  • Newer posts

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

Google Search

Popular posts

  • Numbersで選択範囲のセルの前後の空白を削除
  • macOS 26, Tahoe
  • macOS 15でも変化したText to Speech環境
  • KagiのWebブラウザ、Orion
  • Script Debuggerの開発と販売が2025年に終了
  • 【続報】macOS 15.5で特定ファイル名パターンのfileをaliasにcastすると100%クラッシュするバグ
  • macOS 15 リモートApple Eventsにバグ?
  • NSObjectのクラス名を取得 v2.1
  • 2024年に書いた価値あるAppleScript
  • macOS 15:スクリプトエディタのAppleScript用語辞書を確認できない
  • (確認中)AppleScript Dropletのバグっぽい動作が解消?
  • Xcode上のAppleScriptObjCのプログラムから、Xcodeのログ欄へのメッセージ出力を実行
  • AppleScript Dropletのバグっぽい動作が「復活」(macOS 15.5β)
  • AVSpeechSynthesizerで読み上げテスト
  • 指定フォルダ以下の画像のMD5チェックサムを求めて、重複しているものをピックアップ
  • Apple、macOS標準搭載アプリ「写真」のバージョン表記を間違える
  • macOS 26, 15.5でShortcuts.app「AppleScriptを実行」アクションのバグが修正される
  • Numbersで選択中の2列のセルを比較して並べ直して書き戻す v2
  • Script Debuggerがフリーダウンロードで提供されることに
  • macOS 15.5beta5(24F74)でaliasのキャスティングバグが修正された???

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 (158) 26.0savvy (21) CotEditor (66) Finder (52) Keynote (119) NSAlert (61) NSArray (51) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (53) NSDictionary (28) NSFileManager (23) NSFont (21) NSImage (41) NSJSONSerialization (21) NSMutableArray (63) NSMutableDictionary (22) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (119) NSURL (98) NSURLRequest (23) NSUTF8StringEncoding (30) NSView (33) NSWorkspace (20) Numbers (76) Pages (56) 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)
  • 未分類

アーカイブ

  • 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