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

月: 2020年1月

2020/2/8のTMUG例会で「Kamenoko」のデモをします

Posted on 1月 31, 2020 by Takaaki Naganoya

2020/2/8(土)に東京都目黒区 目黒区民センター内の中小企業センター 2F第二集会室において行われる東京マッキントッシュユーザーズグループ(TMUG)の2月度例会において、本Blogでもちょくちょく作例が載っているHex-cell Mapの作成アプリケーション「Kamenoko」のデモを行います。

すべてAppleScriptで記述している、グラフというか「図」の作成アプリケーションで、アウトラインプロセッサやマインドマップにはない、プレゼン向きの図の作成や、図を作りながら対話的にアイデアをまとめていけるツールになる(んじゃないかなぁ)と期待しています。英語ネイティブの友人に

ぴ:「これ、一般的にはなんて呼ぶの?」
友:「Graphics」

あれか? 和菓子もシュークリームも、全部『Cake』って呼ぶアレなのか?! というわけで、日本語訳として「図」。独自の用語で「Hex-cell Graphics」と呼んでいる、概念階層レベル色分けマインドマップ的なものをAppleScriptで作ってみた(最中)です。

ご興味のある方は、ぜひこの機会にご参加ください!(事前登録とか別にしなくてもけっこうですので)

日時:2020/2/8(土) 14:00〜17:00(開場14:00、開始14:30)
場所:目黒区民センター内中小企業センター2階第2集会室
東京都目黒区目黒2-4-36/03-3711-1135


▲当時のKamenokoは、フォント変更、書類保存、環境設定などが一切できない「おかわいらしい」ツールでしかありませんでした


▲Xcodeプロジェクトも非常にシンプル。まだ440行ほどのapplescriptファイルが1個しかありません(当時)

(Visited 70 times, 1 visits today)
Posted in イベント(Event) | Leave a comment

電子ブック年度末フェア実施中!

Posted on 1月 29, 2020 by Takaaki Naganoya

ぴよまるソフトウェアでは、本日より2020/3/31までの間、Piyomaru SoftwareがBOOTH上にて販売している電子ブックをお買い上げの方に、もれなく「Piyomaru Script Assistant v.2.0βお試し版」を配布するキャンペーンを開始いたしました。

Piyomaru Script Assistantは、スクリプトエディタのコンテクストメニューから呼び出すAppleScript記述補助ツール群「Script Assistant」の改良強化版です。


▲左:Apple純正のScript Assistant、右:Piyomaru Script Assistant v2.0

2004年ごろに作成し、以来ずっと個人的にメンテナンスを続けてきた、いわゆる「秘伝のタレ」でしたが、「AppleScript最新リファレンス」「AppleScript 10大最新技術」の刊行時に購入特典としてオマケで配布。これがPiyomaru Script Assistant v.1.0(以下、PSA v1.0と略)です。

その後、時はながれ、macOS 10.13の時代になってこのPSA v1.0のうち動かないScriptが出てきており、さらに2000年代初頭に作成したため「Cocoaの機能を呼び出さないのはおかしい」「いまならもっとスゲーことが普通にできている」と、時代に合わなくなってきました。

# 基礎的なScriptを自動入力できるという意味では、ねらいどおりなのですが、、、

そこで、昨年よりPSAのv.2.0を企画して実装を開始。ちょくちょく画面のスナップショットが掲載されているアレです。

PSA v2.0はv1.0よりもはるかに強力で、さまざまなOSの力を引き出す構成になっており、たとえばメニューバーに常駐するメニューなどもコンテクストメニューから一発入力できるようになっています。AirDropによる編集中のAppleScript書類の共有なども組み込まれています。ほぼ、内容的にはv1.0とは別物です。

このPSA v.2.0のβ版に対するご意見をいただきたいので、macOS 10.14以降の環境をお持ちで、該当期間中にPiyomaru Softwareの電子書籍をご購入いただいた方に、このPSA v2.0の評価キット(実際に使えます)を差し上げます。

同封のアンケートにお答えいただければ、PSA v.2.0の強力な機能をお試しいただけます。

この機会にふるってご応募ください!

応募方法:ご購入後にmaro@piyocast.comまで、「年度末フェア」のタイトルで購入お知らせメールをいただければ、ダウンロード先の情報をご返送いたします。

なお、普通に購入特典の希望メールをいただいた場合でも、「年度末フェア」のご案内を申し上げます。

(Visited 84 times, 1 visits today)
Posted in PRODUCTS | Leave a comment

eppcで他のMac上のアプリケーション操作

Posted on 1月 26, 2020 by Takaaki Naganoya

MacScripterのフォーラムでeppcについての質問があったので回答していました。eppcを用いて、ネットワーク上の他のMacを操作する件についての話でした。

eppcは、Remote AppleEventのプロトコル表記であり、自分のマシン上のアプリケーションだと、

application "Finder"

と表記しますが、他のMac上のアプリケーションだと、

application "Finder" of machine "eppc://user:password@machineName.local"

という表記になります。パスワードを書いておかないとダイアログで問い合わせが行われるので、書かなくてもいいです(パスワードが丸裸で書いてあるのは不用心なので、テスト時以外はおすすめしません)。

自分の認識では、ネットワーク上の他のマシンの操作については、

のような認識でした。この認識は間違っているわけではなく、リモートのアプリケーション操作はリモート側のアプレットに行わせるようにして、自分からはリモート側のアプレットのハンドラを呼び出すのがリモートアプリケーション操作の基本的な「作法」です。

GUIアプリケーションを直接操作するのは無理だけど、AppleScriptアプレットを常駐させておいて、アプレットのハンドラを呼び出すことで、各リモートマシン上のアプリケーションを操作できる、と。

で、これが他のメンバーのコメントで(リモートアプリケーションのダイレクト呼び出しは)「macOS 10.15でもできるぞ」という話が出てきて、腰を抜かしました。現状の自分のマシン環境(古いのばっかりですが)で検証してみたところ、たしかに(若干の癖はありますが)、GUIアプリケーションを直接操作できて驚きました(セキュリティ上の制約がいろいろあるので、ローカルでできることすべてがリモートアプリケーションに直接司令できるわけではありません)。


▲テストに用いたMac OS X 10.6.8環境


▲テストに用いたMac OS X 10.7.5環境


▲テストに用いたMac OS X 10.13.6環境

Mac OS X 10.6からmacOS 10.12あたり(厳密には確認できていない)の環境では、明確にリモートAppleEventに制約が加わっていました。

ところが、macOS 10.13あたり(10.12かも。このあたり未確認)から、eppcでGUIアプリケーションの操作ができることが確認できました。

macOS Version Direct eppc to GUI Apps
10.0 (No AppleScript Env)
10.1 Works????
10.2 Works
10.3 Works
10.4 Works
10.5 (???)
10.6 Not Work
10.7 Not Work
10.8 Not Work
10.9 Not Work
10.1 Not Work
10.11 Not Work
10.12 (??? Maybe not work)
10.13 Works
10.14 Works
10.15 Works

eppcのポート

eppcがTCP/IPのどこのポート番号を用いているかは、/etc/servicesを見ると書いてあります。

eppc            3031/udp    # Remote AppleEvents/PPC Toolbox
eppc            3031/tcp    # Remote AppleEvents/PPC Toolbox

なので、VPN接続時にこれらのポートが開いていれば、相手側のマシンをAppleScriptで遠隔操作できることになります(実際には、ファイル共有とかいろいろその他の付随するポートを開けておく必要があるわけですが)。

リモート操作の傾向

ただし、ローカルマシン上のアプリケーションを操作するのと比較して、いくつかの挙動の違いも見られます。

(1)アプリケーションの直接的な起動が効かない

各GUIアプリケーションに「activate」とか「launch」コマンドを送っても無視されます。リモートマシン上でいったんアプリケーションが起動した後に「activate」で最前面に持ってくることは可能ですが、起動していない状態でactivateを実行しても、起動は行われません。

AppleScript名:他のマシン上でSafariを起動
set RemoteMachine to "eppc://me@MacMini2014.local"

using terms from application "Finder"
  tell application "Finder" of machine RemoteMachine
    open application file id "com.apple.Safari"
  end tell
end using terms from

★Click Here to Open This Script 

Finder経由でBundle IDを指定して「application fileをオープンする」という指定であれば、たしかにアプリケーションが起動します。

(2)System Eventsの操作に難あり

面白くなっていろいろリモートアプリケーションを操作していてわかってきたのですが、初期状態だとSystem Eventsが起動していない状態です。いえ、ローカルでもSystem Eventsは常時起動してはいないんでしょうけれど、命令を発行すると自動で起動されます。

この自動起動とか明示的に指定して起動といった操作が受け付けられないので、Finder経由で間接的にapplication fileのオープンというかたちでSystem Eventsの起動を行い、処理を依頼します。

このリモートマシン上のSystem Eventsはしばらく処理が行われないと自動で終了するようなので、何かまとまった処理をSystem Eventsに行わせる前には明示的に起動を司令しておくべきなんでしょう。

AppleScript名:他のマシン上のSystem Eventsを起動する
set RemoteMachine to "eppc://me@MacMini2014.local"

using terms from application "Finder"
  tell application "Finder" of machine RemoteMachine
    open application file id "com.apple.SystemEvents"
  end tell
end using terms from

★Click Here to Open This Script 

(3)けっこう動く

GUIアプリケーションの代表としてSafariを実際に操作してみたところ、

Safariのバージョン名の取得、できました。

AppleScript名:他のマシン上で起動しているアプリケーションのバージョンを取得
set RemoteMachine to "eppc://me@MacMini2014.local"

using terms from application "Safari"
  tell application "Safari" of machine RemoteMachine
    version
  end tell
end using terms from

★Click Here to Open This Script 

Safariの新規ウィンドウの作成、できました。

AppleScript名:他のマシン上で起動しているSafariで新規ウィンドウ作成
set RemoteMachine to "eppc://me@MacMini2014.local"

using terms from application "Safari"
  tell application "Safari" of machine RemoteMachine
    make new document
  end tell
end using terms from

★Click Here to Open This Script 

SafariのウィンドウのURLの取得、できました。

AppleScript名:他のマシン上で起動しているSafariの最前面のウィンドウのURLを取得
set RemoteMachine to "eppc://me@MacMini2014.local"

using terms from application "Safari"
  tell application "Safari" of machine RemoteMachine
    set aURL to URL of front document
  end tell
end using terms from

★Click Here to Open This Script 

SafariのウィンドウのURLの書き換え、できました。

AppleScript名:他のマシン上で起動しているSafariのウィンドウのURLを書き換える
set RemoteMachine to "eppc://me@MacMini2014.local"

