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

最前面のFinder Windowをクローン

Posted on 7月 4, 2018 by Takaaki Naganoya

Finderの最前面のウィンドウを、同じ対象フォルダ&同じビュー形式で新規作成するAppleScriptです。

昔どこかで拾ってきたものを使い続けているものです。利用頻度はかなり高く、ファイルの整理をFinder上で行なっているときには、たいてい利用しています。

ファイル作成日が2011年になっていましたが、実際にはさらに古い時期のものだと思います。

開けてみて驚きました(v1)。海外のScripterとの間でなんとなく成立している、

 ・過度に英文っぽく書かない
 ・「the」の乱発はやらない(できてもやらない)
 ・過度に短縮記述は行わない
 ・よほどの必要性がないかぎり、暗黙の実行結果「result」は使わない(何を処理しているかがわかりにくいので)
 ・「get」は省略できる場合が多いので、あえて書かない

というお約束が守られておらず、「the」は入りまくっているわ、「get」が無意味に(この後でresultで受け取っていたのだろうか)使われているわで、読みにくいことこのうえない代物でした。

そこで、v2のように書き換えました。これならかなり読みやすく、わかりやすく、無駄な処理もありません。

はるかかなた昔のAppleScriptの中には、今見るとあまり書きこなれていない記述もあったりして、読み直すとかなり驚くものがたくさんあります。

AppleScript名:最前面のWindowをクローン v1
tell application "Finder"
  set sDisk to (name of startup disk) & ":"
  
  
get the exists of the front Finder window –なにこれ???
  
if the (exists of the front Finder window) is true then
    try
      set newWindow to target of front window
      
set oldView to current view of front window
      
make new Finder window to newWindow
      
set current view of front window to oldView
    end try
  else
    try
      make new Finder window to alias sDisk
      
set the current view of the front Finder window to column view
    end try
  end if
end tell

★Click Here to Open This Script 

AppleScript名:最前面のFinder Windowをクローン v2
tell application "Finder"
  set wEx to (exists of front Finder window)
  
  
if wEx = true then
    try
      set winRef to a reference to front window
      
set curTarget to target of winRef
      
set curView to current view of winRef
      
make new Finder window to curTarget
      
set current view of winRef to curView
    end try
  else
    try
      make new Finder window
      
set current view of front Finder window to list view
    end try
  end if
end tell

★Click Here to Open This Script 

Posted in GUI | Tagged 10.11savvy 10.12savvy 10.13savvy Finder | Leave a comment

Mac Blue-ray Playerで表示中の内容をKeynoteに追記

Posted on 7月 3, 2018 by Takaaki Naganoya

Mac Blue-ray Playerで表示中のディスクの映像を1コマキャプチャして、その画像をオープン中のKeynote書類の末尾に追記するAppleScriptです。

–> Watch Demo Movie

Mac Blue-ray Playerには表示中の映像を静止画像のスナップショットを作成する機能があり、保存先のフォルダは「環境設定」で指定できるようになっています。

本ScriptはmacOS標準搭載のScript Menuに入れて実行することを想定しています。また、自分はMac Blue-ray PlayerでBru-rayディスクではなくDVDを再生することが多く、本検証もDVDディスクで行なっています(たぶんBlu-rayでも大丈夫です)。

キャプチャ先のKeynote書類をあらかじめ作成してオープンしておきます。次に、Mac Blue-ray Playerでディスクを再生して、キャプチャしたい場所で一時停止し、本Scriptをメニューから呼び出して実行すると、Playerの表示内容をキャプチャして、Keynote書類の末尾に新規スライドを追加し、そこにキャプチャした画像をインポートします。

Mac Blue-ray Playerは発売直後(2011年)に購入し、そのままアップデートして利用していたのですが、発売後7年以上経過した現在ではサポートが終了。

アプリケーションを作る側の人間から言わせれば、ひんぱんにオンラインアップデートを行い、6年以上も同一製品ラインナップを維持してきたというのは(品質について批判もないことはないですが)、素直に尊敬に値します。

話が横道に入ってしまいましたが、Mac Blue-ray Playerは現在では「Mac Blu-ray Player Pro」「Mac Blu-ray Player Standard」そして無料版の「Free Mac Media Player」へと別れたようです。

「Free Mac Media Player」は機能面からMac Blue-ray Playerとほぼ同じものに見えます。AppleScript用語辞書もMac Blue-ray Playerと同じものであり、Mac Blue-ray Player用のAppleScriptはFree Mac Media Playerでも使えます(tell application名を直すだけです)。

実際に、本Scriptを「Free Mac Media Player」向けに書き換えて実行できることを確認しています。

AppleScript名:Mac Blue-ray Playerで表示中の内容をKeynoteに追記
— Created 2018-07-02 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 NSPredicate : a reference to current application’s NSPredicate
property NSFileManager : a reference to current application’s NSFileManager
property NSUserDefaults : a reference to current application’s NSUserDefaults
property NSDirectoryEnumerationSkipsHiddenFiles : a reference to current application’s NSDirectoryEnumerationSkipsHiddenFiles

set aExtension to "png" — Mac Blue-ray Player’s Snapshot file name extension
set aKeyword to "スナップショット" –Mac Blue-ray Player’s Snapshot file name’s pre-fix (@Japanese User environment), maybe this is localized string

–Mac Blueray Playerの設定からスナップショットの設定値を取得する
set theID to "com.macblurayplayer.Mac Blu-ray Player"
set theTargKey to "Preferences.snapshotSavePath"
set vRes to defaultsReadFromPlistEntry(theID, theTargKey) of me

–Mac Blueray Playerの環境設定に「~」(チルダ)が入っていた場合に備えて展開
set pathString to current application’s NSString’s stringWithString:vRes
set sourceFolder to pathString’s stringByExpandingTildeInPath()

–処理前にスナップショットのファイルを削除
set file1Res to getFilePathListByExtAndKeyword(sourceFolder, aExtension, aKeyword) of me –ファイル一覧取得
trashItemsByList(file1Res) of me –削除

–Mac Blueray Playerで表示している内容を設定中のフォルダに「スナップショット -YYYY-MM-DD at hh_mm_ss AM-9999999999.png」のファイル名で保存
tell application "Blu-ray Player"
  snapshot –こんだけ
end tell

–処理前にスナップショットのファイルを削除
set file2Res to getFilePathListByExtAndKeyword(sourceFolder, aExtension, aKeyword) of me –ファイル一覧取得
if file2Res = file1Res or file2Res = {} then return –No Snap

–Add Snapshot images to Keynote
repeat with i in file2Res
  set tmpFile to POSIX file i
  
set tmpAlias to tmpFile as alias
  
  
tell application "Keynote"
    tell front document
      set endSlide to make new slide at end
      
      
set blankMaster to master slide "空白" –"Blank" in Japanese. This string is *localized*
      
      
tell endSlide
        set base slide to blankMaster
        
set thisImage to make new image with properties {file:tmpAlias}
      end tell
    end tell
  end tell
  
  
–ファイル削除(ゴミ箱に移動)
  
trashItemAt(tmpAlias) of me
end repeat

–指定フォルダ内のファイルを、拡張子と先頭キーワードで抽出
on getFilePathListByExtAndKeyword(aFol, aExt, aKeyword)
  set aFM to NSFileManager’s defaultManager()
  
set aURL to |NSURL|’s fileURLWithPath:aFol
  