using terms from application "Safari"
  tell application "Safari" of machine RemoteMachine
    set URL of document 1 to "http://piyocast.com/as/"
  end tell
end using terms from

★Click Here to Open This Script 

Safariの最前面のウィンドウの内容をメールに転送、できました。

AppleScript名:他のマシン上で起動しているSafariの最前面の内容をメール
set RemoteMachine to "eppc://me@MacMini2014.local"

using terms from application "Safari"
  tell application "Safari" of machine RemoteMachine
    make new document
    
set URL of front document to "http://www.apple.com"
    
delay 3 –wait for page loading
    
email contents of front document
  end tell
end using terms from

★Click Here to Open This Script 

Safariのページローディング検出はいろいろ蓄積されているノウハウもありますが、do javascriptコマンドが問題なく動くレベルまで信用できるのかわからなかったので、delayで単純に時間待ちしています。

実際に動かしてみて、自分がビビるぐらいeppcでリモートアプリケーションの操作ができてしまいました。SIPだとかアプリケーション権限だとかでセキュリティ機能でがんじがらめにされている今日このごろですが、eppc経由でリモートマシン上のアプリケーション操作が緩和されている事実にビビりました。

これはおそらくですが、Xcode上のリモートデバッグとか、そういうあたりの機能の実装時に機能がeppcまわりの機能が再実装されたかコメントアウトしていた箇所が復活したかという話に見えます。

(Visited 249 times, 1 visits today)
Posted in Remote Control | Tagged 10.13savvy 10.14savvy 10.15savvy Safari | Leave a comment

GUI Scriptingでコンテクストメニューのキャプチャを取得

Posted on 1月 24, 2020 by Takaaki Naganoya

GUI Scriptingを用いてスクリプトエディタ上でコンテクストメニューを表示させて、コンテクストメニューのキャプチャを行うAppleScriptです。macOS 10.14.6上で試しただけなので、10.15上では試していません(たぶん動くと思うのですが)。

–> Watch Demo Movie

画面キャプチャをNSImageに取得する機能については、DSCapture.frameworkをビルドして、AppleScript(実行環境はScript Debugger)から呼び出しています。

–> Download DSCapture.framework (To ~/Library/Frameworks/)

AppleScriptの鬼っ子機能である「GUI Scripting」。ある顧客が「キーボードショートカットとキーボード操作をそのままScript化することでこれを作れ」という仕様を出してきて、とても実現できない内容がまだらに含まれていたので「ナイスジョーク!」と却下した記憶があります。

「できること」(キーボードショートカット操作)に「できないこと」(目視で当該データの位置確認)を混ぜて仕様を出されると悪夢でしかありません。

あと、GUI Scriptingで操作を行うと信頼性がないうえに、信頼性を確保するためには「待つ」という処理が必要だったり、本来のAppleScriptの処理速度よりも100倍以上遅くなるので、本当に必要な箇所にだけ使う&可能なかぎり使用しないというのが自分の基本的なスタンスです。

コンテクストメニューの画面キャプチャを自動で

そんな中、新型Piyomaru Script Assistant(macOS 10.14以降対応。10.13は無視)の資料を作るために、コンテクストメニューの内容を画面キャプチャする必要に迫られました。

AppleScriptが500個ぐらい、階層化されたメニューに入っているので、これの画面キャプチャを撮るだけで一仕事です。テストで1階層分の資料を作ってみたのですが、けっこうかかります。

そこで、スクリプトエディタ上で表示させたコンテクストメニューをプログラムで撮れないかを検討することになります。

真っ先に調べたのはCocoaにそういう機能がないかどうか。自前のプログラムのビューの内容をキャプチャすることはできますが、他のアプリケーションのビューをキャプチャする機能は見つかりませんでした。

仕方がないので、画面のキャプチャをまるごと取得して、撮影対象のビューの座標から画像の切り抜きを行うようにしてみました。

GUI Scriptingでコンテクストメニューを表示させるのは無理かと思っていたのですが、できるんですね。これも冗談半分で探してみたらあっけなく方法が見つかって、

tell theTarget to perform action "AXShowMenu" --コンテクストメニューの表示

これで実際にコンテクストメニューの表示を行えました。

実現はいろいろ大変

スクリプトエディタ上の画面撮影を行うので、Scriptの実行そのものはScript Debuggerで実行。

問題になったのは2点。

1つは、画面キャプチャの撮影を行うフレームワークでメインディスプレイから画面イメージをNSImageで取得し、その結果をメイン側(暗黙のrunハンドラといったほうがいいのか)のプロパティに返しているのですが、すぐに反映されないらしくて、クラッシュを頻発。

結局、プロパティに内容が反映されたことをループで時間待ちして受信。

もう1つ困った点は、コンテクストメニューの表示解除(キャンセル)。1つのコンテクストメニュー表示&キャプチャ撮影だけでは意味がありません。選択メニュー項目を変更して、複数のコンテクストメニューのキャプチャを順次行えなくてはなりません。

いろいろな方法を試してみたものの、最前面のアプリケーションを「スクリプトエディタ」でない状態を作ればコンテクストメニュー表示状態は解除されます(このあたり、AppleScriptが純粋なプログラマーに苦手とされる理由。実際に使っているユーザーでないとこういう発想自体が出てこない)。Script Debugger側で実行しているので、Script Debuggerをactivateすることでその状態(コンテクストメニュー表示解除)を作ってみました。

そんなわけでコンテクストメニューの(選択項目を変更して全項目を選択状態にした)画面キャプチャができました。

現在は1階層分のコンテクストメニューの撮影を行なっていますが、メニュー階層をすべてAppleScript側からスキャンして、それぞれのメニューに対して、各メニュー項目を表示した状態で巡回キャプチャできるとよさそうです。

cropNSImageTo:{x1, y1, x2, y2} fromImage:theImage ハンドラは、Y座標の変換をこの用途(全画面キャプチャしたNSImageの切り抜き)の帳尻合わせのために書き換えています。この用途以外では使えないはずです。

AppleScript名:GUI Scriptingで指定したGUI部品のキャプチャを取得.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/01/24
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "DSCapture" –https://github.com/kiding/DSCapture.framework
use framework "AppKit"
use scripting additions

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

property targPos : {0, 0}
property targSize : {0, 0}
property screenSize : {}
property outPath : ""
property captImg : missing value

set (my captImg) to missing value

tell application "System Events"
  tell process "スクリプトエディタ" –"Script Editor" (Japanese localized name)
    –Editor Area Reference
    
set theTarg to text area 1 of scroll area 1 of splitter group 1 of splitter group 1 of window 1
  end tell
end tell

repeat with i from 1 to 19
  
  
set captImg to missing value
  
set outPath to (POSIX path of (path to desktop)) & ((NSUUID’s UUID()’s UUIDString()) as string) & ".png"
  
  
set {mPos, mSize} to dispMenu(i, theTarg) of me
  
copy mPos to {cx1, cy1}
  
copy mSize to {cWidth, cHeight}
  
  
screenCapture() of me
  
  
repeat 100 times
    if (my captImg) is not equal to missing value then exit repeat
    
delay 0.1
  end repeat
  
  
  
set bImg to (my cropNSImageTo:{cx1, cy1, cWidth, cHeight} fromImage:(my captImg))
  
saveNSImageAtPathAsPNG(bImg, my outPath) of me
  
  
tell current application to activate –Cancel Context Menu
  
delay 0.1
end repeat

on screenCapture()
  current application’s DSCapture’s sharedCapture()’s |full|()’s captureWithTarget:me selector:"displayCaptureData:" useCG:false
end screenCapture

–Delegate Handler
on displayCaptureData:aSender
  set aCount to aSender’s |count|()
  
set anImage to (aSender’s imageAtIndex:0)
  
set my captImg to anImage
  
–saveNSImageAtPathAsPNG(anImage, my outPath) of me
end displayCaptureData:

on cropNSImageTo:{x1, y1, x2, y2} fromImage:theImage
  set newWidth to x2
  
set newHeight to y2
  
set theSize to (theImage’s |size|())
  
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:x2, height:y2}}
  
  
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:

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

on dispMenu(selInd, theTarget)
  activate application "Script Editor"
  
tell application "System Events"
    tell process "スクリプトエディタ" –"Script Editor" (Japanese localized name)
      
      
ignoring application responses
        tell theTarget to perform action "AXShowMenu" –コンテクストメニューの表示
      end ignoring
      
      
tell text area 1 of scroll area 1 of splitter group 1 of splitter group 1 of window 1
        tell menu 1
          set mPos to position
          
set mSize to size
          
          
set mList to every menu item
          
tell menu item (13 + selInd)
            set aRes to properties
            
set selected to true
          end tell
        end tell
      end tell
      
    end tell
  end tell
  
  
return {mPos, mSize}
end dispMenu

★Click Here to Open This Script 

(Visited 236 times, 3 visits today)
Posted in GUI Scripting | Tagged 10.14savvy NSBitmapImageRep NSImage NSPNGFileType NSString NSURL NSUUID | Leave a comment

Blogへの新規ユーザー登録を停止

Posted on 1月 24, 2020 by Takaaki Naganoya

本Blogには誰でもユーザー登録できるようになっていました。フォーラムの運用を想定していたので、誰でも登録できるようになっていたほうがよいと考えたからです。

ただ、最近はスパマーのボットによるユーザー登録が増えてきて、スパマーのブラックリストを用いての確認とかユーザー削除の作業が増えてきて、一時はスパマー除去のためのプラグインを入れて様子を見ていました。

スパマー除去プラグインのお試し期間が過ぎ、一思案。

スパマー除去サービスを利用するのが最善手でありますが、そこまでするんだったらもう少し、WordPressのユーザー登録時にロボットを弾くための認証プロセスを追加するなどの方法もありそうですし(自分が考えるぐらいだから存在するでしょう)。

とりあえずの暫定措置で、ユーザー登録そのものを一時的に停止します。日本語で書いて意味があるかは不明ですが、、、

(Visited 25 times, 1 visits today)
Posted in news | Leave a comment

1888年1月1日以前の日付が-1日になる問題の原因

Posted on 1月 23, 2020 by Takaaki Naganoya

Shane Stanleyにチャットで教えてもらっていました(お食事前に申し訳ない!) これは-1日になるほうが暦自体の仕様的に正しいようです。1888/1/1以前には「子午線」とかタイムゾーン(子午線ごとの標準時)という考え方自体が存在せず、1888/1/1に運用を開始した「日本標準時」に合わせてGMT +9になったため、この1888/1/1から前の日付はさかのぼって-1日される、と。

# 子午線のある現在の日付から子午線という概念がまだ存在しない日付をさかのぼった結果、日付が1日ズレた、と

現在施行されている「グレゴリオ暦」は、日本においても1873年(明治3年)に導入されました。この件については、よく知られていることです(自分の記憶があいまいで明治1年かと思っていました)。

ただ、この「グレゴリオ暦@Japan Ver.1」では子午線に関する決まりがなく、アメリカなどの国土が広い国では列車の時刻表などで問題になっていました。

その後、1884/10/11の国際子午線会議における子午線の制定を受け、日本標準時の運用が1888/1/1に開始になりました。この、1888/1/1の日本標準時の運用前にはタイムゾーンという考え方自体がなかったわけです。この、「グレゴリオ暦@Japan Ver.2」ともいえる暦法が1888/1/1に導入されたことにともない、時刻の変更とともに日付が変わったということである、と。

当時は子午線という概念そのものがなく、日本標準時が運用開始になったのが1888/1/1だということでようやく納得できました。

Classic Mac OSやMac OS X 10.6まではカレンダーの計算にこうした歴史的な経緯が加味されておらず、途中でポリシーが変更になったというのが真相のようです。累積誤差で日付が変わったんじゃなかったんですね、、、、

1582/10/15
ローマにてグレゴリオ暦 制定

1873/1/1(明治3年)
日本にてグレゴリオ暦に改暦。ただし、子午線の運用は各国間で規定がなかった。

1884/10/11
国際子午線会議

1888/1/1
日本標準時 運用開始

[おまけ] Cocoa自体のグレゴリオ暦の開始日を実際に取得してみました。

AppleScript名:gregorianStartDate.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/01/23
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

set sDate to current application’s NSDateFormatter’s alloc()’s init()’s gregorianStartDate()
–> (NSDate) "1582-10-15 00:00:00 +0000"

set asDate to sDate as date
–> date "1582年10月15日 金曜日 9:18:59"

★Click Here to Open This Script 

(Visited 222 times, 1 visits today)
Posted in Calendar History | 2 Comments

元号変換v42

Posted on 1月 23, 2020 by Takaaki Naganoya

西暦→和暦の元号を求めるAppleScriptの改修版です。

前バージョンでは、1868年から1887年までの計算が1日ズレるとか(dateオブジェクトの仕様)、明治の計算が合っていなかったので、その点を修正しました。

前バージョンまでは文字列で与えられた日付をいったんdateオブジェクトに変換していました。これは、”2020/11/31″といった正しくない日付が与えられた場合に、”2020/12/1″と妥当な解釈をし直すための処理でした。つまり、エラー対策のためだけにいったんdateオブジェクトに変換していたわけです。

これさえ行わなければ、とくにdateオブジェクトまわりの問題(before1887)は発生しません。dateオブジェクトとして解釈を行わず、単なる文字列を年、月、日に分解して、大小判定するだけの処理に置き換えました(11/31といったカレンダー的におかしな記述は無視)。

明治の計算についてもごにょごにょして修正してみました。

dateとしての年、月、日の妥当性チェックを行いたい場合には、月が1〜12、日が1〜31といった値の範囲チェックを追加で行うぐらいでしょうか。

AppleScript名:元号変換v42
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/01/23
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

set outList to {}
repeat with i from 1867 to 2021
  set aStr to (i as string) & "/1/25"
  
set {aGengoStr, aGengoNum} to retJapaneseGengo(aStr) of JGengoKit
  
set the end of outList to {i, aGengoStr, aGengoNum}
end repeat

return outList
–> {{1867, "(改暦前)", false}, {1868, "明治", 1}, {1869, "明治", 2}, {1870, "明治", 3}, {1871, "明治", 4}, {1872, "明治", 5}, {1873, "明治", 6}, {1874, "明治", 7}, {1875, "明治", 8}, {1876, "明治", 9}, {1877, "明治", 10}, {1878, "明治", 11}, {1879, "明治", 12}, {1880, "明治", 13}, {1881, "明治", 14}, {1882, "明治", 15}, {1883, "明治", 16}, {1884, "明治", 17}, {1885, "明治", 18}, {1886, "明治", 19}, {1887, "明治", 20}, {1888, "明治", 21}, {1889, "明治", 22}, {1890, "明治", 23}, {1891, "明治", 24}, {1892, "明治", 25}, {1893, "明治", 26}, {1894, "明治", 27}, {1895, "明治", 28}, {1896, "明治", 29}, {1897, "明治", 30}, {1898, "明治", 31}, {1899, "明治", 32}, {1900, "明治", 33}, {1901, "明治", 34}, {1902, "明治", 35}, {1903, "明治", 36}, {1904, "明治", 37}, {1905, "明治", 38}, {1906, "明治", 39}, {1907, "明治", 40}, {1908, "明治", 41}, {1909, "明治", 42}, {1910, "明治", 43}, {1911, "明治", 44}, {1912, "明治", 45}, {1913, "大正", 2}, {1914, "大正", 3}, {1915, "大正", 4}, {1916, "大正", 5}, {1917, "大正", 6}, {1918, "大正", 7}, {1919, "大正", 8}, {1920, "大正", 9}, {1921, "大正", 10}, {1922, "大正", 11}, {1923, "大正", 12}, {1924, "大正", 13}, {1925, "大正", 14}, {1926, "大正", 15}, {1927, "昭和", 2}, {1928, "昭和", 3}, {1929, "昭和", 4}, {1930, "昭和", 5}, {1931, "昭和", 6}, {1932, "昭和", 7}, {1933, "昭和", 8}, {1934, "昭和", 9}, {1935, "昭和", 10}, {1936, "昭和", 11}, {1937, "昭和", 12}, {1938, "昭和", 13}, {1939, "昭和", 14}, {1940, "昭和", 15}, {1941, "昭和", 16}, {1942, "昭和", 17}, {1943, "昭和", 18}, {1944, "昭和", 19}, {1945, "昭和", 20}, {1946, "昭和", 21}, {1947, "昭和", 22}, {1948, "昭和", 23}, {1949, "昭和", 24}, {1950, "昭和", 25}, {1951, "昭和", 26}, {1952, "昭和", 27}, {1953, "昭和", 28}, {1954, "昭和", 29}, {1955, "昭和", 30}, {1956, "昭和", 31}, {1957, "昭和", 32}, {1958, "昭和", 33}, {1959, "昭和", 34}, {1960, "昭和", 35}, {1961, "昭和", 36}, {1962, "昭和", 37}, {1963, "昭和", 38}, {1964, "昭和", 39}, {1965, "昭和", 40}, {1966, "昭和", 41}, {1967, "昭和", 42}, {1968, "昭和", 43}, {1969, "昭和", 44}, {1970, "昭和", 45}, {1971, "昭和", 46}, {1972, "昭和", 47}, {1973, "昭和", 48}, {1974, "昭和", 49}, {1975, "昭和", 50}, {1976, "昭和", 51}, {1977, "昭和", 52}, {1978, "昭和", 53}, {1979, "昭和", 54}, {1980, "昭和", 55}, {1981, "昭和", 56}, {1982, "昭和", 57}, {1983, "昭和", 58}, {1984, "昭和", 59}, {1985, "昭和", 60}, {1986, "昭和", 61}, {1987, "昭和", 62}, {1988, "昭和", 63}, {1989, "平成", 1}, {1990, "平成", 2}, {1991, "平成", 3}, {1992, "平成", 4}, {1993, "平成", 5}, {1994, "平成", 6}, {1995, "平成", 7}, {1996, "平成", 8}, {1997, "平成", 9}, {1998, "平成", 10}, {1999, "平成", 11}, {2000, "平成", 12}, {2001, "平成", 13}, {2002, "平成", 14}, {2003, "平成", 15}, {2004, "平成", 16}, {2005, "平成", 17}, {2006, "平成", 18}, {2007, "平成", 19}, {2008, "平成", 20}, {2009, "平成", 21}, {2010, "平成", 22}, {2011, "平成", 23}, {2012, "平成", 24}, {2013, "平成", 25}, {2014, "平成", 26}, {2015, "平成", 27}, {2016, "平成", 28}, {2017, "平成", 29}, {2018, "平成", 30}, {2019, "平成", 31}, {2020, "令和", 2}, {2021, "令和", 3}}

script JGengoKit
  on retJapaneseGengo(aDate as string)
    set dList to parseByDelim(aDate, "/") of me
    
if length of dList is not equal to 3 then error "Date Format Error"
    
    
copy dList to {aYear, aMonth, aDay}
    
    
tell current application
      
      
set aStr to retZeroPaddingText(aYear, 4) of me & retZeroPaddingText(aMonth, 2) of me & retZeroPaddingText(aDay, 2) of me
      
      
set aGengo to ""
      
if aStr ≥ "20190501" then
        set aGengo to "令和"
        
set aGengoNum to aYear – 2019 + 1
      else if aStr ≥ "19890108" then
        set aGengo to "平成"
        
set aGengoNum to aYear – 1989 + 1
      else if aStr ≥ "19261225" then
        set aGengo to "昭和"
        
set aGengoNum to aYear – 1926 + 1
      else if aStr ≥ "19120730" then
        set aGengo to "大正"
        
set aGengoNum to aYear – 1912 + 1
      else if aStr ≥ "18680125" then
        set aGengo to "明治"
        
if aYear = 1868 then
          set aGengoNum to 1
        else if (aYear ≥ 1869) or (aYear ≤ 1912) then
          set aGengoNum to aYear – 1867
        end if
      else
        –日本では明治以降に太陽暦を導入したのでそれ以前は意味がない?
        
set aGengo to "(改暦前)"
        
set aGengoNum to false
      end if
      
      
return {aGengo, aGengoNum}
    end tell
  end retJapaneseGengo
  
  
–数値にゼロパディングしたテキストを返す
  
on retZeroPaddingText(aNum, aLen)
    set tText to ("0000000000" & aNum as text)
    
set tCount to length of tText
    
set resText to text (tCount – aLen + 1) thru tCount of tText
    
return resText
  end retZeroPaddingText
  
  
on parseByDelim(aData, aDelim)
    set curDelim to AppleScript’s text item delimiters
    
set AppleScript’s text item delimiters to aDelim
    
set dList to text items of aData
    
set AppleScript’s text item delimiters to curDelim
    
return dList
  end parseByDelim
end script

★Click Here to Open This Script 

(Visited 56 times, 1 visits today)
Posted in Calendar | Tagged 10.13savvy 10.14savvy 10.15savvy | Leave a comment

1867/1/1〜1887/12/31までの範囲のdateオブジェクトからyear, month, dayを取り出すと-1日される?

Posted on 1月 22, 2020 by Takaaki Naganoya

過去のdateオブジェクトを検証する機会があり(明治の元号計算が合っていない件)、いろいろ検証していたところ、1867/1/1から1887/12/1までのdateオブジェクトからyear,month,dayを個別に取り出すと、dayが-1されるという現象が観測されました。