set urlArray to aFM’s contentsOfDirectoryAtURL:aURL includingPropertiesForKeys:{} options:(NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
  
set thePred to NSPredicate’s predicateWithFormat:"pathExtension == [c]%@ && lastPathComponent BEGINSWITH %@" argumentArray:{aExt, aKeyword}
  
set anArray to (urlArray’s filteredArrayUsingPredicate:thePred)
  
if anArray = missing value then return {}
  
return (anArray’s valueForKeyPath:"path") as list
end getFilePathListByExtAndKeyword

–ファイル削除(ゴミ箱に移動) POSIX path listで指定
on trashItemsByList(posixPathList)
  repeat with i in posixPathList
    set fRes to trashItemAt(i) of me
    
if fRes = false then error "Error deleting a path:" & (i as string)
  end repeat
end trashItemsByList

–ファイル削除(ゴミ箱に移動)
on trashItemAt(anAlias)
  set theNSFileManager to NSFileManager’s defaultManager()
  
set anNSURL to |NSURL|’s fileURLWithPath:(POSIX path of anAlias)
  
set theResult to theNSFileManager’s trashItemAtURL:anNSURL resultingItemURL:(missing value) |error|:(missing value)
  
return (theResult as integer = 1) as boolean
end trashItemAt

–指定IDのplistから指定キーの内容を取り出す
on defaultsReadFromPlistEntry(theID, theTargKey)
  set storedDefaults to (NSUserDefaults’s standardUserDefaults()’s persistentDomainForName:theID)
  
set keyList to storedDefaults’s allKeys() as list
  
if theTargKey is not in keyList then return false
  
set aRes to (storedDefaults’s valueForKeyPath:theTargKey) as list of string or string — as anything
  
return aRes
end defaultsReadFromPlistEntry

★Click Here to Open This Script 

Posted in Image | Tagged 10.11savvy 10.12savvy 10.13savvy Free Mac Media Player Keynote Mac Blu-ray Player NSDirectoryEnumerationSkipsHiddenFiles NSFileManager NSPredicate NSURL NSUserDefaults | Leave a comment

指定フォルダ内の指定拡張子のファイルのうち、指定キーワードで始まるものを

Posted on 7月 3, 2018 by Takaaki Naganoya

指定フォルダ(デスクトップ)内の指定拡張子のファイルのうち、ファイル名が指定キーワードではじまるものを抽出するAppleScriptです。

AppleScriptでは定番の処理ですが、Finderが10.7あたりでCocoa化されて書き直しが行われたあたりからフィルタ参照を併用した条件抽出のパフォーマンスが大幅に低下。

アプリケーション間通信でパフォーマンスを低下させないための機能であるフィルタ参照が、かえって処理速度を低下させるというたいへん皮肉な事態に。

AppleScript名:指定フォルダ内の指定拡張子のファイルのうち、指定キーワードで始まるものをaliasリストで返す(Finder Version)
tell application "Finder"
  tell folder (path to desktop)
    set aList to (every file whose name starts with "スナップショット" and kind of it is "PNGイメージ") as alias list
  end tell
end tell

★Click Here to Open This Script 

Finder経由で行うと、処理時間は驚愕の4.6秒(67項目から1項目を抽出するだけの処理です)。これをCocoaの機能を用いて処理すると0.002秒。同じAppleScriptなのに2,000倍以上高速。逆にいえば、現在のFinder経由でのファイル処理の速度は遅すぎです。

macOS 10.10以降では、各種ファイル処理についてはFinderではなくCocoaの機能を用いたほうがよいでしょう。

その他、Finder上で選択中のファイルの一覧を取得するとか、Finder上で選択中のフォルダを取得するといった処理であればパフォーマンスの低下はないので、使っても(処理速度上の)問題はありません。

AppleScript名:指定フォルダ内の指定拡張子のファイルのうち、指定キーワードで始まるものをPOSIX pathリストで返す
— Created 2015-10-01 by Takaaki Naganoya
— Modified 2015-10-01 by Shane Stanley–With Cocoa-Style Filtering
— Modified 2018-07-03 by Takaaki Naganoya–Added filtering feature
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"

property |NSURL| : a reference to current application’s |NSURL|
property NSPredicate : a reference to current application’s NSPredicate
property NSFileManager : a reference to current application’s NSFileManager
property NSDirectoryEnumerationSkipsHiddenFiles : a reference to current application’s NSDirectoryEnumerationSkipsHiddenFiles

set aExtension to "png" — no dot
set aKeyword to "スナップショット" –"Snapshot" in Japanese
set aTargetFolder to POSIX path of (path to desktop folder)

set fList to getFilePathListByExtAndKeyword(aTargetFolder, aExtension, aKeyword) of me
–>  {"/Users/me/Desktop/スナップショット-2018-07-03 at 11_42_12 AM-1696613812.png"}

on getFilePathListByExtAndKeyword(aFol, aExt, aKeyword)
  set aFM to NSFileManager’s defaultManager()
  
set aURL to |NSURL|’s fileURLWithPath:aFol
  
set urlArray to aFM’s contentsOfDirectoryAtURL:aURL includingPropertiesForKeys:{} options:(NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
  
set thePred to NSPredicate’s predicateWithFormat:"pathExtension == [c]%@ && lastPathComponent BEGINSWITH %@" argumentArray:{aExt, aKeyword}
  
set anArray to (urlArray’s filteredArrayUsingPredicate:thePred)
  
if anArray = missing value then return {}
  
return (anArray’s valueForKeyPath:"path") as list
end getFilePathListByExtAndKeyword

★Click Here to Open This Script 

Posted in file | Tagged 10.11savvy 10.12savvy 10.13savvy Finder NSDirectoryEnumerationSkipsHiddenFiles NSFileManager NSPredicate NSURL | Leave a comment

SkimでPDF表示モードを「単一」と「2ページ見開き」でトグル切り替え

Posted on 7月 1, 2018 by Takaaki Naganoya

オープンソースのPDFビューワー「Skim」でPDF表示モードを「単一ページ」と「2ページ見開き」でトグル切り替えするAppleScriptです。


▲Skim 単一ページ表示モード


▲Skim 2ページ見開きモード

一応、macOS標準搭載のScript Menuから呼び出して実行できることを確認していますが、、、

正直なところ、ウィンドウ上のボタンを操作したほうがScript Menuを操作するよりも手っ取り早いので、本Scriptに実用性はほとんどありません。

単に、SkimのPDF表示モードの指定方法を調べたので、その方法をScriptで記述しておいた(スケッチ)ぐらいの意味合いです。

AppleScript名:SkimでPDF表示モードを「単一」と「2ページ見開き」でトグル切り替え
tell application "Skim"
  tell front document
    set curViewSets to view settings
    
–> {auto scales:true, displays as book:false, displays page breaks:true, scale factor:1.235772357724, display mode:two up, display box:crop box}
    
    
set curMode to display mode of curViewSets
    
    
if curMode = single page then
      set display mode of curViewSets to two up
    else
      set display mode of curViewSets to single page
    end if
    
    
set view settings to curViewSets
  end tell
end tell

★Click Here to Open This Script 

Posted in PDF | Tagged 10.11savvy 10.12savvy 10.13savvy Skim | Leave a comment

Skimで現在表示中のPDFのページをJPEG画像で書き出す

Posted on 6月 30, 2018 by Takaaki Naganoya

オープンソースのPDFビューワー「Skim」で現在表示中のPDFの現在表示中のページをJPEG画像で書き出すAppleScriptです。

macOS標準装備のPreview.appはつい最近AppleScriptからの制御が公式に行えるようになった程度で、対応度も最低限です。Skimであれば、こうした「現在オープン中のPDFの表示中のページ」の番号を取得することもできます。

macOS標準装備のScript Menuから呼び出して利用することを前提に作成してあります。

Skimでオープン中の最前面のPDFと同じフォルダに、元ファイル名に対してページの数値をゼロパディングして追加したものをJPEG画像のファイル名に指定しています。ファイル名の重複回避などは行っていません。

ただし、Skimで表示モードが「単一」(1ページ分のみビューワーに表示)以外になっていると、カレントページ(現在表示中のページ)が画面上とアプリケーション側で管理しているものがズレることがあるので、表示モードを「単一」に切り替えてから「このページでよいか?」といった確認をユーザーに対して行うとよいかもしれません。

AppleScript名:Skimで現在表示中のPDFのページをJPEG画像で書き出す
— Created 2018-06-30 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "Quartz"
use framework "AppKit"

property |NSURL| : a reference to current application’s |NSURL|
property NSString : a reference to current application’s NSString
property NSImage : a reference to current application’s NSImage
property NSScreen : a reference to current application’s NSScreen
property NSNumber : a reference to current application’s NSNumber
property NSZeroPoint : a reference to current application’s NSZeroPoint
property PDFDocument : a reference to current application’s PDFDocument
property NSJPEGFileType : a reference to current application’s NSJPEGFileType
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 NSNumberFormatter : a reference to current application’s NSNumberFormatter
property NSImageInterpolationHigh : a reference to current application’s NSImageInterpolationHigh

tell application "Skim"
  set docCount to count every document
  
if docCount = 0 then return
  
  
tell front document
    set curInd to index of current page
    
set docFile to file of it
  end tell
end tell

set aPOSIX to POSIX path of docFile
set aURL to (|NSURL|’s fileURLWithPath:aPOSIX)

set aPDFdoc to PDFDocument’s alloc()’s initWithURL:aURL
set pCount to aPDFdoc’s pageCount()

set compFactor to 1.0 –1.0 — 0.0 = max jpeg compression, 1.0 = none

–Detect Retina Environment
set retinaF to NSScreen’s mainScreen()’s backingScaleFactor()
if retinaF = 1.0 then
  set aScale to 2.0 –Non Retina Env
else
  set aScale to 1.0 –Retina Env
end if

–PDFをページごとに分割してJPEGでファイル書き出し
set i to (curInd – 1) –AppleScript index (1 based) to Cocoa index (0 based) conversion

–Pick Up a PDF page as an image
set thisPage to (aPDFdoc’s pageAtIndex:(i))
set thisDoc to (NSImage’s alloc()’s initWithData:(thisPage’s dataRepresentation()))
if thisDoc = missing value then error "Error in getting imagerep from PDF in page:" & (i as string)

–Resize Image
set pointSize to thisDoc’s |size|()
set newSize to current application’s NSMakeSize((pointSize’s width) * aScale, (pointSize’s height) * aScale)
set newImage to (NSImage’s alloc()’s initWithSize:newSize)

newImage’s lockFocus()
(
thisDoc’s setSize:newSize)
(
NSGraphicsContext’s currentContext()’s setImageInterpolation:(NSImageInterpolationHigh))
(
thisDoc’s drawAtPoint:(NSZeroPoint) fromRect:(current application’s CGRectMake(0, 0, newSize’s width, newSize’s height)) operation:(NSCompositeCopy) fraction:2.0)
newImage’s unlockFocus()

–Save Image as JPEG
set theData to newImage’s TIFFRepresentation()
set newRep to (NSBitmapImageRep’s imageRepWithData:theData)
set targData to (newRep’s representationUsingType:(NSJPEGFileType) |properties|:{NSImageCompressionFactor:compFactor, NSImageProgressive:false})
set zText to retZeroPaddingText((i + 1), 4) of me
set outPath to addString_beforeExtensionIn_addingExtension_("_" & zText, aPOSIX, "jpg")

(targData’s writeToFile:outPath atomically:true) –書き出し

–ファイルパス(POSIX path)に対して、文字列(枝番)を追加。任意の拡張子を追加
on addString:extraString beforeExtensionIn:aPath addingExtension:aExt
  set pathString to NSString’s stringWithString:aPath
  
set theExtension to pathString’s pathExtension()
  
set thePathNoExt to pathString’s stringByDeletingPathExtension()
  
  
set newPath to (thePathNoExt’s stringByAppendingString:extraString)’s stringByAppendingPathExtension:aExt
  
return newPath as string
end addString:beforeExtensionIn:addingExtension:

on retZeroPaddingText(aNum as integer, aDigitNum as integer)
  if aNum > (((10 ^ aDigitNum) as integer) – 1) then return "" –Range Check
  
set aFormatter to NSNumberFormatter’s alloc()’s init()
  
aFormatter’s setUsesGroupingSeparator:false
  
aFormatter’s setAllowsFloats:false
  
aFormatter’s setMaximumIntegerDigits:aDigitNum
  
aFormatter’s setMinimumIntegerDigits:aDigitNum
  
aFormatter’s setPaddingCharacter:"0"
  
set aStr to aFormatter’s stringFromNumber:(NSNumber’s numberWithFloat:aNum)
  
return aStr as string
end retZeroPaddingText

★Click Here to Open This Script 

Posted in Image PDF | Tagged 10.11savvy 10.12savvy 10.13savvy NSBitmapImageRep NSImage NSNumber NSNumberFormatter NSScreen NSString NSURL PDFDocument Skim | Leave a comment

日付テキストを年単位で集計

Posted on 6月 29, 2018 by Takaaki Naganoya

yyyy-MM-dd HH:mm:ss形式の日付テキストをdateオブジェクトに変換して日付を年単位で集計するAppleScriptです。

Blog Archiveのデータベースのダンプテキストを読み取って、年別の投稿記事本数の集計を行うために作成しました(といっても、既存のルーチンを組み合わせただけです)。

AppleScript名:日付テキストを年単位で集計
— Created 2018-06-28 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

property NSArray : a reference to current application’s NSArray
property NSString : a reference to current application’s NSString
property NSLocale : a reference to current application’s NSLocale
property NSDictionary : a reference to current application’s NSDictionary
property NSCountedSet : a reference to current application’s NSCountedSet
property NSMutableArray : a reference to current application’s NSMutableArray
property NSSortDescriptor : a reference to current application’s NSSortDescriptor
property NSDateFormatter : a reference to current application’s NSDateFormatter

set aList to {"2006-06-27 02:38:52", "2008-03-09 19:08:05", "2008-03-09 19:29:29"}
set aRes to totalDateStrByYear(aList, "yyyy-MM-dd HH:mm:ss") of me
–> {{aCount:1, aKey:2006}, {aCount:2, aKey:2008}}

–日付テキストを年単位で集計
on totalDateStrByYear(aList, strFormat)
  set theCountedSet to NSCountedSet’s |set|()
  
set newArray to NSMutableArray’s new()
  
  
repeat with i in aList
    set postDate to dateFromStringWithDateFormat(i, strFormat) of me –日付テキストをDate Objectに変換
    
set yearStr to (year of postDate) –「年」の数字
    (
newArray’s addObject:yearStr)
  end repeat
  
  
set resArray to countItemsByItsAppearance(newArray) of me
  
set bList to sortRecListByLabel(resArray, "aKey", true) of me –昇順ソート
  
return bList
end totalDateStrByYear

–日付文字列からdate objectを作成する
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 list of string or string
end dateFromStringWithDateFormat

–登場頻度でリストを集計する
on countItemsByItsAppearance(aList)
  set aSet to NSCountedSet’s alloc()’s initWithArray:aList
  
set bArray to NSMutableArray’s array()
  
set theEnumerator to aSet’s objectEnumerator()
  
  
repeat
    set aValue to theEnumerator’s nextObject()
    
if aValue is missing value then exit repeat
    
bArray’s addObject:(NSDictionary’s dictionaryWithObjects:{aValue, (aSet’s countForObject:aValue)} forKeys:{"aKey", "aCount"})
  end repeat
  
  
return bArray
end countItemsByItsAppearance

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

★Click Here to Open This Script 

Posted in Calendar list | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

Recruit Tech Japanese Text Summarization API

Posted on 6月 28, 2018 by Takaaki Naganoya

Recruit techのA3RT機械学習ソリューションAPIのひとつ、「Text Summarization API」(日本語文章要約API)を呼び出すAppleScriptです。

APIの説明ページからAPI Keyを取得して本リストに記載して実行させてみてください。

他の2つのAPIが箸にも棒にもひっかからないレベルであるのとは異なり、本APIは割と使えます。

使えるというよりも、「日本語文章要約」という処理の結果が適切かどうか、その妥当性の評価が難しいので「とりあえずそれっぽく動いている」ように見えます。

論文やニュース記事のような要約に適した論理構造の文章というものが、一般的にはかなり「まれ」な存在であり、たいていは要約してみても納得しづらいものになりがちです。とくに論理ではなく情緒に訴えるような「くだけた」書き方をすると要約しづらいものになります。

AppleScript自体にも「summarize」という文章要約コマンドが標準装備されており、日本語の文章に対しても実行できますが、処理結果に100%納得できているわけではありません。半信半疑というところです。

本来、文章要約という処理を考えると、「主語」が何か、その主語がどのようなアクションを起こしたり、起こされたりしたのか、という処理を期待したいところですが、かならずしもそのような処理結果が得られるわけではありません。文章構造上、重要と思われるような箇所をそのまま抜き出すような処理が行われます。

そのため、大当たりという印象はないものの、大外しになることもなく「なんとなくそんな感じ?」という割り切れないものを感じてしまいがちです。

日本語文章の要約はいつの日か実用的な、納得できるレベルの処理ができるようになるのかもしれませんが、目下のところはこのレベルで満足するべきなのかもしれません。

AppleScript名:Recruit Tech Japanese Text Summarization API
— Created 2018-06-13 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
–https://a3rt.recruit-tech.co.jp/product/TextSummarizationAPI/

set apiKeyStr to getAPIKey() of me
set targText to returnBody() of me

set sText to "curl -X POST -d ’apikey=" & apiKeyStr & "’ –data-urlencode ’sentences=" & targText & "’ ’https://api.a3rt.recruit-tech.co.jp/text_summarization/v1/’"
set aRes to do shell script sText
set jsonString to current application’s NSString’s stringWithString:aRes
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
set aRec to aJsonDict as record
–>  {​​​​​message:"Summarization is completed", ​​​​​status:0, ​​​​​summary:{​​​​​​​"世間的には「Appleが新製品を発表するイベント」と見られているけれども、本来そんなイベントではありません"​​​​​}​​​}

on getAPIKey()
  return "xXXXXXXxXxxxXXxxXxXXXxXxXXxxxxxx"
end getAPIKey

on returnBody()
  return "WWDCというイベントがあります。World Wide Developpers Conference。Appleが1年に一度、開発者を集めて「これからこういう感じのOSにしまっせー」という発表を行う場です。WWDCは例年、カリフォルニア州のモスコーニュ・センターというバカでかいイベント会場で行われます。数千人単位で収容できる会場で、参加者は朝の4~5時ぐらいから並ぶと聞きました。遅く行くと後ろの方のスクリーンから遠い席になるのだとか。世間的には「Appleが新製品を発表するイベント」と見られているけれども、本来そんなイベントではありません。ほかにいろいろイベントがあったのが、WWDCだけ残ったのでたまたま新製品発表があったりするだけの話で、なにが言いたいかといえば、本来はハードウェア製品の発表の場ではなくてOSなどのソフトウェアの(開発者向けの)話をする発表会でした。"
end returnBody

★Click Here to Open This Script 

AppleScript名:summarize
set aStr to returnBody() of me
set bStr to summarize aStr in 1
–> "ほかにいろいろイベントがあったのが、WWDCだけ残ったのでたまたま新製品発表があったりするだけの話で、なにが言いたいかといえば、本来はハードウェア製品の発表の場ではなくてOSなどのソフトウェアの(開発者向けの)話をする発表会でした。"

on returnBody()
  return "WWDCというイベントがあります。World Wide Developpers Conference。Appleが1年に一度、開発者を集めて「これからこういう感じのOSにしまっせー」という発表を行う場です。WWDCは例年、カリフォルニア州のモスコーニュ・センターというバカでかいイベント会場で行われます。数千人単位で収容できる会場で、参加者は朝の4~5時ぐらいから並ぶと聞きました。遅く行くと後ろの方のスクリーンから遠い席になるのだとか。世間的には「Appleが新製品を発表するイベント」と見られているけれども、本来そんなイベントではありません。ほかにいろいろイベントがあったのが、WWDCだけ残ったのでたまたま新製品発表があったりするだけの話で、なにが言いたいかといえば、本来はハードウェア製品の発表の場ではなくてOSなどのソフトウェアの(開発者向けの)話をする発表会でした。"
end returnBody

★Click Here to Open This Script 

Posted in REST API Text URL | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

Finder上で選択中のPDFのファイル名の数字部分で小さいものから大きなものへとソート

Posted on 6月 27, 2018 by Takaaki Naganoya

Finder上で選択中のPDFのうち、ファイル名中の数字が小さいものから大きなものへソートを行うAppleScriptです。

Finder上で選択中のPDFをファイル名順でソートするような用途に使用します。選択中のファイルのうちPDFに該当しないものは無視します。

Finderで選択中の各PDFファイルに数字以外の文字がファイル名に混入していても無視します。

ファイル名はいったん数値として評価してソートするため、ファイル名にゼロパディングしてある場合には無視します。

Finder上で選択中のPDFを連結するさいに、ファイル名順で連結するScriptがあったほうが便利なので、そのために作ったものです。

ソートを行う際に、ファイル名の中の数字以外の部分をすべて無視するようにしています。そのため、Finder上の並び順と関係なく、ファイル名の中の数字部分のみをピックアップしてソートします。Finder自体にもFinderのルールでファイル名をソートして返すAppleScriptの機能がありますが、あれに甘えているとまともな処理はできません。

「test1_0004.pdf」というファイル名があった場合には10004という数値を検出するため、こうしたケースに対応する必要があるかもしれませんが、現時点では無用な数字の除去はしていません(それこそ一括処理で行うものではなくユーザーの目で見て判断してもらうような処理なので)。

AppleScript名:Finder上で選択中のPDFの数字のファイル名で小さいものから大きなものへとソート
— Created 2018-06-26 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use mdLib : script "Metadata Lib" version "1.0.0" –https://www.macosxautomation.com/applescript/apps/
use bPlus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html

property |NSURL| : a reference to current application’s |NSURL|
property NSArray : a reference to current application’s NSArray
property NSPredicate : a reference to current application’s NSPredicate
property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey

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

if inFiles = {} then return

–指定のAlias listのうちPDFのみ抽出
set filRes1 to filterAliasListByUTI(inFiles, "com.adobe.pdf") of me

–ファイル名
set cList to {}
repeat with i in (filRes1 as list)
  set j to contents of i
  
set aFileName to ((current application’s NSString’s stringWithString:j)’s valueForKeyPath:"lastPathComponent.stringByDeletingPathExtension")
  
  
set aNumF to returnNumberCharsOnly(aFileName) of me
  
set the end of cList to {numDat:(aNumF as integer), pathDat:j}
end repeat

set aResList to sortRecListByLabel(cList, "numDat", true) of me –昇順ソート
set bResList to (aResList’s valueForKeyPath:"pathDat") as list of string or string
–>  {​​​​​"/Users/me/Pictures/243.pdf", ​​​​​"/Users/me/Pictures/244.pdf", ​​​​​"/Users/me/Pictures/245.pdf", ​​​​​"/Users/me/Pictures/246.pdf", ​​​​​"/Users/me/Pictures/247.pdf", ​​​​​"/Users/me/Pictures/248.pdf", ​​​​​"/Users/me/Pictures/249.pdf", ​​​​​"/Users/me/Pictures/250.pdf", ​​​​​"/Users/me/Pictures/251.pdf", ​​​​​"/Users/me/Pictures/252.pdf", ​​​​​"/Users/me/Pictures/253.pdf", ​​​​​"/Users/me/Pictures/254.pdf", ​​​​​"/Users/me/Pictures/255.pdf", ​​​​​"/Users/me/Pictures/256.pdf", ​​​​​"/Users/me/Pictures/257.pdf"​​​}

–文字列中から
on returnNumberCharsOnly(aStr)
  set anNSString to current application’s NSString’s stringWithString:aStr
  
set anNSString to anNSString’s stringByReplacingOccurrencesOfString:"[^0-9]" withString:"" options:(current application’s NSRegularExpressionSearch) range:{0, anNSString’s |length|()}
  
return anNSString as text
end returnNumberCharsOnly

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

–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

★Click Here to Open This Script 

Posted in file File path PDF Sort | Tagged 10.11savvy 10.12savvy 10.13savvy Finder | Leave a comment

Recruit Tech Japanese Proofreading API

Posted on 6月 26, 2018 by Takaaki Naganoya

Recruit techのA3RT機械学習ソリューションAPIのひとつ、「Proofreading API」(日本語文章校正API)を呼び出すAppleScriptです。

APIの説明ページからAPI Keyを取得して本リストに記載して実行させてみてください。

「とりあえず作ってみました」レベルで実用性については皆無です。誤変換を指摘できるという触れ込みなのですが、助詞の多重入力、誤変換などほとんど見落としてくれます。

日本語の新語作成能力が高いのと、日本語自体がわりとずさんな運用が行われているといった事情もあり、日本語スペルチェックで完全なものを作れると言い切るには勇気が必要です。

日本語文章のスペルチェックという目的自体が壮大すぎて、実用レベルまで持っていくこと自体が大変です。ある程度の「割り切り」が必要になってくるものと思われます。ただ、このAPIがどういう割り切りを行なったのかが見えてきません、、、

AppleScript名:Recruit Tech Japanese Proofreading API
— Created 2018-06-13 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
–https://a3rt.recruit-tech.co.jp/product/proofreadingAPI/

set apiKeyStr to getAPIKey() of me
set targText to returnBody() of me
set sensitivity to "high"

set sText to "curl -X POST -d ’apikey=" & apiKeyStr & "’ –data-urlencode ’sentence=" & targText & "’ ’sensitivity=" & sensitivity & "’ ’https://api.a3rt.recruit-tech.co.jp/proofreading/v2/typo’"
set aRes to do shell script sText
set jsonString to current application’s NSString’s stringWithString:aRes
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
set aRec to aJsonDict as record
–>  {resultID:"0dee57af118a", status:1, inputSentence:"本来はハードウェア製品のの発表のの場ではなくて、OSなどのソフトベアの話をする発表貝でさた。", normalizedSentence:"本来はハードウェア製品のの発表のの場ではなくて、OSなどのソフトベアの話をする発表貝でさた。", alerts:{{|word|:"貝", suggestions:{"ま", "会", "す"}, score:1.0, pos:41}}, message:"pointed out", checkedSentence:"本来はハードウェア製品のの発表のの場ではなくて、OSなどのソフトベアの話をする発表 <<貝>> でさた。"}

on getAPIKey()
  return "XXXXxXxxXXXxXXXxxxXXxxXXxXXXXXXx"
end getAPIKey

on returnBody()
  return "本来はハードウェア製品のの発表のの場ではなくて、OSなどのソフトベアの話をする発表貝でさた。"
end returnBody

★Click Here to Open This Script 

Posted in Network REST API Text | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

Recruit Tech Small Talk API

Posted on 6月 25, 2018 by Takaaki Naganoya

Recruit techのA3RT機械学習ソリューションAPIのひとつ、「Small Talk API」を呼び出すAppleScriptです。

エンタメ用に機械学習させたお手軽日本語チャットボット作成用のAPIとのこと。APIの説明ページからAPI Keyを取得して本リストに記載して実行させてみてください。

「おはよう」に「おはよう」で返したり、質問に質問で返すような「使えないチャットボットAPI」ですが、雑談系チャットボットに過剰な期待をするのは間違いなので、こんなもんなんでしょう。

AppleScript名:Recruit Tech Talk API
— Created 2018-06-13 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set apiKeyStr to getAPIKey() of me
set targText to text returned of (display dialog "Input Some text" default answer "")

set sText to "curl -X POST -d ’apikey=" & apiKeyStr & "’ –data-urlencode ’query=" & targText & "’ ’https://api.a3rt.recruit-tech.co.jp/talk/v1/smalltalk’"
set aRes to do shell script sText
set jsonString to current application’s NSString’s stringWithString:aRes
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
set aRec to aJsonDict as record
–>  {​​​​​status:0, ​​​​​message:"ok", ​​​​​results:{​​​​​​​{​​​​​​​​​perplexity:0.834903951818, ​​​​​​​​​reply:"何の事でしょう?"​​​​​​​}​​​​​}​​​}
–>  {​​​​​status:2000, ​​​​​message:"empty reply"​​​}

set curStat to status of aRec
if curStat is not equal to 0 then return false
set theAns to (aJsonDict’s valueForKeyPath:"results.reply") as list of string or string
say theAns using "Otoya" –"Kyoko" or "Otoya"

on getAPIKey()
  return "XXXXxxxXxxXXXxXXXxXxxXXxxxXxXxXX"
end getAPIKey

★Click Here to Open This Script 

Posted in Network REST API | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

Call Postmark’s spam detection API

Posted on 6月 21, 2018 by Takaaki Naganoya

PostmarkのSpamAssassin REST APIを呼び出してメールのスパム判定を行うAppleScriptです。

NSURLSessionを用いてPOST methodのREST APIを呼び出しています。

メール本文のソーステキストを渡すと、スパム度のスコアを計算して返してくれます。パラメータの「options」で「short」か「long」を指定でき、最終的な評価値のみ知りたい場合には前者を、詳細情報を知りたい場合には後者を指定することになります。

すでにMail.appにスパム判定の機能が標準搭載されているため、スパムフィルタ単体で利用する用途というのは減ってきましたが、メールの送信前にスパムフィルタに引っかからないかをチェックしておく(メールマガジン作成時など)ためには「あったほうが便利」な処理です。

本APIを利用するのに、事前のユーザー登録やAPI Keyを取得する必要はありません。このリストを実行するとそのまま結果が得られます。Mail.appのメッセージのソースを渡すのもたいして手間はかかりません。

ただし、本APIは継続して提供される保証もありませんし、トラブルが発生して動作が止まっていた場合に対処してくれたりはしません。実際の業務ほかシビアな用途で利用するのはためらわれるものがあります。

ローカルにSpamSieveをインストールしてAppleScriptで呼び出すと同様にスパム評価値を計算してくれるので、メールのSPAM判定のための用途にはこれも検討に値するでしょう。

AppleScript名:Call Postmark’s spam API
— Created 2018-06-20 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.5"
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
property retCode : 0
property retHeaders : 0

set aBody to "raw dump of email"

–https://spamcheck.postmarkapp.com/doc/
set aURL to "https://spamcheck.postmarkapp.com/filter"
set aRec to {email:aBody, options:"long"}

set aRESTres to callRestPOSTAPIAndParseResults(aURL, aRec, 10) of me
set aRESTcode to retCode of aRESTres
–> 200

set aRESTheader to retHeaders of aRESTres
set aRESTres to retData of aRESTres
–> {success:true, rules:{{score:"1.2", |description|:"Missing To: header"}, {score:"-0.0", |description|:"Informational: message was not relayed via SMTP"}, {score:"1.4", |description|:"Missing Date: header"}, {score:"1.8", |description|:"Missing Subject: header"}, {score:"2.3", |description|:"Message appears to have no textual parts and no Subject: text"}, {score:"0.1", |description|:"Missing Message-Id: header"}, {score:"-0.0", |description|:"Informational: message has no Received headers"}, {score:"1.0", |description|:"Missing From: header"}, {score:"0.0", |description|:"Message appears to be missing most RFC-822 headers"}}, score:"7.9", report:" …."}

on callRestPOSTAPIAndParseResults(reqURLStr as string, aRec as record, timeoutSec as integer)
  set retData to missing value
  
set retCode to 0
  
set retHeaders to {}
  
  
set aURL to |NSURL|’s URLWithString:reqURLStr
  
set aRequest to NSMutableURLRequest’s requestWithURL:aURL
  
aRequest’s setHTTPMethod:"POST"
  
aRequest’s setCachePolicy:(current application’s NSURLRequestReloadIgnoringLocalCacheData)
  
aRequest’s setHTTPShouldHandleCookies:false
  
aRequest’s setTimeoutInterval:timeoutSec
  
–aRequest’s setValue:"gzip" forHTTPHeaderField:"Content-Encoding"–Does not work with this API & Method
  
aRequest’s setValue:"application/json" forHTTPHeaderField:"Accept"
  
aRequest’s setValue:"application/json; charset=UTF-8" forHTTPHeaderField:"Content-Type"
  
  
set dataJson to current application’s NSJSONSerialization’s dataWithJSONObject:aRec options:0 |error|:(missing value)
  
aRequest’s setHTTPBody:dataJson
  
  
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
  
  
set hitF to false
  
aTask’s resume() –Start URL Session
  
  
repeat (1000 * timeoutSec) times
    if retData is not equal to missing value then
      set hitF to true
      
exit repeat
    end if
    
delay ("0.001" as real)
  end repeat
  
  
if hitF = false then error "REST API Timeout Error"
  
  
return {retData:retData, retCode:retCode, retHeaders:retHeaders}
end callRestPOSTAPIAndParseResults

on URLSession:tmpSession dataTask:tmpTask didReceiveData:tmpData
  set aRes to tmpTask’s response()
  
set retCode to aRes’s statusCode()
  
set retHeaders to aRes’s allHeaderFields()
  
  
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 –as anything
end URLSession:dataTask:didReceiveData:

★Click Here to Open This Script 

Posted in JSON Network Record REST API URL | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

Bash In Tokyoで音声認識コマンドプログラムをデモしてきました

Posted on 6月 17, 2018 by Takaaki Naganoya

6月15日(金)に渋谷で行われた「Bash In Tokyo」にて、急遽作成した音声認識コマンド実行プログラムをデモしてきました。

macOSの「音声認識コマンド」と「音声文字入力」の中間のような動きをしていて、シソーラス辞書(同義語辞書)を搭載しているため、パラメータの表現の「ゆらぎ」を許容する構造になっています。

GUI部分はXcode上のAppleScriptのプロジェクトであり、呼び出されるコマンド側も(編集可能な)AppleScriptのファイルです。現段階では、コマンド側のAppleScriptのファイル名にコマンドとパラメータを記述してあり、音声認識したテキストを形態素解析して、コマンドやパラメータに該当する品詞の単語をピックアップし、コマンド側の単語とのマッチングを行います。

本プログラムを作成する前に「Web APIでチャットボットなんか使えば楽をできるのでは?」と考えて調査はしてみたものの、結論からいえば「雑談暇つぶしボットぐらいしかできない」という印象でした。お金をかけて作り込めばMicrosoft Bot Frameworkにしても、NTT Communicatins 「COTOHA」にしても使えるとは思うのですが、特定のコマンドキーワードを認識したあとは急に業務系アプリっぽい挙動になったり、コマンド実行の演出とかはとくにないので、「自分で作ったほうがマシ」だということに、、、、デモの前日に気づきました。

# つまり、プログラムのコア部分は1日かけずに作ったという、、、、

もうちょっと調整して何かのデモに使ってみたいところです。

Posted in 未分類 | Leave a comment

GET method REST API v4.1

Posted on 6月 17, 2018 by Takaaki Naganoya

Web上のREST APIを、NSURLSessionを用いて呼び出すAppleScriptの改良版です。

status code、Response Header、処理結果をそれぞれ返すように改良してみました。これで、実際のプログラムに組み込むことができるようになりました。

Response Headerの各フィールドはスペースやハイフンを含んでいたりするので、CocoaのNSDictionaryからAppleScriptのrecordに変換すると値が取り出せなくなってしまいます。

そのため、NSDictionaryのまま返すようにしています。

AppleScript名:GET method REST API v4.1
— Created 2018-06-16 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.5"
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
property retCode : 0
property retHeaders : 0

set reqURLStr to "http://jsonplaceholder.typicode.com/posts"
set aRESTres to callRestGETAPIAndParseResults(reqURLStr, 10) of me
set aRESTcode to retCode of aRESTres
–> 200

set aRESTheader to retHeaders of aRESTres
–>  (NSDictionary) {​​​​​Content-Type:"application/json; charset=utf-8", ​​​​​Pragma:"no-cache", ​​​​​X-Powered-By:"Express", ​​​​​Set-Cookie:"__cfduid=dc7a11359ba7f9518366108f4c2e2d7fb1529215907; expires=Mon, 17-Jun-19 06:11:47 GMT; path=/; domain=.typicode.com; HttpOnly", ​​​​​Server:"cloudflare", ​​​​​Via:"1.1 vegur", ​​​​​Content-Encoding:"gzip", ​​​​​Expires:"Sun, 17 Jun 2018 15:21:12 GMT", ​​​​​CF-Cache-Status:"HIT", ​​​​​Transfer-Encoding:"Identity", ​​​​​Cache-Control:"public, max-age=14400", ​​​​​Date:"Sun, 17 Jun 2018 11:21:12 GMT", ​​​​​Access-Control-Allow-Credentials:"true", ​​​​​Connection:"keep-alive", ​​​​​CF-RAY:"42c5219eb6f2a5cc-NRT", ​​​​​Etag:"W/"6b80-Ybsq/K6GwwqrYkAsFxqDXGC7DoM"", ​​​​​Vary:"Origin, Accept-Encoding", ​​​​​X-Content-Type-Options:"nosniff"​​​}

set aRESTres to retData of aRESTres
–>
(*
{​​​​​{​​​​​​​body:"quia et suscipit
suscipit recusandae consequuntur expedita et cum
reprehenderit molestiae ut ut quas totam
nostrum rerum est autem sunt rem eveniet architecto", ​​​​​​​id:1, ​​​​​​​title:"sunt aut facere repellat provident occaecati excepturi optio reprehenderit", ​​​​​​​userId:1​​​​​},….}
*)

on callRestGETAPIAndParseResults(reqURLStr as string, timeoutSec as integer)
  set retData to missing value
  
set retCode to 0
  
set retHeaders to {}
  
  
set aURL to |NSURL|’s URLWithString:reqURLStr
  
set aRequest to NSMutableURLRequest’s requestWithURL:aURL
  
aRequest’s setHTTPMethod:"GET"
  
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
  
  
set hitF to false
  
aTask’s resume() –Start URL Session
  
  
repeat (1000 * timeoutSec) times
    if retData is not equal to missing value then
      set hitF to true
      
exit repeat
    end if
    
delay ("0.001" as real)
  end repeat
  
  
if hitF = false then error "REST API Timeout Error"
  
  
return {retData:retData, retCode:retCode, retHeaders:retHeaders}
end callRestGETAPIAndParseResults

on URLSession:tmpSession dataTask:tmpTask didReceiveData:tmpData
  set aRes to tmpTask’s response()
  
set retCode to aRes’s statusCode()
  
set retHeaders to aRes’s allHeaderFields()
  
  
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 –as anything
end URLSession:dataTask:didReceiveData:

★Click Here to Open This Script 

Posted in Network REST API | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

GET method REST API v4

Posted on 6月 17, 2018 by Takaaki Naganoya

Web上のREST APIを、NSURLSessionを用いて呼び出すAppleScriptです。

各種REST APIをAppleScriptから呼び出して使うのは、もはや日常的な光景になっていますが、これまでNSURLConnectionを用いていたのが気になっていました。

現在の、Cocoa-BridgeされたAppleScriptではObjective-CのBlocks構文を用いるAPIを呼び出せないために、非同期処理ではなく同期処理を用いる必要があります。NSURLConnectionは明示的に同期処理を呼び出すことができますが、NSURLSessionのサンプルではもれなくBlocks構文が書かれていたので、使えないものかと思っていました。

ただ、それは私・長野谷の単なる思い込みであり、Xcodeでヘッダーファイルを調べてみたらBlocks構文を使わずに書けることがわかったので試してみたものです。呼び出しているのは動作確認用のREST APIで、毎回同じ値を返してきます。

まだ、status codeを受け取れていないので実際の処理に組み込むことはできませんが、きちんと動くコードが書けた意義は大きいでしょう。

AppleScript名:GET method REST API v4
— 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 "http://jsonplaceholder.typicode.com/posts"
set aRESTres to callRestGETAPIAndParseResults(reqURLStr) of me
–>  
(*
{​​​​​{​​​​​​​body:"quia et suscipit
suscipit recusandae consequuntur expedita et cum
reprehenderit molestiae ut ut quas totam
nostrum rerum est autem sunt rem eveniet architecto", ​​​​​​​id:1, ​​​​​​​title:"sunt aut facere repellat provident occaecati excepturi optio reprehenderit", ​​​​​​​userId:1​​​​​}, ​​​​​{​​​​​​​body:"est rerum tempore vitae
sequi sint nihil reprehenderit dolor beatae ea dolores neque
fugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis"}……}
*)

on callRestGETAPIAndParseResults(reqURLStr)
  set aURL to |NSURL|’s URLWithString:reqURLStr
  
set aRequest to NSMutableURLRequest’s requestWithURL:aURL
  
aRequest’s setHTTPMethod:"GET"
  
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
    
delay ("0.001" as real)
  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:

★Click Here to Open This Script 

Posted in Network REST API | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

Numbersのアクティブシート上の表の行数をデータに合わせる

Posted on 6月 13, 2018 by Takaaki Naganoya

Numbersの最前面の書類の選択中のシート(アクティブシート)上の「表」の行数をデータに合わせて変更するAppleScriptです。


▲Before


▲After

表データ上の空白部分を末尾(下)から先頭(上)に向かってサーチし、空白ではない箇所を見つけるまで繰り返します。

AppleScript名:Numbersのアクティブシート上の表の行数をデータに合わせる
— Created 2018-06-12 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use bPlus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html

set tCount to getTableCount() of me

repeat with tableID from 1 to tCount
  
  
–Numbersからデータを取得する
  
set aList to getDataFromNumbersDoc(tableID) of me
  
if aList = false then error "No Data in table " & (tableID as string)
  
  
–Numbersの対象の表の情報を取得
  
set aWidth to getColumnCount(tableID) of me
  
set aHeaderCount to getHeaderCount(tableID) of me
  
set aFooterCount to getFooterCount(tableID) of me
  
  
–Numbersから取得した2D Listのデータからデータの末尾を見つける
  
set aDataRowCount to findDataEnd(aWidth, aHeaderCount, aFooterCount, aList) of me
  
  
tell application "Numbers"
    tell front document
      tell active sheet
        tell table tableID
          set row count to aDataRowCount
        end tell
      end tell
    end tell
  end tell
  
end repeat

–Numbersでオープン中の書類の選択中のシートの表1からデータを取得して2D Listに
on getDataFromNumbersDoc(tableNum as integer)
  
  
load framework
  
  
tell application "Numbers"
    if (count every document) = 0 then return false
    
    
tell front document
      if (count every sheet) = 0 then return false
      
      
tell active sheet
        tell table tableNum
          set colCount to column count
          
set rowCount to row count
          
set headerCount to header row count
          
set footerCount to footer row count
          
          
set dList to value of every cell of cell range
        end tell
      end tell
      
    end tell
  end tell
  
  
–Convert 1D List to 2D List
  
set bList to (current application’s SMSForder’s subarraysFrom:dList groupedBy:colCount |error|:(missing value)) as list
  
set sItem to 1 + headerCount
  
set eItem to rowCount – footerCount
  
set cList to items sItem thru eItem of bList
  
  
return cList
  
end getDataFromNumbersDoc

on getTableCount()
  tell application "Numbers"
    set dCount to count every document
    
if dCount = 0 then error "Numbers: There is No Document"
    
    
tell front document
      tell active sheet
        return (count every table)
      end tell
    end tell
  end tell
end getTableCount

on getHeaderCount(tableID as integer)
  tell application "Numbers"
    tell front document
      tell active sheet
        tell table tableID
          return (header row count)
        end tell
      end tell
    end tell
  end tell
end getHeaderCount

on getFooterCount(tableID as integer)
  tell application "Numbers"
    tell front document
      tell active sheet
        tell table tableID
          return (footer row count)
        end tell
      end tell
    end tell
  end tell
end getFooterCount

on getColumnCount(tableID as integer)
  tell application "Numbers"
    tell front document
      tell active sheet
        tell table tableID
          return (column count)
        end tell
      end tell
    end tell
  end tell
end getColumnCount

–Numbersから取得した2D Arrayのデータ末尾を見つける(ただし、高速化処理を一切していないのでデータ数が数千件を超えると遅くなる)
on findDataEnd(aWidth as integer, aHeaderCount as integer, aFooterCount as integer, aList as list)
  set rAList to reverse of aList –get reverse order list
  
  
set anItem to {}
  
repeat aWidth times
    set the end of anItem to missing value
  end repeat
  
  
set aCount to length of aList
  
set hitF to false
  
  
repeat with i in rAList
    set j to contents of i
    
if j is not equal to anItem then
      set hitF to true
      
exit repeat
    end if
    
set aCount to aCount – 1
  end repeat
  
  
if hitF = false then return false –すべて空(missing value)だった場合には処理打ち切り
  
  
return aCount + aHeaderCount + aFooterCount
end findDataEnd

★Click Here to Open This Script 

Posted in list | Tagged 10.11savvy 10.12savvy 10.13savvy Numbers | Leave a comment

サーバーの移行を行います

Posted on 6月 12, 2018 by Takaaki Naganoya

移行前

Blogのサーバー移行を行います。2018年2月にWordPressの新バージョンに移行した後から、Blogの応答パフォーマンスが低下してきているので(大きな画像をWordPressまかせでサムネール作成させて表示しているのが問題なのか、WordPressそのものに問題があるのか)、高速なサーバーへの移行を行います。

放っておいても8月ぐらいには自動で移行というスケジュールのようですが、またホスティング会社側に全部おまかせで行うと、トラブルが発生すること必至です(状況をまともに説明する能力がないようなので、期待していません)。

なので、一括移行のタイミングよりも前のタイミングで移行の実験を行います。さっそく、1月末のトラブル中に作成したMySQLのユーザーアカウントのうちの1つのパスワードが読み取れないといったエラーが報告されました。

実験用に作成したアカウントだったのでアカウントごと消しましたが、ホスティング会社のWebフォーム上のメニューから作成したアカウントがホスティング会社側のプログラムから読み取れないとは実におかしな話です。

今回のサーバー移行は、同じホスティング会社の古いサーバーから、新しい高速(といわれる)サーバーに移行します。つまり、古いサーバーよりも新しく調達したサーバーの方が仕様的に上なのでアクセスが快適になる、、、、、、という話なのですが、実際に移行してみないとわかりません。

移行後

実際に移行してみましたが、とくに何も問題はないようです。ただ、サーバーを移行してもWordPressの応答速度がたいして上がらなかったので、WordPressのプラグインを外しまくりました。

プラグインによってずいぶんパフォーマンスが落ちていたようです。いまはかなり快適に? つまり、サーバー移行自体はあまり関係なかったようなのですが、あとでモメなくてよかった程度の話でしょうか。

ホスティングしているサーバーのアップデートが計画されているようですが、1台あたりの収容ユーザー数を増やせば、数値どおりのパフォーマンス向上を体感することは難しいことでしょう。

Posted in 未分類 | Leave a comment

Blog Archiveの電子書籍を計画しています

Posted on 6月 11, 2018 by Takaaki Naganoya

「AppleScriptの穴」の内容が、2018年の1月末にBlog開設10年目にして突然消滅。あの悪夢のBlog消失事件から半年近くが経過しました。

消失直後に、AppleScript書類をHTML化してXML-RPC経由でWordPressをコントロールして、BlogにアップロードするAppleScriptを書いて実戦投入。機械的に基礎的なサブルーチンをアップロードし、じょじょに説明文を付加したコンテンツをアップロード。

macOS 10.11以降のScriptを対象に迅速な復旧を行い、意図した範囲でのサイト復旧はできているのかな、という状況です。

一方で、もっと古い時期&OSバージョン向けの情報については、正直なところそれを検証する環境を整備・維持するのが難しい状況です。

そのため、本BlogでもmacOS 10.10以前の情報について再掲載するつもりはありません。

そこで、古い情報のみを集めたBlog Archive本を電子ブックで出版することを計画中です。AppleScriptの穴のフォーマットと同じく、構文色分けを行なったプログラムリストに、クリックすると内容がScript Editorに転送されるURLリンク付き。PDFによる出版のため全文検索で内容をサーチ可能です。

→ Blog Archive Vol.1〜6 発売中

とりあえず1か月分の見出しをリストアップしてみたら、130本ぐらいありました(Blog開設当初で、AppleScriptによる自動投稿プログラムにより連続アップしていました)。2008年3月9日から1年分を拾うだけでも500〜800ページぐらいにはなりそうです(×10年分)。

いまでもOS X 10.4〜10.9あたりを使い続けている方には見逃せない情報になるものと思われます。

なお、Blog復旧&再始動したあとのBlogアーカイブについては、新刊のCocoa Scripting Courseシリーズに各カテゴリのScriptをまとめて添付するため、これがアーカイブに該当することになります。

Posted in Books PRODUCTS Release | Leave a comment

Finderで選択中の画像を右に90度回転

Posted on 6月 11, 2018 by Takaaki Naganoya

Finder上で選択中の画像を右に(時計回りに)90度回転させるAppleScriptです。

Finder上で選択中のファイルのうち、UTIがpublic.imageに含まれるもの(JPEGとかPNGとかTIFFとか)を指定の角度に回転させます。

もともと、選択中のアイテムからファイル種別でオブジェクトを抽出する機能はFinderのものを利用していたのですが、最近のFinderは応答速度が下がっているため、選択中のファイルの取得以外は極力Finderを利用しないのが(macOS 10.10以降の)おすすめです。

macOS標準搭載のScript Menu(フォルダ構造がそのままメニューになり、Scriptをメニューから実行できる)に登録して実行しています。

AppleScript名:Finderで選択中の画像を右に90度回転
— Created 2017-11-21 by Takaaki Naganoya
— Modified 2018-04-06 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.5" — El Capitan (10.11) or later
use framework "Foundation"
use scripting additions

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 NSPredicate : a reference to current application’s NSPredicate
property NSFileManager : a reference to current application’s NSFileManager
property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey

set targDegree to 90 — targDegree have to be in {0, 90, 180, 270, 360} in clockwise

tell application "Finder"
  set inFiles to selection as alias list
end tell
if inFiles = {} then return

–指定のAlias listのうち画像のみ抽出
set filRes1 to filterAliasListByUTI(inFiles, "public.image") of me
if filRes1 = {} then return

–選択中のファイルのうちの1つから親フォルダを求め、出力先ファイルパスを組み立てる
set outPathTarg to POSIX path of (first item of filRes1)
set pathString to current application’s NSString’s stringWithString:outPathTarg
set newPath to (pathString’s stringByDeletingLastPathComponent()) as string

repeat with i in filRes1
  rotateImageandSaveIt(i, targDegree) of me
end repeat

–指定角度に画像を回転させて上書き保存
on rotateImageandSaveIt(this_file, aTargerRect)
  tell application "Image Events"
    launch
    
set this_image to open this_file
    
rotate this_image to angle aTargerRect
    
save this_image with icon
    
close this_image
  end tell
end rotateImageandSaveIt

–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

★Click Here to Open This Script 

Posted in file filter Image | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

数値演算ライブラリ「calcLibAS」v1.3(28倍速)

Posted on 6月 8, 2018 by Takaaki Naganoya

数値演算の関数を35個提供するAppleScript Libraries「calcLibAS」の高速版です。

–> Download calcLibAS (To ~/Library/Script Libraries/)

掘っ建て小屋とか犬小屋みたいな吹けば飛ぶような数値演算ライブラリだったものが、気づけば最初のバージョンから28倍速といったトンでもない状況になっています。ただ、前バージョンとくらべて少し安定性が損なわれているような気がしないでもありません。

計算に速度が求められる用途では、BridgePlusやSatimage OSAXなどを使うのがよいと思いますが、これらのライブラリやOSAXがサポートしていない数値関数が割とあるので(とくにatan2)それを埋めるためだけに本ライブラリは存在しています。

こうしてグラフで比較してみると、C++で書かれたSatimage OSAX、Objective-Cで書かれたCocoa Frameworkと1桁違うぐらいの処理速度でAppleScriptによる(JavaScript処理系呼んでますけど)数値演算ができているのは割とすごいと思います(自分ではなくCPUとかOSとかShane Stanleyの高速化とかが。割と他力本願ライブラリなので)。

本来であれば、AppleがNumbersの関数の充実のために導入した「Cephes Math Library」をNSNumberを介してAppleScriptから呼べるようにラッピングするのがよいのですが(Github上にあるObjectiveCephesは、単にCocoa Framework化しただけでC言語レベルでデータを扱っているのでAppleScriptからは使えない)、割と手間がかかるので「とりあえずJavaScriptの処理系の関数を使えるようにしてみよう」ということで(数時間で)でっち上げた、その場しのぎのためのライブラリです。

AppleScript名:testScript1
— Created 2018-06-06 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use mLib : script "calcLibAS"

set a01Res to calcAbs(-10) of mLib –> 10
set a02Res to calcAcos(-1) of mLib –> 3.14159265359
set a03Res to calcAcosh(10) of mLib –> 2.993222846126
set a04Res to calcAsin(-1) of mLib –> -1.570796326795
set a05Res to calcAsinh(10) of mLib –> 2.998222950298
set a06Res to calcAtan(10) of mLib –> 1.471127674304
set a07Res to calcAtan2(10, 20) of mLib –> 0.463647609001
set a08Res to calcAtanh(0.5) of mLib –> 0.549306144334
set a09Res to calcCbrt(3) of mLib –> 1.442249570307
set a10Res to calcCeil(0.95) of mLib –> 1
set a11Res to calcClz32(1) of mLib –> 31
set a12Res to calcCos(1) of mLib –> 0.540302305868
set a13Res to calcCosh(1) of mLib –> 1.543080634815
set a14Res to calcExp(1) of mLib –> 2.718281828459
set a15Res to calcExpm1(-1) of mLib –> -0.632120558829
set a16Res to calcFloor(45.95) of mLib –> 45
set a17Res to calcFround(1.337) of mLib –> 1.337000012398
set a18Res to calcHypot({3, 4, 5}) of mLib –> 7.071067811865
set a19Res to calcImul(2, 5) of mLib –> 10
set a20Res to calcLog(10) of mLib –> 2.302585092994
set a21Res to calcLog10(2) of mLib –> 0.301029995664
set a22Res to calcLog1p(1) of mLib –> 0.69314718056
set a23Res to calcLog2(3) of mLib –> 1.584962500721
set a24Res to calcMax({1, 2, 3, 4, 6, 2, 10}) of mLib –> 10
set a25Res to calcMin({1, 2, 3, 4, 6, 2, 10, 0}) of mLib –> 0
set a26Res to calcPow(7, 2) of mLib –>  49.0
set a27Res to calcRandom() of mLib –>  0.200867049467
set a28Res to calcRound(5.95) of mLib –>  6.0
set a29Res to calcSign(10) of mLib –> -1/0/1 –> -1.0/0.0/1.0
set a30Res to calcSin(pi / 2) of mLib –> 1–>  1.0
set a31Res to calcSinh(1) of mLib –> 1.175201193644
set a32Res to calcSqrt(2) of mLib –> 1.414213562373
set a33Res to calcTan(30) of mLib –> -6.405331196646
set a34Res to calcTanh(10) of mLib –> 0.999999995878
set a35Res to calcTrunc(13.37) of mLib –> 13 –>  13.0

★Click Here to Open This Script 

AppleScript名:calcLibAS
— Created 2018-06-06 by Takaaki Naganoya
— 2017 Piyomaru Software
–v1.0 First Version。run scriptでJXAを呼び出して計算。連続呼び出し時にクラッシュが頻発
–v1.1 JavaScriptCoreを使用。run script命令をフックして呼び出し。JXA呼び出しをやめて6倍の高速化
–v1.2 JavaScriptCoreを使用。run script命令のフックをやめて若干の高速化
–v1.3 Shane Stanleyによる高速化。JSContextをpropertyにキャッシュして高速化

— Created 2018-06-06 by Takaaki Naganoya
— 2017 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "JavaScriptCore"

property theContext : missing value

–数値の絶対値を返す
on calcAbs(aNum as string)
  set aStr to "Math.abs(" & aNum & ")"
  
return exeJS(aStr)
end calcAbs

–アークコサインをラジアン単位で返す
on calcAcos(aNum as string)
  set aStr to "Math.acos(" & aNum & ")"
  
return exeJS(aStr)
end calcAcos

–ハイパーボリックアークコサインを返す
on calcAcosh(aNum as string)
  set aStr to "Math.acosh(" & aNum & ")"
  
return exeJS(aStr)
end calcAcosh

–アークサインをラジアン単位で返す
on calcAsin(aNum as string)
  set aStr to "Math.asin(" & aNum & ")"
  
return exeJS(aStr)
end calcAsin

–ハイパーボリックアークサインを返す
on calcAsinh(aNum as string)
  set aStr to "Math.asinh(" & aNum & ")"
  
return exeJS(aStr)
end calcAsinh

–アークタンジェントをラジアン単位で返す
on calcAtan(aNum as string)
  set aStr to "Math.atan(" & aNum & ")"
  
return exeJS(aStr)
end calcAtan

–アークタンジェントを返す
on calcAtan2(aNum as string, bNum as string)
  set aStr to "Math.atan2(" & aNum & ", " & bNum & ")"
  
return exeJS(aStr)
end calcAtan2

–ハイパーボリックアークタンジェントを返す
on calcAtanh(aNum as string)
  set aStr to "Math.atanh(" & aNum & ")"
  
return exeJS(aStr)
end calcAtanh

–引数として与えた数の立方根を返す
on calcCbrt(aNum as string)
  set aStr to "Math.cbrt(" & aNum & ")"
  
return exeJS(aStr)
end calcCbrt

–引数として与えた数以上の最小の整数を返す
on calcCeil(aNum as string)
  set aStr to "Math.ceil(" & aNum & ")"
  
return exeJS(aStr)
end calcCeil

–引数として与えた数以上の最小の整数を返す
on calcClz32(aNum as string)
  set aStr to "Math.clz32(" & aNum & ")"
  
return exeJS(aStr)
end calcClz32

–引数として与えた数のコサインを返す
on calcCos(aNum as string)
  set aStr to "Math.cos(" & aNum & ")"
  
return exeJS(aStr)
end calcCos

–引数として与えた数のハイパーボリックコサインを返す
on calcCosh(aNum as string)
  set aStr to "Math.cosh(" & aNum & ")"
  
return exeJS(aStr)
end calcCosh

–Ex を返す。ここでの x は引数、E は、自然対数の底であるネイピア数(オイラー数)
on calcExp(aNum as string)
  set aStr to "Math.exp(" & aNum & ")"
  
return exeJS(aStr)
end calcExp

–ex – 1 を返す。x は引数で、e は自然対数の底
on calcExpm1(aNum as string)
  set aStr to "Math.expm1(" & aNum & ")"
  
return exeJS(aStr)
end calcExpm1

–引数として与えた数以下の最大の整数を返す
on calcFloor(aNum as string)
  set aStr to "Math.floor(" & aNum & ")"
  
return exeJS(aStr)
end calcFloor

–引数として与えた数の最も近い単精度 floatを返す
on calcFround(aNum as string)
  set aStr to "Math.fround(" & aNum & ")"
  
return exeJS(aStr)
end calcFround

–引数の二乗和の平方根を返す
on calcHypot(aList as list)
  set bStr to retArrowText(aList, ", ") of me
  
set aStr to "Math.hypot(" & bStr & ")"
  
return exeJS(aStr)
end calcHypot

— 2 つの引数をとり、C 言語の様な 32 ビット乗算の結果を返す
on calcImul(aNum as string, bNum as string)
  set aStr to "Math.imul(" & aNum & ", " & bNum & ")"
  
return exeJS(aStr)
end calcImul

— 引数として与えた数の自然対数 (底は e) を返す
on calcLog(aNum as string)
  set aStr to "Math.log(" & aNum & ")"
  
return exeJS(aStr)
end calcLog

— 引数として与えた数に対して、10を底とする対数を返す
on calcLog10(aNum as string)
  set aStr to "Math.log10(" & aNum & ")"
  
return exeJS(aStr)
end calcLog10

— 引数として与えた数と 1 の合計の自然対数(底 e)を返す
on calcLog1p(aNum as string)
  set aStr to "Math.log1p(" & aNum & ")"
  
return exeJS(aStr)
end calcLog1p

— 引数として与えた数の2を底とする対数を返す
on calcLog2(aNum as string)
  set aStr to "Math.log2(" & aNum & ")"
  
return exeJS(aStr)
end calcLog2

–引数として与えた複数の数の中で最大の数を返す
on calcMax(aList as list)
  set bStr to retArrowText(aList, ", ") of me
  
set aStr to "Math.max(" & bStr & ")"
  
return exeJS(aStr)
end calcMax

–引数として与えた複数の数の中で最小の数を返す
on calcMin(aList as list)
  set bStr to retArrowText(aList, ", ") of me
  
set aStr to "Math.min(" & bStr & ")"
  
return exeJS(aStr)
end calcMin

–引数として与えた複数の数の中で最小の数を返す
on calcPow(aNum as string, bNum as string)
  set aStr to "Math.pow(" & aNum & ", " & bNum & ")"
  
return exeJS(aStr)
end calcPow

–(0以上、1未満)の範囲で浮動小数点の擬似乱数を返す
on calcRandom()
  set aStr to "Math.random()"
  
return (run script aStr in "JavaScript")
end calcRandom

–引数として与えた数を四捨五入して、もっとも近似の整数を返す
on calcRound(aNum as string)
  set aStr to "Math.round(" & aNum & ")"
  
return exeJS(aStr)
end calcRound

–引数として与えた数が正、負、0 のどれであるか示す符号を返す
on calcSign(aNum as string)
  set aStr to "Math.sign(" & aNum & ")"
  
return exeJS(aStr)
end calcSign

–引数として与えた数のサイン(正弦)を返す
on calcSin(aNum as string)
  set aStr to "Math.sin(" & aNum & ")"
  
return exeJS(aStr)
end calcSin

–引数として与えた数のハイパーボリックサインを返す
on calcSinh(aNum as string)
  set aStr to "Math.sinh(" & aNum & ")"
  
return exeJS(aStr)
end calcSinh

–引数として与えた数の平方根を返す
on calcSqrt(aNum as string)
  set aStr to "Math.sqrt(" & aNum & ")"
  
return exeJS(aStr)
end calcSqrt

–引数として与えた数のタンジェントを返す
on calcTan(aNum as string)
  set aStr to "Math.tan(" & aNum & ")"
  
return exeJS(aStr)
end calcTan

–引数として与えた数のハイパーボリックタンジェントを返す
on calcTanh(aNum as string)
  set aStr to "Math.tanh(" & aNum & ")"
  
return exeJS(aStr)
end calcTanh

–引数として与えた数の小数部の桁を取り除いて整数部を返す
on calcTrunc(aNum as string)
  set aStr to "Math.trunc(" & aNum & ")"
  
return exeJS(aStr)
end calcTrunc

–Sub Routines

–リストを指定デリミタをはさんでテキスト化
on retArrowText(aList, aDelim) –自分のASでよく使うハンドラ名称なので、同じものを用意
  set anArray to current application’s NSArray’s arrayWithArray:aList
  
set aRes to anArray’s componentsJoinedByString:aDelim
  
return aRes as text
end retArrowText

–JavaScriptCore版実行部
on exeJS(aStr)
  return (myContext()’s evaluateScript:aStr)’s toDouble()
end exeJS

on myContext()
  if theContext = missing value then set theContext to current application’s JSContext’s new()
  
return theContext
end myContext

★Click Here to Open This Script 

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

数値演算ライブラリ「calcLibAS」v1.2(6倍速)

Posted on 6月 7, 2018 by Takaaki Naganoya

数値演算の関数を35個提供するAppleScript Libraries「calcLibAS」の高速・安定化版です。

–> Download calcLibAS (To ~/Library/Script Libraries/)


▲atan2 calculation comparison

前バージョンのv1.0よりも6倍高速で、JXAの利用をやめてJavaScript Coreに切り替えたため、数百回呼び出したときでもクラッシュすることがなくなりました(ひどい場合だと数回でクラッシュしていたため、JXAを外せて本当によかったです。run scriptコマンドがひどいのかもしれませんが)。

v1.1ではrun scriptコマンドをのっとってJavaScript Coreを呼び出していましたが、v1.2ではrun scriptコマンドの利用をやめてすべてサブルーチン呼び出しに書き換えたので、若干高速化しました。

JavaScript CoreのほかWebKit経由でもJavaScriptの実行は行えますが、WebKitではメインスレッドでの実行が求められたため、JavaScript Coreを使用しています。ただし、このためかどうかわかりませんが、macOS 10.13の環境で本Scriptを実行したときにSafariのJavaScriptデバッグ画面が実行回数だけオープンするという怪奇現象に直面しました。Safariを起動していない場合には発生しませんし、テスト環境では2度目以降は発生していません。ご注意ください。

AppleScript名:calcLibAS
— Created 2018-06-06 by Takaaki Naganoya
— 2017 Piyomaru Software
–v1.0 First Version。run scriptでJXAを呼び出して計算。連続呼び出し時にクラッシュが頻発
–v1.1 JavaScriptCoreを使用。run script命令をフックして呼び出し。JXA呼び出しをやめて6倍の高速化
–v1.2 JavaScriptCoreを使用。run script命令のフックをやめて若干の高速化
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "JavaScriptCore"

set a01Res to calcAbs(-10) of me –> 10
set a02Res to calcAcos(-1) of me –> 3.14159265359
set a03Res to calcAcosh(10) of me –> 2.993222846126
set a04Res to calcAsin(-1) of me –> -1.570796326795
set a05Res to calcAsinh(10) of me –> 2.998222950298
set a06Res to calcAtan(10) of me –> 1.471127674304
set a07Res to calcAtan2(10, 20) of me –> 0.463647609001
set a08Res to calcAtanh(0.5) of me –> 0.549306144334
set a09Res to calcCbrt(3) of me –> 1.442249570307
set a10Res to calcCeil(0.95) of me –> 1
set a11Res to calcClz32(1) of me –> 31
set a12Res to calcCos(1) of me –> 0.540302305868
set a13Res to calcCosh(1) of me –> 1.543080634815
set a14Res to calcExp(1) of me –> 2.718281828459
set a15Res to calcExpm1(-1) of me –> -0.632120558829
set a16Res to calcFloor(45.95) of me –> 45
set a17Res to calcFround(1.337) of me –> 1.337000012398
set a18Res to calcHypot({3, 4, 5}) of me –> 7.071067811865
set a19Res to calcImul(2, 5) of me –> 10
set a20Res to calcLog(10) of me –> 2.302585092994
set a21Res to calcLog10(2) of me –> 0.301029995664
set a22Res to calcLog1p(1) of me –> 0.69314718056
set a23Res to calcLog2(3) of me –> 1.584962500721
set a24Res to calcMax({1, 2, 3, 4, 6, 2, 10}) of me –> 10
set a25Res to calcMin({1, 2, 3, 4, 6, 2, 10, 0}) of me –> 0
set a26Res to calcPow(7, 2) of me –>  49.0
set a27Res to calcRandom() of me –>  0.200867049467
set a28Res to calcRound(5.95) of me –>  6.0
set a29Res to calcSign(10) of me –> -1/0/1 –> -1.0/0.0/1.0
set a30Res to calcSin(pi / 2) of me –> 1–>  1.0
set a31Res to calcSinh(1) of me –> 1.175201193644
set a32Res to calcSqrt(2) of me –> 1.414213562373
set a33Res to calcTan(30) of me –> -6.405331196646
set a34Res to calcTanh(10) of me –> 0.999999995878
set a35Res to calcTrunc(13.37) of me –> 13 –>  13.0

–数値の絶対値を返す
on calcAbs(aNum as string)
  set aStr to "Math.abs(" & aNum & ")"
  
return exeJS(aStr)
end calcAbs

–アークコサインをラジアン単位で返す
on calcAcos(aNum as string)
  set aStr to "Math.acos(" & aNum & ")"
  
return exeJS(aStr)
end calcAcos

–ハイパーボリックアークコサインを返す
on calcAcosh(aNum as string)
  set aStr to "Math.acosh(" & aNum & ")"
  
return exeJS(aStr)
end calcAcosh

–アークサインをラジアン単位で返す
on calcAsin(aNum as string)
  set aStr to "Math.asin(" & aNum & ")"
  
return exeJS(aStr)
end calcAsin

–ハイパーボリックアークサインを返す
on calcAsinh(aNum as string)
  set aStr to "Math.asinh(" & aNum & ")"
  
return exeJS(aStr)
end calcAsinh

–アークタンジェントをラジアン単位で返す
on calcAtan(aNum as string)
  set aStr to "Math.atan(" & aNum & ")"
  
return exeJS(aStr)
end calcAtan

–アークタンジェントを返す
on calcAtan2(aNum as string, bNum as string)
  set aStr to "Math.atan2(" & aNum & ", " & bNum & ")"
  
return exeJS(aStr)
end calcAtan2

–ハイパーボリックアークタンジェントを返す
on calcAtanh(aNum as string)
  set aStr to "Math.atanh(" & aNum & ")"
  
return exeJS(aStr)
end calcAtanh

–引数として与えた数の立方根を返す
on calcCbrt(aNum as string)
  set aStr to "Math.cbrt(" & aNum & ")"
  
return exeJS(aStr)
end calcCbrt

–引数として与えた数以上の最小の整数を返す
on calcCeil(aNum as string)
  set aStr to "Math.ceil(" & aNum & ")"
  
return exeJS(aStr)
end calcCeil

–引数として与えた数以上の最小の整数を返す
on calcClz32(aNum as string)
  set aStr to "Math.clz32(" & aNum & ")"
  
return exeJS(aStr)
end calcClz32

–引数として与えた数のコサインを返す
on calcCos(aNum as string)
  set aStr to "Math.cos(" & aNum & ")"
  
return exeJS(aStr)
end calcCos

–引数として与えた数のハイパーボリックコサインを返す
on calcCosh(aNum as string)
  set aStr to "Math.cosh(" & aNum & ")"
  
return exeJS(aStr)
end calcCosh

–Ex を返す。ここでの x は引数、E は、自然対数の底であるネイピア数(オイラー数)
on calcExp(aNum as string)
  set aStr to "Math.exp(" & aNum & ")"
  
return exeJS(aStr)
end calcExp

–ex – 1 を返す。x は引数で、e は自然対数の底
on calcExpm1(aNum as string)
  set aStr to "Math.expm1(" & aNum & ")"
  
return exeJS(aStr)
end calcExpm1

–引数として与えた数以下の最大の整数を返す
on calcFloor(aNum as string)
  set aStr to "Math.floor(" & aNum & ")"
  
return exeJS(aStr)
end calcFloor

–引数として与えた数の最も近い単精度 floatを返す
on calcFround(aNum as string)
  set aStr to "Math.fround(" & aNum & ")"
  
return exeJS(aStr)
end calcFround

–引数の二乗和の平方根を返す
on calcHypot(aList as list)
  set bStr to retArrowText(aList, ", ") of me
  
set aStr to "Math.hypot(" & bStr & ")"
  
return exeJS(aStr)
end calcHypot

— 2 つの引数をとり、C 言語の様な 32 ビット乗算の結果を返す
on calcImul(aNum as string, bNum as string)
  set aStr to "Math.imul(" & aNum & ", " & bNum & ")"
  
return exeJS(aStr)
end calcImul

— 引数として与えた数の自然対数 (底は e) を返す
on calcLog(aNum as string)
  set aStr to "Math.log(" & aNum & ")"
  
return exeJS(aStr)
end calcLog

— 引数として与えた数に対して、10を底とする対数を返す
on calcLog10(aNum as string)
  set aStr to "Math.log10(" & aNum & ")"
  
return exeJS(aStr)
end calcLog10

— 引数として与えた数と 1 の合計の自然対数(底 e)を返す
on calcLog1p(aNum as string)
  set aStr to "Math.log1p(" & aNum & ")"
  
return exeJS(aStr)
end calcLog1p

— 引数として与えた数の2を底とする対数を返す
on calcLog2(aNum as string)
  set aStr to "Math.log2(" & aNum & ")"
  
return exeJS(aStr)
end calcLog2

–引数として与えた複数の数の中で最大の数を返す
on calcMax(aList as list)
  set bStr to retArrowText(aList, ", ") of me
  
set aStr to "Math.max(" & bStr & ")"
  
return exeJS(aStr)
end calcMax

–引数として与えた複数の数の中で最小の数を返す
on calcMin(aList as list)
  set bStr to retArrowText(aList, ", ") of me
  
set aStr to "Math.min(" & bStr & ")"
  
return exeJS(aStr)
end calcMin

–引数として与えた複数の数の中で最小の数を返す
on calcPow(aNum as string, bNum as string)
  set aStr to "Math.pow(" & aNum & ", " & bNum & ")"
  
return exeJS(aStr)
end calcPow

–(0以上、1未満)の範囲で浮動小数点の擬似乱数を返す
on calcRandom()
  set aStr to "Math.random()"
  
return (run script aStr in "JavaScript")
end calcRandom

–引数として与えた数を四捨五入して、もっとも近似の整数を返す
on calcRound(aNum as string)
  set aStr to "Math.round(" & aNum & ")"
  
return exeJS(aStr)
end calcRound

–引数として与えた数が正、負、0 のどれであるか示す符号を返す
on calcSign(aNum as string)
  set aStr to "Math.sign(" & aNum & ")"
  
return exeJS(aStr)
end calcSign

–引数として与えた数のサイン(正弦)を返す
on calcSin(aNum as string)
  set aStr to "Math.sin(" & aNum & ")"
  
return exeJS(aStr)
end calcSin

–引数として与えた数のハイパーボリックサインを返す
on calcSinh(aNum as string)
  set aStr to "Math.sinh(" & aNum & ")"
  
return exeJS(aStr)
end calcSinh

–引数として与えた数の平方根を返す
on calcSqrt(aNum as string)
  set aStr to "Math.sqrt(" & aNum & ")"
  
return exeJS(aStr)
end calcSqrt

–引数として与えた数のタンジェントを返す
on calcTan(aNum as string)
  set aStr to "Math.tan(" & aNum & ")"
  
return exeJS(aStr)
end calcTan

–引数として与えた数のハイパーボリックタンジェントを返す
on calcTanh(aNum as string)
  set aStr to "Math.tanh(" & aNum & ")"
  
return exeJS(aStr)
end calcTanh

–引数として与えた数の小数部の桁を取り除いて整数部を返す
on calcTrunc(aNum as string)
  set aStr to "Math.trunc(" & aNum & ")"
  
return exeJS(aStr)
end calcTrunc

–Sub Routines

–リストを指定デリミタをはさんでテキスト化
on retArrowText(aList, aDelim) –自分のASでよく使うハンドラ名称なので、同じものを用意
  set anArray to current application’s NSArray’s arrayWithArray:aList
  
set aRes to anArray’s componentsJoinedByString:aDelim
  
return aRes as text
end retArrowText

–JavaScriptCore版実行部
on exeJS(aStr)
  set theContext to current application’s JSContext’s alloc()’s init()
  
set x to (theContext’s evaluateScript:aStr)’s toNumber()
  
return x as list of string or string –as anything
end exeJS

★Click Here to Open This Script 

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

Post navigation

  • Older posts
  • Newer posts

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

Google Search

Popular posts

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

Tags

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

カテゴリー

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

アーカイブ

  • 2025年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