→ 本現象の発生メカニズムはこちら

西暦から和暦に変換する処理で、明治の年が合わないという(自分のプログラム由来の)問題を検討していました。この問題の洗い出しのため、「日」単位で順次和暦変換していたら、そのちょうど(明治→大正など)改元の境目の日付で(原因不明の)計算ミスが起こっていました。

1868/1/25からは明治時代、という判定は行えても、その1868/1/25というdateオブジェクトからYear, Month, Dayの各要素を取り出すと1868, 1, 24という結果に。

以前から「大昔の日付を扱うと問題がありそう」だとは思っていましたが、このように具体的な現象として観測したのは(個人的には)初めてでした(単に覚えていないだけかも)。

確認したのはmacOS 10.14.6とmacOS 10.15.3beta、macOS 10.13.6上ですが、どれも同じ結果になるようです。

# 追試で、OS X 10.7.5でも試してみたところ、同じ結果になりました
# OS X 10.6.8では確認されませんでした

未来のdateオブジェクトは2050年ぐらいまでチェックしてみたものの、問題はありませんでした。

過去に遡ってうるう日が設定されたとかいう話なんでしょうか? そういう話は聞いたことがないのですが、、、

日本においては太陽暦(グレゴリオ暦)を導入したのが明治元年(1868/1/25〜)なので、それ以前の日付をグレゴリオ歴で求めてもいまひとつ実用性がない(?) ともいえますが、少なくとも1868年から1887年までの間のdateオブジェクトから各種の値の取り出しが期待どおりに行われないのは問題といえるでしょう。

多分、もっと昔の日付も同様にdateオブジェクトからの値取り出しを行うと問題が出ると思われますが、前述のような理由からそこまでの日付を計算させることもないだろうかと。

# ふだん使っているgetMLenInternationalに問題があるのかと考えて、昔使っていたgetMLenを引っ張り出してきましたが、こちらはずいぶんと記法がお可愛らしい感じで、、、、

ただ、この件は気がつかなかっただけで、ずいぶん昔から存在している話なのかも????


▲Classic Mac OS 8.6では確認できませんでした(SheepShaver上で動作)この時代にはmonthをas numberで数値にcastできませんでした

AppleScript名:dateTest.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/01/22
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

script spd
  property mList : {}
end script

set (mList of spd) to {}
repeat with y from 1867 to 1888
  repeat with m from 1 to 12
    set aLen to getMlen(y, m) of me
    
repeat with d from 1 to aLen
      set aTmpStr to (y as string) & "/" & (m as string) & "/" & (d as string)
      
set aTmpD to date aTmpStr
      
      
set tmpY to year of aTmpD
      
set tmpM to month of aTmpD as number
      
set tmpD to day of aTmpD
      
      
if (tmpY is not equal to y) or (tmpM is not equal to m) or (tmpD is not equal to d) then
        set the end of (mList of spd) to {aTmpD, tmpY, tmpM, tmpD}
      end if
    end repeat
  end repeat
end repeat

return (mList of spd)
–> {{date "1867年1月1日 火曜日 0:00:00", 1866, 12, 31}, …… {date "1887年12月31日 土曜日 0:00:00", 1887, 12, 30}}

–現在のカレンダーで指定年月の日数を返す
on getMlenInternational(aYear as integer, aMonth as integer)
  set theNSCalendar to current application’s NSCalendar’s currentCalendar() — do *not* use initWithCalendarIdentifier:
  
set theDate to theNSCalendar’s dateWithEra:1 |year|:aYear |month|:aMonth |day|:1 hour:0 minute:0 |second|:0 nanosecond:0
  
set theResult to theNSCalendar’s rangeOfUnit:(current application’s NSDayCalendarUnit) inUnit:(current application’s NSMonthCalendarUnit) forDate:theDate
  
return |length| of theResult
end getMlenInternational

–指定年の指定月の日数を求める
on getMlen(aYear, aMonth)
  set aYear to aYear as number
  
set aMonth to aMonth as number
  
  
set aDat to (aYear as text) & "/" & (aMonth as text) & "/1"
  
if aMonth is 12 then
    set eDat to ((aYear + 1) as text) & "/" & (1 as text) & "/1"
  else
    set eDat to ((aYear as text) & "/" & (aMonth + 1) as text) & "/1"
  end if
  
  
set eDat to date eDat
  
set eDat to eDat – 1
  
  
set mLen to day of eDat
  
return mLen
end getMlen

★Click Here to Open This Script 

(Visited 68 times, 2 visits today)
Posted in Calendar History | Tagged 10.13savvy 10.14savvy 10.15savvy | 1 Comment

Keynoteで選択中の画像を特定する

Posted on 1月 22, 2020 by Takaaki Naganoya


Keynoteの書類上で選択中のオブジェクト(image)を特定するAppleScriptです。

Keynoteには、選択中のオブジェクトを求めるという重要な機能「selection」が実装されていません。一応、最新版のKeynoteには「selection」の予約語が存在しているものの、slide中の選択オブジェクトではなく「選択中のスライド」が返ってきます。current slideとほぼ同じ動作です。これでは実用性がいまひとつです。

ないと困るselection(get selected object)ですが、実装されていないのは仕方ありません。

そのものズバリの機能が存在していないものの、他のやりかたで選択中の画像を特定してみました。数が少なかったり重複するものが存在していない場合には有効のようです。

本Scriptでは、Keynote書類上で選択中の画像があるという前提の上で、GUI Scripting経由でコピーを行い、選択対象をクリップボードに入れます。このクリップボード内の画像のサイズを取得。次に、現在のKeynote書類の現在のスライド(ページ)上の画像(imageオブジェクト)のサイズを取得し、順次照合。同じサイズのものがあれば、それが選択中のオブジェクトであると類推します。

かなり穴の多いロジックですが、最初の一歩としては悪くないでしょう。とりあえずは、サイズで比較を行い、同一のものがあれば画像同士の類似性を計算するといった方法も検討できそうです。

お手上げになってしまうのは、画像サイズや内容ともに同一のものが複数あった場合です。その場合を除けば割と識別できそうに思えます。

また、ながらく調査を行なってきた「ローカライズ言語に依存しないGUI Scripting」を用いて選択中のオブジェクトのコピーができるとよさそうです。

AppleScript名:Keynoteで選択中の画像を特定する.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/01/22
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.7"
use scripting additions
use framework "Foundation"
use framework "AppKit"

set kRes to getSelectedImage() of me
–> image 3 of slide 24 of document id "534F4E65-4459-4B00-95D4-34C3E020467E"

on getSelectedImage()
  my executeKeynoteItemCopy() –Execute Copy From Menu
  
  
–クリップボードの内容をNSImageに
  
set aNSIMage to my getClipboardASImage()
  
if aNSIMage = false then
    return false
  end if
  
  
–クリップボード中のNSImageのサイズを取得
  
set aSize to aNSIMage’s |size|()
  
set selWidth to (aSize’s width) as real
  
set selHeight to (aSize’s height) as real
  
  
–Keynoteの最前面のドキュメントの現在のスライド上の画像からサイズを取得してクリップボード内の画像サイズと照合する
  
tell application "Keynote"
    tell front document
      tell current slide
        set iList to every image
        
        
repeat with i in iList
          set myHeight to (height of i) as real
          
set myWidth to (width of i) as real
          
if {myWidth, myHeight} = {selWidth, selHeight} then
            return contents of i
          end if
        end repeat
      end tell
    end tell
  end tell
  
return false
end getSelectedImage

— クリップボードの内容をNSImageとして取り出して返す
on getClipboardASImage()
  set theNSPasteboard to current application’s NSPasteboard’s generalPasteboard()
  
set theAttributedStringNSArray to theNSPasteboard’s readObjectsForClasses:({current application’s NSImage}) options:(missing value)
  
if theAttributedStringNSArray = {} then return false
  
set theNSAttributedString to theAttributedStringNSArray’s objectAtIndex:0
  
return theNSAttributedString
end getClipboardASImage

on executeKeynoteItemCopy()
  activate application "Keynote"
  
tell application "System Events"
    tell process "Keynote"
      –click menu item "Copy" of menu 1 of menu bar item "Edit" of menu bar 1
      
click menu item "コピー" of menu 1 of menu bar item "編集" of menu bar 1
    end tell
  end tell
end executeKeynoteItemCopy

★Click Here to Open This Script 

(Visited 180 times, 1 visits today)
Posted in Clipboard GUI Scripting Image | Tagged 10.14savvy 10.15savvy Keynote NSImage NSPasteboard | Leave a comment

AirSharingLib Script Library

Posted on 1月 22, 2020 by Takaaki Naganoya

AppleScriptからAirDrop経由で他のMacやiPhone、iPadなどのiOSデバイスとファイル共有するAppleScript Library「AirSharingLib」v1.0です。

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

もともとの内容はhttp://www.macosautomation.comに掲載されている「Sharing Utilities」ですが、現在のmacOS用に一部書き換えたのと、WiFiの強制パワーオンなどの機能を追加しています。

AirDrop経由のファイル共有については、さまざまな場面で必要になりますし、複数ファイルを指定してAirDrop共有するのはGUI側(Finder側)から行うのはなかなか操作が煩わしいので、AppleScriptから操作できると便利です。

そうしたAirDrop共有のためのAppleScriptライブラリが存在していることは重要なのですが、Sharing Utilityだといまひとつ古くなりすぎているので、さまざまなプログラムで参照するのに問題が出てくるように感じていました。

そのため、あらためてSharing Utilityとは別のライブラリをでっち上げた次第です。

AppleScript名:sample1
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/01/20
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
–  http://www.piyocast.com
use AppleScript version "2.7" –10.13 or later
use framework "Foundation"
use scripting additions
use airLib : script "AirSharingLib"

set fileList to (choose file with prompt "You can select multiple files with folding [SHIFT] key" with multiple selections allowed)

share with air fileList

★Click Here to Open This Script 

(Visited 109 times, 1 visits today)
Posted in AirDrop Script Libraries | Tagged 10.14savvy 10.15savvy | 1 Comment

自然言語テキストから複数の日付情報を抽出

Posted on 1月 21, 2020 by Takaaki Naganoya

自然言語テキストから日付の情報(複数可)を抽出するAppleScriptです。

URLやメールアドレスの抽出では、複数のデータをNSDataDetectorで抽出するAppleScriptは書いてありましたが、日付情報の抽出を行うものはなかったので、書いておきました。

AppleScript名:自然言語テキストから複数の日付情報(複数)を抽出して日付のリストを返す.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/01/21
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set theDate to getDatesIn("本テキストには次の火曜日という日付情報を含んでいる。明日かもしれない。次の木曜日もそうだ。") of me
–> {date "2020年1月28日 火曜日 12:00:00", date "2020年1月22日 水曜日 12:00:00", date "2020年1月23日 木曜日 12:00:00"}

set theDate to getDatesIn("This text contains next Tuesday. The date may be tomorrow. Next Wednesday happen.") of me
–> {date "2020年1月28日 火曜日 12:00:00", date "2020年1月22日 水曜日 12:00:00", date "2020年1月29日 水曜日 12:00:00"}

on getDatesIn(aString)
  set anNSString to current application’s NSString’s stringWithString:aString
  
set theDetector to current application’s NSDataDetector’s dataDetectorWithTypes:(current application’s NSTextCheckingTypeDate) |error|:(missing value)
  
set theMatchs to theDetector’s matchesInString:anNSString options:0 range:{0, anNSString’s |length|()}
  
if theMatchs = missing value then error "No date found with String:" & aString
  
set dRes to theMatchs’s valueForKeyPath:"date"
  
return dRes as list
end getDatesIn

★Click Here to Open This Script 

AppleScript名:自然言語テキストから複数の日付情報(複数)を抽出して日付と当該箇所のリストを返す v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/01/21
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set theDate to getDatesAndOrigStringsIn("本テキストには次の火曜日という日付情報を含んでいる。明日かもしれない。次の木曜日もそうだ。") of me
–> {{originalStr:"次の火曜日", detectDate:date "2020年1月28日 火曜日 12:00:00"}, {originalStr:"明日", detectDate:date "2020年1月22日 水曜日 12:00:00"}, {originalStr:"次の木曜日", detectDate:date "2020年1月23日 木曜日 12:00:00"}}

set theDate to getDatesAndOrigStringsIn("This text contains next Tuesday. The date may be tomorrow. Next Wednesday happen.") of me
–> {{originalStr:"next Tuesday", detectDate:date "2020年1月28日 火曜日 12:00:00"}, {originalStr:"tomorrow", detectDate:date "2020年1月22日 水曜日 12:00:00"}, {originalStr:"Next Wednesday", detectDate:date "2020年1月29日 水曜日 12:00:00"}}

on getDatesAndOrigStringsIn(aString)
  set anNSString to current application’s NSString’s stringWithString:aString
  
set theDetector to current application’s NSDataDetector’s dataDetectorWithTypes:(current application’s NSTextCheckingTypeDate) |error|:(missing value)
  
set theMatchs to theDetector’s matchesInString:anNSString options:0 range:{0, anNSString’s |length|()}
  
if theMatchs = missing value then error "No date found with String:" & aString
  
set dRes to (theMatchs’s valueForKeyPath:"date") as list
  
set rRes to (theMatchs’s valueForKeyPath:"range") as list
  
  
set allRes to {}
  
set aLen to length of dRes
  
repeat with i from 1 to aLen
    set aSubStr to (anNSString’s substringWithRange:(item i of rRes))
    
set dDate to contents of item i of dRes
    
set the end of allRes to {originalStr:aSubStr as string, detectDate:dDate}
  end repeat
  
  
return allRes
end getDatesAndOrigStringsIn

★Click Here to Open This Script 

(Visited 58 times, 1 visits today)
Posted in Calendar Natural Language Processing | Tagged 10.12savvy 10.13savvy 10.14savvy 10.15savvy NSDataDetector NSString | Leave a comment

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

Posted on 1月 21, 2020 by Takaaki Naganoya

一部の本Blog愛読者の方々からのご要望にお応えして(慣用句)、ここにBlogアーカイブ本のVol.6(2015年)の発売をお知らせいたします。旧BlogのDBダンプからデータを取り出して、2015年11月分までしか残っていなかったので、旧Blogのアーカイブ本はこれが最終巻になります。

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

本Blog「AppleScriptの穴」は、開設10年目を迎える直前の2018年1月末に、格安ホスティングサービス「Xserver」との間の手違いでDBがシャットダウンされ、そのままの形で公開し続けることができなくなってしまいました。

そこで、AppleScriptのプログラムによるFinder上のAppleScriptの自動HTML化、AppleScriptによるXML-RPC経由でのWordPressへの自動記事投入といったさまざまなソリューションを投下して、現在の登録記事数に復旧。自動記事投入による復旧を行なったために、当時の作業環境でオープンできない(OSバージョン依存、アプリケーション依存)Scriptについては掲載を見送っています。

 旧AppleScriptの穴:2008〜2018年 Mac OS X 10.4〜10.5の時代に開設
 現AppleScriptの穴:2018年〜   Cocoa APIを呼びまくる現在のスタイルが定着

自動投入可能なコンテンツを優先して掲載したため、旧Blogと現Blogでは掲載内容が大幅に変わっています。別物といってよいでしょう。

そのため、Cocoa APIを使用しない「オールドスタイルのAppleScript」(とくに昔のバージョンのアプリケーション依存)については再掲載が難しく、このBlogアーカイブ本シリーズにしか情報をまとめていません。

旧Blogアーカイブ本シリーズも、1年ごとに区切って記事をPDF化して6冊目。Vol.6は2015年1〜12月の1年分の内容をまとめています。全383ページ、2,000円。

ファイル形式はPDFで、キーワードによる全文検索や印刷が行えます。本文からリンクしているXcodeプロジェクトのダウンロードリンクも新たに現行Blogにアップロードしたアーカイブにリンクし直しています。

もちろん、各プログラムリスト末尾にURLリンクをそなえ、ワンクリックでプログラム内容をスクリプトエディタに転送可能です。

ほとんどの掲載プログラムについてコメントを行い、現時点(2020年時点)で評価してどうか、ということを追記しています。

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

ASObjCExtras ICU Transformのサンプル
(Free) ASObjCExtras Scripting Guide
Display情報の取得
2Dリストから、指定アイテムNoで、指定データが該当する最初のものを返す v3
指定したアプリケーションの各lproj内の各stringsファイルのパス一覧を取得する
2月1日が日曜日でうるう年ではないかチェック(ASOC)
カレンダー.app(旧称iCal)で選択中のイベントの情報を取得
起動中のプロセスの存在確認
起動中のプロセスの存在確認(ASOC)v2
Photoshop Action Setをインストールする
現在地点の緯度経度情報を取得する
CSVファイルをListにParseする(ASOC)
CSVファイルをListにParseする(ASOC) 2
errorのpartial resultとは?
レコードとレコードの連結
同スコアを考慮した順位決定
公開添削:サーバー上のファイル権限をローカルで書き換えて書き戻し
ASOCで基礎的な文字列比較
ASOCで基礎的な文字列比較 2
文字列同士が同じかチェック(大文字,小文字の差異を考慮したり無視したり)
Umlautを無視した文字列比較
ASOCで数値文字の比較
POSIX pathで与えられたパスの親フォルダを求める(末尾にスラッシュ添付)
DiskSpaceを求める
CocoaでDisk Free Space (Bytes) を求める
写真.app(Photos.app)のScript対応機能は未完成
OS X 10.10.3のdelayに(新たな)バグ? マウスカーソルの移動でdelayがキャンセルされる
Spotlight検索インデックスを再生成
2015/5
Mailで選択中のMessageの添付ファイルをデスクトップに保存
Mailで有効なmailアカウントの新規メール取得を強制的に有効にする
メモリー解放?
OS X 10.11, El Capitanが発表に
バージョン番号文字列からメジャーバージョンを取り出し数値として返す v4
SafariのWebViewへのGUI Scripting的な参照を取得する v2
URLByAppendingPathComponentのじっけん
指定のURLのYouTubeのムービーをOffLiberty経由でローカルにダウンロード
Finderで選択中の戦場の絆のリプレイムービーのファイル名を取得して対戦人数を集計する
JSON文字列とrecordの相互変換
ASOCでレコードのリストをユニーク化
ASOCでbase64エンコード、デコード
ASOCでバージョン番号文字列の正確な比較
ASOCでbase64エンコード、デコード v2
ASOCでNSStringをas stringでcastすると問題が出るバグの検証
指定の画像を別形式に変換する
現在のLocaleのIdentifier文字を取得する
ASOCで数値を指定桁でゼロパディング
指定の画像を別形式に変換する v2
指定の画像を別形式に変換する v3
フォルダアクションの操作
CPUの詳細な型番を取得する
使用中のMacの製品呼称を取得する
使用中のMacの製品呼称を取得する v2
ASOCで少数点以下の数値の切り上げ、切り下げ
ASOCでScript Editorの構文色分け情報を設定ファイルから取り出す v2
ASOCで少数点以下の数値の切り上げ、切り下げ v2
ASOCでRTFの内容を読み取って指定文字を置換してファイルに保存する
ASOCで与えられた画像ファイルがNSImageでハンドリング可能かを取得
ASOCで無線LANの各種情報を取得する
ASOCで無線LANの各種情報を取得する v2
ASOCで動的にWindowを作成
El Capitanの各Apple純正ツールのAppleScript用語辞書の変更度合い
ASOCで各種文字列からdate objectに変換 ほかNSDataDetectorの活用
NSDataDetectorを用いてテキストから各種データを抽出
MacのHardware UUIDを取得する
ASOCで性別と言語コードを指定してTTS voiceを取得 v2
ASOCでHostの情報を取得する
ASOCでNSLocaleのじっけん
100%クラッシュするNSCalendarの操作
NSTimeZoneのじっけん
ASOCでNSFont,NSFontManagerのじっけん
ASOCでプロセス関連のじっけん
ASOCでspotlight検索するじっけん
ASOCで文字を逆順に
ASOCでspotlight検索するじっけん v2
秒以下の時間待ちを検証
エラートラップのpartial result
メールアドレスの妥当性チェック
URLの妥当性チェック
URLからドメイン名を抽出
指定URLをロードしてtitleを取得
メーラーから取得したメールアドレスのうち純粋なアドレス部分を抽出 v2
現在実行中のプロセスの情報を取得
続・伏字文字列を作成する
指定URLのファイルをダウンロード
テキストの言語を推測する
与えられたテキストの言語を自動判別して対応する言語のTTS Voiceで読み上げ
マルチバイト文字の検出、の落とし穴
NSCountedSetでNSDictionaryの登場頻度集計
指定URLをロード WKWebView版
クリップボードの内容をRTFとPDFで書き出す
spotlightでタグを指定して検索
NSPredicateによる正規表現を利用した部分一致抽出
BridgePlus 1.2のframeworkの新機能テスト(1)
多国語OCR「FineReader OCR Pro」をAppleScriptでコントロール
指定フォルダのファイルパス一覧取得(拡張子指定つき)
続・指定フォルダのファイルパス一覧取得(拡張子指定つき)
文字エンコーディングを自動判別して日本語テキストファイル読み込み v1.2.1
マウスカーソルの強制移動とクリック
XML-RPCのテスト
数字以外を削除して返す
テキストとリストの変換
iWorkアプリがアップデート、AppleScript対応機能が強化される
PDFメディアサイズの取得(単位:Point)
指定ファイルに指定アイコン画像をつける
PDFの各種情報を取得する
指定ファイルのアイコン画像を取得する
アプレットのアイコンをDockに出さない
ASOCによるファイルの移動
Keynote 6.6のじっけん(3)〜表を作成してデータで埋める
指定フォルダ内のフォルダのみを取得する
Foundationのバージョンを取得する
NSErrorを生成する
Systemのアラートサウンド名称を取得して鳴らす v2
ムービーからオーディオのみ抽出してm4aで保存 v2
Safariと同じUser Agent文字列を組み立てる
Safariでアクセス中のページが設定しているCookieの値を求める
文字列のURLエンコード、デコード
iWorkアプリがアップデート。AppleScript関連の機能変更はなし
PEGKitのじっけん
Cocoaオブジェクトのクラス名を文字列で取得

(Visited 35 times, 1 visits today)
Posted in PRODUCTS | Leave a comment

Numbersで書類Aのすべてのシートの表1を、書類Bの現在のシートの表1にまとめる

Posted on 1月 21, 2020 by Takaaki Naganoya

Numbersでオープン中の複数の書類があったときに、書類Aのすべてのシートの表1を、書類Bの現在のシートの表1にまとめるAppleScriptです。

さすがに、機械的な作業すぎて手で行う気にはなれなかったので、ありもののScriptを利用して作ってみました。

こういう用途のために作っておいたライブラリ「choose multiple list」を利用しています。


▲データ取得元


▲データ集約先


▲ダイアログで「データ取得元」と「データ集約先」を選択

BridgePlus内蔵のFrameworkがmacOS 10.14/10.15に邪魔されて認識されない環境では動かせないかもしれません。このあたり、SIP解除するしかないと思わせるものがあります。

ライブラリで複雑な選択を行えるUI部品を作っておいたおかげで、これだけ込み入った動作を行うAppleScriptを書きましたが、Cocoaの機能はほぼ使っていません(getDataFromNumbersDocは作り置きしておいた、頻出ルーチンなので使いまわしています)。choose multiple listライブラリは、こういう用途のために作っておいたものであり、まさにそのぴったりな用途であったといえるでしょう。

AppleScript名:書類Aのすべてのシートの表1を、書類Bの現在のシートの表1にまとめる.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/01/20
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.7" — High Sierra (10.13) or later
use framework "Foundation"
use scripting additions
use bPlus : script "BridgePlus"
use mulList : script "choose multiple list"

script spd
  property allData : {}
end script

set (allData of spd) to {}

set {aName, bName} to getTargetDocNames() of me

–「データ取得元」のNumbers書類のすべてのシートの表1から2D Listでデータ取得
tell application "Numbers"
  tell document aName
    set sList to name of every sheet
    
repeat with i in sList
      set tmp2DDat to getDataFromNumbersDoc(aName, i) of me
      
set (allData of spd) to (allData of spd) & tmp2DDat
    end repeat
  end tell
end tell

set aHeight to length of (allData of spd)
set aWidth to length of item 1 of (allData of spd)

–「データ集約先」のNumbers書類の現在のシートの表1にまとめた2D Listを展開する(巨大すぎると時間がかかるので、CSV書き出ししてオープンするなどの別の方法を採るべき)
tell application "Numbers"
  tell document bName
    tell active sheet
      set tRes to make new table with properties {row count:aHeight + 1, column count:aWidth}
    end tell
  end tell
end tell

fillCurrentTable(bName, (allData of spd)) of me

–Numbersの書類の現在のシートを、指定の2次元配列でfillする
on fillCurrentTable(docName, aList)
  set aLen to length of aList
  
set aWidth to length of first item of aList
  
  
tell application "Numbers"
    tell document docName
      tell active sheet
        tell table 1
          repeat with i from 1 to aLen
            tell row (i + 1)
              set aRowList to contents of item i of aList
              
repeat with ii from 1 to aWidth
                tell cell ii
                  set aTmpData to contents of item ii of aRowList
                  
ignoring application responses
                    set value to aTmpData
                  end ignoring
                end tell
              end repeat
            end tell
          end repeat
        end tell
      end tell
    end tell
  end tell
end fillCurrentTable

–Numbersでオープン中の書類の名称一覧からデータ取得元とデータ集約先の書類名をダイアログで選択
on getTargetDocNames()
  tell application "Numbers"
    set nList to name of every document
  end tell
  
  
set selList to {nList, nList}
  
set tList to {"データ取得元", "データ集約先"}
  
  
set {aRes, bRes} to choose multiple list selList main message "各Numbers書類の役割を選択してください" sub message "「データ取得元」のデータを順次、「データ集約先」の表1に連結します" with title lists tList height 140 width 400 return type item contents without allow same items
  
return {aRes, bRes}
end getTargetDocNames

–Numbersでオープン中の書類の選択中のシートの表1からデータを取得して2D Listに
on getDataFromNumbersDoc(aDocName, sheetName)
  
  
load framework
  
  
tell application "Numbers"
    if (count (every document)) = 0 then return false
    
    
tell document aDocName
      if (count (every sheet)) = 0 then return false
      
      
tell sheet sheetName
        tell table 1
          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

★Click Here to Open This Script 

(Visited 368 times, 1 visits today)
Posted in dialog GUI list | Tagged 10.13savvy 10.14savvy 10.15savvy Numbers | Leave a comment

サーバーメンテナンスが行われます

Posted on 1月 20, 2020 by Takaaki Naganoya

2018年1月にDBをふっとばしてくれたホスティング業者「Xserver」をまだ使っているわけですが、日本標準時(JST)で2020年1月21日 AM2:00〜AM8:00ごろまで、データセンター内の回線増強にともない10分から60分程度、本サイトにアクセスできなくなる見通しです。

その間は、本サイトを通じて配布している各種AppleScriptライブラリのsdefに入れている画像やムービーなどが見えなくなります。

(Visited 26 times, 1 visits today)
Posted in news | Leave a comment

BlogアーカイブのMarkdown書類をリネーム。親、親+1階層フォルダをMM, YYYYとみなして反映

Posted on 1月 19, 2020 by Takaaki Naganoya

Finderで選択中のファイルすべてに対して、親フォルダ名、親+1階層のフォルダ名を反映させたファイル名をつけるAppleScriptです。

Blogアーカイブ本を作るのに、こうした道具を作って使っています。一度書いておけば、2度目からは大幅に時間を短縮できます。最初のファイルから拡張子を取得してそれを後続のファイルすべてに適用するため、同一種類のファイルである必要があります。自分用のツールならではの手抜きといったところでしょうか。

AppleScript名:BlogアーカイブのMarkdown書類をリネーム。親、親+1階層フォルダをMM, YYYYとみなして反映 .scptd
— Created 2020-01-18 by Takaaki Naganoya
— 2020 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

–選択ファイルを取得
tell application "Finder"
  set aSel to selection as alias list –Select documents to Rename
end tell

set aCount to 10 –start
set aStep to 10
set aDigit to 3

–パス情報を取得
set aFirst to first item of aSel
set aPOSIX to POSIX path of aFirst
set aPathStr to (current application’s NSString’s stringWithString:aPOSIX)
set aDateComList to aPathStr’s pathComponents() –ディレクトリごとにパス情報を分割してリスト化
set aExt to aPathStr’s pathExtension() –拡張子

set aYear to (item -3 of aDateComList) as string –親の親フォルダ名
set aMonth to (item -2 of aDateComList) as string –親フォルダ名

–リネーム(数百項目を超える場合にはFinderでは遅すぎるのでNSFileManagerで処理)
tell application "Finder"
  repeat with i in aSel
    set aTEXT to numToZeroPaddingStr(aCount, aDigit, "0") of me –3 digit
    
set aName to aYear & aMonth & aTEXT & "." & aExt
    
set name of i to aName
    
set aCount to aCount + aStep
  end repeat
end tell

–整数の値に指定桁数ゼロパディングして文字列で返す
on numToZeroPaddingStr(aNum as integer, aDigit as integer, paddingChar as text)
  set aNumForm to current application’s NSNumberFormatter’s alloc()’s init()
  
aNumForm’s setPaddingPosition:(current application’s NSNumberFormatterPadBeforePrefix)
  
aNumForm’s setPaddingCharacter:paddingChar
  
aNumForm’s setMinimumIntegerDigits:aDigit
  
  
set bNum to current application’s NSNumber’s numberWithInt:aNum
  
set aStr to aNumForm’s stringFromNumber:bNum
  
  
return aStr as text
end numToZeroPaddingStr

★Click Here to Open This Script 

(Visited 100 times, 1 visits today)
Posted in file File path list Markdown Text | Tagged 10.12savvy 10.13savvy 10.14savvy 10.15savvy Finder NSNumber NSNumberFormatter NSNumberFormatterPadBeforePrefix NSString | Leave a comment

osascript系のAppleScriptランタイムを区別する

Posted on 1月 18, 2020 by Takaaki Naganoya

AppleScriptのランタイム環境が何であるかを区別できるようになりました。

それらのうち、/usr/bin/osascriptを呼び出しているランタイム環境について、さらに細分化して個別に識別するために、ランタイム環境そのものと親プロセスが何であるかをAppleScriptで調査してみました。

結論からいえば、親プロセスが「bash」ならTerminalからosascriptコマンドで起動されたと判断してよさそう。その他は、実行されたScriptの置かれているパスを求めて、macOS標準装備のScript Menuかアプリケーション内部のScript Menuかを見分けるぐらいでしょうか。

これを判定したプログラム自体は、別に技術的にすごいとか機密の塊とかいうことはなくて、「清書してなくて、きたない。無駄に長い。掲載されているプログラムを見ても何も感じない」ことから掲載していません。実験用のテストプログラムでも、ちょっと近年稀に見るぐらいひどい出来です。内容は、単にランタイムプログラムのプロセスIDを取得して、そのプロセスIDをもとにpsコマンドで親プロセスを求めて、コマンドからいろいろ情報を抜いてくるというだけのものです。

Script Menu

ランタイムのパラメータ:/usr/bin/osascript -P /Users/me/Library/Scripts/Finder/pTEST.scptd
親プロセス:/System/Library/Frameworks/Foundation.framework/Versions/C/XPCServices/com.apple.foundation.UserScriptService.xpc/Contents/MacOS/com.apple.foundation.UserScriptService

与えられているScriptが特定フォルダ(/Users/me/Library/Scripts/)以下にあるものかどうか、という識別は可能。ちょっと、根拠が弱そうです。

CotEditor内のScript Menu

ランタイムのパラメータ:/usr/bin/osascript -sd -T 14534 -P /Users/me/Library/Application Scripts/com.coteditor.CotEditor/010)M-pM^_M^MM^NM-pM^_M^SM^\AppleScriptM-cM^AM-(M-cM^AM^WM-cM^AM-&M-hM-'M-#M-iM^GM^H/0020)M-pM^_M^SM^\M-fM-'M^KM-fM^VM^GM-gM-"M-:M-hM-*M^MM-cM^AM^WM-cM^AM-&M-eM-.M^_M-hM-!M^LM-cM^AM^WM-cM^@M^AM-pM^_M^SM^DM-fM^VM-0M-hM-&M^OM-fM^[M-8M-iM-!M^^M-cM^AM-+M-gM-5M^PM-fM^^M^\M-cM^BM^RM-eM^GM-:M-eM^JM^[.@r.scpt
親プロセス:/System/Library/Frameworks/Foundation.framework/Versions/C/XPCServices/com.apple.foundation.UserScriptService.xpc/Contents/MacOS/com.apple.foundation.UserScriptService

親プロセスはScript Menuと同じですが、こちらも実行しているScriptのパスが/Users/me/Library/Application Scripts/com.coteditor.CotEditor/以下であること。これも、識別のための根拠が弱いです。

Terminal経由でosascriptコマンド実行

ランタイムのパラメータ:osascript /Users/me/Desktop/pTEST.scptd
親プロセス:-bash

これは、親プロセスが-bashであることから、明確に区別できます。Terminal.appではなくbashなんですね。

Terminal経由で/usr/bin/osascript(フルパス指定)でコマンド実行

ランタイムのパラメータ:/usr/bin/osascript /Users/me/Desktop/pTEST.scptd
親プロセス:-bash

フルパスで指定すると何か変わってくるかとも思いましたが、とくに変化はありませんでした。

Program AS Style runtime name Parent Process Name Script Path
Script Editor Script/Scriptd Script Editor
Script Editor Cocoa-AppleScript Applet CocoaApplet
Script Editor Applet applet
Script Debugger Script/Scriptd Script Debugger
Script Debugger Applet (Enhanced) FancyDroplet
ASOBjC Explorer 4 Script/Scriptd ASOBjC Explorer 4
Automator Workflow Automator
Automator Applet Application Stub
Script Menu Script/Scriptd osascript …com.apple.foundation.UserScriptService /Users/me/Library/Scripts/ ほか
CotEditor Script osascript …com.apple.foundation.UserScriptService /Users/me/Library/Application Scripts/com.coteditor.CotEditor/
Terminal.app (osascript) Script/Scriptd osascript bash
(Visited 128 times, 1 visits today)
Posted in OSA shell script | Tagged 10.14savvy | Leave a comment

AppleScriptを実行中のランタイムプログラム名を取得する

Posted on 1月 18, 2020 by Takaaki Naganoya

AppleScriptのランタイムプログラム名を取得するAppleScriptです。AppleScript自身が「何によって」実行されているか、その実行プログラム名を取得するものです。

AppleScriptには何種類かランタイム環境が存在し、ランタイム環境ごとに若干の動作が変わってくることが知られています。

ランタイム環境ごとにどこが違うといえば、Finderからのselectionを取得できるとかできないとか(AppleScript Studioがこれに該当。もうありませんけれども)、GUI Scriptingの権限の認証を得られるとか得られないとか。ウィンドウを動的に生成して表示したときに最前面に表示できるとかできないとか(Script Menuがこれに該当)。明示的にメインスレッドで実行する機能がないとか(Script Debuggerがこれに該当)。そういうところです(ほかにもあるかもしれない)。

過去に作ったAppleScriptを確認していたところ、プロセス名を取得するだけの使えないプログラムだと思っていたものが、実は「ランタイムプログラムのプログラム名」を取得できるというスゲーものであることを再発見しました。

ながらく、ランタイムプログラム名をAppleScript側から取得する必要性を感じていたため、この機会に調べてみることに。プログラム自体は些細な(↓)ものです。

AppleScript名:ランタイム環境名の表示
— Created 2015-09-08 by Takaaki Naganoya
— 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set procInfo to current application’s NSProcessInfo’s processInfo()
set aName to procInfo’s processName() as string
display dialog aName

★Click Here to Open This Script 

Script Editor上で実行


–> “Script Editor”

Script Debugger上で実行


–> “Script Debugger”

ASObjC Explorer 4上で実行


–> “ASObjC Explorer 4”

Automator上で実行


–> “Automator”
これには驚きました。特別のランタイムプログラムが使われているのか、それとも単に親プロセスとしてのAutomatorが返ってきているのかは不明ですが、識別できるということには意義がありそうです。

Script Menu上で実行


–> “osascript”
これは、よく知られていることなのでとくに驚きはありません。テストを実施したのはmacOS 10.14.6上で、Script Menuは「スクリプトメニュー」という別アプリケーション(/System/Library/CoreServices/ にある)に変更になったOSバージョンですが、ランタイムにosascriptを使い続けていることを確認することになりました(それ以前のOSと挙動が同じなのでそうだと思っていましたけれども)。

Folder Action上で実行




–> “osascript”
Folder Actionは、macOS標準搭載のフォルダ監視機能です。監視対象のフォルダにファイルが追加されたり、移動されたり、フォルダそのものがオープンしたりするとその対象ファイル/フォルダで指定のAppleScriptを実行します。よく、ドラッグ&ドロップで処理を受け付けたり、ネットワーク経由でファイルを受信した場合にAppleScriptを実行するような使われ方をします。
Folder Action Disptcherが実行しているとばかり思っていたのですが、実際に確認したらosascriptでした。ちなみに、Folder ActionはmacOS 10.11でフルに書き換えられてそれ以前とは別物になっています。以前は数秒に一度対象フォルダをチェックする方式でしたが、10.11以降はFSEventsを利用して随時監視対象フォルダへの変更を受け付けます。

Switch Control上で実行



–> “osascript”
障害者向けの機能としてmacOSに標準装備されている、フローティングパレットからAppleScriptを呼び出せる機能である「Switch Control」。手を使わずに操作したり、他のコントローラで操作するような標準的ではない使い方をサポートするための機構ですが、普通に普通の人が使っても役立ちます。 
Switch ControlでAppleScriptを実行する場合のランタイムプログラムはosascriptです。

CotEditor上で実行


–> “osascript”
これは、CotEditorのソースを読んで確認してありました。ここだけ割と手抜き実装ですが、それでも複数のOSA言語に対応できたりと機能的には悪くはありません。むしろ、osascript側のランタイム環境が他の環境よりも一段落ちることに問題が、、、、GUI Scriptingの権限を取得できないこととか、このCotEditorのメニューから実行するとREST APIが呼び出せないとか。同じosascript系でもScript Menuのほうが制約が少ないのは、おそらくアプリケーション自体に許可されている条件の違いによるものでしょう。

FileMaker Pro上でスクリプトステップ「AppleScriptを実行」を実行


–> “FileMaker Pro”
FileMaker Proはランタイムアプリケーションが廃止され、FileMaker Pro AdvancedもFileMaker Proに一本化されたので、v19以降はFileMaker Proは「FileMaker Pro」というランタイムのみでしょう。v19でもFileMaker Pro自体はSandbox化されていないため、微妙にセキュリティ上の制約が少ない=自由度の高いランタイム環境として残っていくことでしょう。

Script EditorからApplet書き出しして実行


–> “applet”
取得できたらいいなぐらいの気持ちで試してみたものの、これが識別できるのはうれしい誤算です。書き出したAppleScript Applet名は「Appletでランタイム名を取得」であったため、この「applet」というものとは異なります(ねんのため)。

AutomatorからApplet書き出しして実行


–> “Application Stub”
見たことのない名前が、、、、やっぱり、これも別ランタイムなんですね、、、、

Script DebuggerからApplet(Enhanced)で書き出しして実行


–> “FancyDroplet”
Appleの標準ランタイムとはあきらかに別物(Enhanced)なので、たぶん別の名前がついているだろうとは思っていましたが、そういう名前でしたか。名前が予想外だったので驚かされましたが、識別できることに意義があります。

Cocoa-AppleScript Appletを実行


–> “CocoaApplet”
Script Editor上で作成できる、通常のAppleScriptとXcode上で作成するCocoa-Applicationの中間的な性格を持つ「Cocoa-AppleScript Applet」でランタイムプログラム名を取得したらこうなりました。

もちろん、実行プログラム名はまったく別の「ランタイム名を表示するだけのCocoa-AppleScript Applet」というものです。

ショートカットで「AppleScriptを実行」アクションを実行


–> “MacHelper”

macOS 12で搭載されたショートカット.app(Shortcuts.app)および不可視プロセスのAppleScriptの補助専用アプリケーション「Shortcuts Events.app」上で、アクション「AppleScriptを実行」でAppleScriptを実行するときのランタイム名は、「MacHelper」です。意外なところで、ユーザーディレクトリ以下にインストールされたAppleScriptライブラリをこのMacHelper環境は認識します。

RedSweater Software「FastScripts」からAppleScriptを実行

red sweater softwareによるメニュー常駐型Script Menuソフトウェア「FastScripts」から実行したときのランタイム名は「FascScripts Script Runner」です。

Knurling Group「Service Station」からAppleScriptを実行

Knurling Groupによるコンテクストメニューのカスタマイズ・ソフトウェア「Service Station」から実行したときのランタイム名は「osascript」です。

ランタイム名が得られることで実現できること

これらのほか、各アプリケーション内でAppleScript呼び出し機能を有するもの(ファイルメーカー、Mail.appなど)でランタイムプログラム名を取得すると有益な情報が得られることでしょう。

これは、地球上にいる人類が観測衛星を打ち上げて「ここは銀河系だ」と観測できるぐらいすごいことなので、割と意義深いものです。実行中のAppleScriptが、「いま、何のプログラムによって自分自身が実行されている」かという情報を取得できます。

ランタイムプログラムの名称取得については、いくつかのAppleScript実行方法を試してみましたが、得られる名前に違いがないことを確認しています。

直接AppleScriptを動かす方法に加え、間接的にAppleScriptを動かす方法も試してみましたが、同じ結果が得られました。

つまり、動的にOSAScriptViewを生成して実行しようが、NSAppleScriptで実行しようが、AppleScriptの「run script」コマンドで実行しようが、取得されるランタイム名には差がありません。

これで、ランタイム環境のプロセスの親プロセスの情報が取得できると、Terminal.app上から起動したosascriptコマンドで呼び出したのか、Script Menu上から呼び出したのかという状況をAppleScript側で認識できることになることでしょう。

ランタイム環境を識別した上で、各環境で実行できない処理を行わないとか、ランタイム環境ごとに処理を分岐できるようになることでしょう。

ちょうど、Edama2さんと「ランタイム環境ごとに若干の挙動の違いが見られるし、利用できるCocoaの機能にも違いがあるから、ランタイム環境ごとに認識コードでも振ってみようか」などと相談していたので、渡りに船でした。

(Visited 118 times, 1 visits today)
Posted in OSA | Tagged 10.13savvy 10.14savvy 10.15savvy Automator CotEditor Script Debugger Script Editor | Leave a comment

display drop dialog Script Library

Posted on 1月 16, 2020 by Takaaki Naganoya

指定UTIのファイルのFinderからのドラッグ&ドロップを受け付けるAppleScript Libraries「display drop dialog」をリリース、フリー配布いたします。

# 本ライブラリはEdama2さんのScriptに若干の改変を行い、sdefをつけてパラメータのエラー処理を行い、コードサインしてライブラリ化したものです

–> Download display drop dialog Script Library (To ~/Library/Script Libraries/)

本ライブラリは、指定UTIの書類のドラッグ&ドロップを受け付けるダイアログをAppleScriptから手軽に使えるようにするものです。macOS 10.14以降で動作します。

現在のAppleのTim Cook体制は、セキュリティ強化の美名のもとに「動かないコンピュータ」を目指し、各種機能を阻害する方向に進んでいます。

AppleScriptの世界はその中でも自由度が比較的高い状態にありますが、それでもmacOS 10.12以降では、AppleScriptドロップレットにFinderからドラッグ&ドロップしても、Finderの拡張属性(Xattr)がついたファイルは無視されたりと、なかなか困ります。

そこで、Finderからのドラッグ&ドロップ操作を通常の(Applet書き出ししていない)AppleScript、とくにScript Menuから呼び出す形式のAppleScriptで使えるようにすることを目的として本ライブラリを作成しました。

本ライブラリを用いることで、ドロップレットを作らなくても、Script Menuから呼び出した普通のAppleScriptにファイルのドラッグ&ドロップの受信機能を追加できます。セキュリティと機能性(ドラッグ&ドロップ)を両立させるため、すべてのScripterに欠かすことのできないライブラリになるものと期待しています。

本ライブラリのAppleScript用語辞書には実行イメージ(画面キャプチャ)およびサンプルScriptを入れてあり、実行時の様子やサンプルスクリプト(本Blogと同様のワンクリックで内容が転送されるリンクつき)を確認できるようになっています。

AppleScript名:accept AppleScript documents
use dropLib : script "display drop dialog"

set aMainMes to "Drop AppleScript"
set aSubMes to "Drag and Drop AppleScript files here"
set aUTI to "com.apple.applescript.script"
set execButtonTitle to "Execute"
set aRes to (display drop dialog aUTI main message aMainMes sub message aSubMes with initial folder "" OK button title execButtonTitle)
–> {alias "Machintosh HD:Users:me:Documents:display drop dialog:accept PNG images.scpt", alias "Machintosh HD:Users: me:Documentsaccept Markdown documents.scpt"}

★Click Here to Open This Script 

AppleScript名:accept Markdown documents
use dropLib : script "display drop dialog"

set aMainMes to "Drop Markdown Documents"
set aSubMes to "Drag and Drop Markdown documents here"
set aUTI to "net.daringfireball.markdown"
set execButtonTitle to "Execute"
set aRes to (display drop dialog aUTI main message aMainMes sub message aSubMes with initial folder "" OK button title execButtonTitle)
–> {alias "Machintosh HD:Users:me:Documents::–Book 11 「Blog Archives vol5 2013-2014」:2013:01:201301013.md", alias "Machintosh HD:Users:me:Documents::–Book 11 「Blog Archives vol5 2013-2014」:2013:01:201301012.md"}

★Click Here to Open This Script 

AppleScript名:accept PNG images with initial folder contents
use scripting additions
use dropLib : script "display drop dialog"

set aMainMes to "Drop PNG"
set aSubMes to "Drag and Drop png images here"
set aUTI to "public.png"
set execButtonTitle to "Execute"
set iFolder to path to pictures folder –At first, PNG files in this folder is displayed
set aRes to (display drop dialog aUTI main message aMainMes sub message aSubMes with initial folder iFolder OK button title execButtonTitle)
–> {alias "Machintosh HD:Users:me:Pictures:1015sedhelp2.png", alias "Machintosh HD:Users:me:Pictures:574G01.png", alias "Machintosh HD:Users:me:Pictures:macDown1.png", alias "Machintosh HD:Users:me:Pictures: 2017-09-27 19.33.53.png", alias "Machintosh HD:Users:me:Pictures:2018-11-01 10.54.06.png"

★Click Here to Open This Script 

(Visited 182 times, 1 visits today)
Posted in dialog GUI PRODUCTS Script Libraries sdef | Tagged 10.14savvy 10.15savvy | Leave a comment

Microsoft Edgeが正式リリース

Posted on 1月 16, 2020 by Takaaki Naganoya

MicrosoftによるGoogle Chrome(オープンソース版のChromium)をベースにした(そのまま)Webブラウザ「Microsoft Edge」の正式版がリリースされました。

ChromiumはAppleScriptに対応しており、ベータ版である「Edge Canary」もChromiumと同様のAppleScript用語辞書を備えていました(A=B)。

正式版「Edge」のAppleScript用語辞書と「Edge Canary」の用語辞書とdiffをとってみたところ、内容が同じであることを確認できました(B=C)。

このため、Google Chromium用のAppleScriptとtell文のアプリケーション名だけ書き換えればEdge用のAppleScriptとして動かせることが期待できます(メニューやボタンを直接動かすGUI Sciriptingをのぞく)。


▲メニュー構成はけっこう違います

(Visited 47 times, 1 visits today)
Posted in news | Tagged Microsoft Edge | Leave a comment

Blog アーカイブVol.5 rev1.1を公開

Posted on 1月 16, 2020 by Takaaki Naganoya

発売したばかりの「BlogアーカイブVol.5」ですが、画像のリンク抜けがあるとのご報告をいただき、すぐさま修正版をリリースしました。すでにお買い上げの方々におかれましても、再ダウンロードでダウンロードできるはずなので、おためしください。

本件については、画像リンクチェッカーAppleScriptの機能を強化。これまでも、Markdownタグでリンクした画像のリンク抜けについてはAppleScriptで自動チェックを行なっていたのですが、HTMLタグで入れた画像リンクについてはチェック対象外となっていました。

そこで、画像リンクチェッカー「指定ディレクトリ以下のMarkdown書類のリモート画像URLのリンク切れをチェック(Markdown、HTMLタグ両方)」を作成し、自動でMarkdown/HTMLタグで記述された画像リンクチェックを実施。

5か所ほど画像リンク抜けが見つかったので、その点を修正したRev. 1.1をアップロードしました。

表紙と奥付のリビジョン表記が1.0から1.1になっています。

原稿(Pages&Markdown書類)→PDF書き出し→PDF結合→TOC作成 と、ワークフローをAppleScriptで自動化しており、こうしたツールを作ってきたからこそ、たった1人で執筆、編集、発行(販売)を行えるようになっている次第です。

なお、画像リンク抜け以外の箇所はほとんど変わっていませんので、現時点でお手もとにあるPDFで不満のない場合にはそのままでもけっこうです。

(Visited 133 times, 2 visits today)
Posted in Books PRODUCTS | Leave a comment

Post navigation

  • Older posts

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

Google Search

Popular posts

  • AppleScriptによるWebブラウザ自動操縦ガイド
  • macOS 13, Ventura(継続更新)
  • ドラッグ&ドロップ機能の未来?
  • macOS 12.x上のAppleScriptのトラブルまとめ
  • PFiddlesoft UI Browserが製品終了に
  • macOS 12.3 beta 5、ASの障害が解消される(?)
  • SF Symbolsを名称で指定してPNG画像化
  • 新刊発売:AppleScriptによるWebブラウザ自動操縦ガイド
  • macOS 12.3 beta4、まだ直らないASまわりの障害
  • macOS 12.3上でFinder上で選択中のファイルをそのままオープンできない件
  • Safariで表示中のYouTubeムービーのサムネイル画像を取得
  • macOS 12のスクリプトエディタで、Context Menu機能にバグ
  • Pixelmator Pro v2.4.1で新機能追加+AppleScriptコマンド追加
  • 人類史上初、魔導書の観点から書かれたAppleScript入門書「7つの宝珠」シリーズ開始?!
  • CotEditor v4.1.2でAppleScript系の機能を追加
  • macOS 12.5(21G72)がリリースされた!
  • UI Browserがgithub上でソース公開され、オープンソースに
  • Pages v12に謎のバグ。書類上に11枚しか画像を配置できない→解決
  • 新発売:AppleScriptからSiriを呼び出そう!
  • iWork 12.2がリリースされた

Tags

10.11savvy (1102) 10.12savvy (1243) 10.13savvy (1391) 10.14savvy (586) 10.15savvy (434) 11.0savvy (274) 12.0savvy (174) 13.0savvy (34) CotEditor (60) Finder (47) iTunes (19) Keynote (97) NSAlert (60) NSArray (51) NSBezierPath (18) NSBitmapImageRep (21) NSBundle (20) NSButton (34) NSColor (51) NSDictionary (27) NSFileManager (23) NSFont (18) NSImage (42) NSJSONSerialization (21) NSMutableArray (62) NSMutableDictionary (21) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (118) NSURL (97) NSURLRequest (23) NSUTF8StringEncoding (30) NSUUID (18) NSView (33) NSWorkspace (20) Numbers (55) Pages (36) Safari (41) Script Editor (20) WKUserContentController (21) WKUserScript (20) WKWebView (23) WKWebViewConfiguration (22)

カテゴリー

  • 2D Bin Packing
  • 3D
  • AirDrop
  • AirPlay
  • Animation
  • AppleScript Application on Xcode
  • beta
  • Bluetooth
  • Books
  • boolean
  • bounds
  • Bug
  • Calendar
  • call by reference
  • Clipboard
  • Code Sign
  • Color
  • Custom Class
  • dialog
  • drive
  • 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
  • Machine Learning
  • Map
  • Markdown
  • Menu
  • Metadata
  • MIDI
  • MIME
  • Natural Language Processing
  • Network
  • news
  • Noification
  • Notarization
  • Number
  • Object control
  • OCR
  • OSA
  • PDF
  • Peripheral
  • PRODUCTS
  • QR Code
  • Raw AppleEvent Code
  • Record
  • 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)
  • 未分類

アーカイブ

  • 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