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

タグ: 10.15savvy

OSADictionaryViewの情報がない

Posted on 10月 12, 2020 by Takaaki Naganoya

macOS 10.10以降、通常のAppleScriptでもCocoaオブジェクトへのアクセスが許可されたため、macOSの中に存在するAppleScript系の機能への理解が深まりました。

正確にいえばOS X 10.6でXcode上のCocoa AppleScriptアプリケーション内でCocoaの機能が利用できたわけですが、やはり通常のAppleScriptの中で利用できると理解の度合いが違います。

そうしたCocoaなどのmacOSのAPIは数多くあり、今日ではPDF関連の処理など専用のアプリケーションを使わずにたいていの処理ができるようになり、Web上のREST APIを自在に呼び出せるようになり、各種画像フィルタ処理や機械学習までAppleScriptから呼び出せるようになりました。Cocoaの機能が呼べなかった時代に戻れと言われたら途方に暮れてしまうレベルで日常的な風景になりました。

そんなmacOS側の機能に、AppleScript系の機能が用意されています。

大きく分けると、

①Cocoa系のOSAKit。AppleScriptを実行したりOSAコンポーネント情報を取得するなどの機能。AppleScriptから日常的によく使っています。

②AppKit内のNSAppleScript。AppleScriptの実行を行うための部品と、プロセス間通信のAppleEventsまわりの機能です。このあたりはAppleScriptからは手が出ません。

③Carbon系のOpenScripting。AppleScript言語処理系そのものといってよいでしょう。まったく手が出ません。

などの機能の所在がわかっています。Xcode上から調べるとヘッダーファイルも調査できて、どのようなメソッドが揃っているかも確認できます。

これらの他に、割とメジャーそうな機能なのにヘッダーファイルも何も一切公開されていないオブジェクトがあります。

それが、AppleScript用語辞書の表示関連のOSADictionaryViewとOSADictionaryControllerです。

これについては、不思議と情報が何もありません。あたりをつけて、「おそらくPathかURLをコントローラーに渡して初期化するとViewに表示するんだろう」と試しているのですが、まったく歯が立ちません。


▲macOS 10.14.6+Xcode 11.3.1の組み合わせで、OSADictionaryViewをドラッグ&ドロップで部品配置すると、その瞬間にXcodeがクラッシュ(事前にプロジェクトにOSAKit.frameworkをinclude)。この環境にはNSBrowserなど同様の瞬間クラッシュを引き起こす部品がある。macOS 10.15上では修正されているため、10.14上での対処は行わないとAppleから明言されました

とりあえずは、いつものアラートダイアログ上でOSADictionaryViewを表示して、指定のsdefファイルを表示するレベルからはじまって、GUIアプリケーション上でSDEF表示機能を実装するところがゴール地点でしょうか。失敗を重ねながら何度も調査やテストを行うことになります。

OSADictionaryView/OSADictionaryControllerの情報があったところで、これが使い物になるのかどうかという疑問があります。

OSADictionaryViewが使えたとして、それはsdefファイルのパスなりURLを渡して表示させるようなものになると想像されますが、このsdefに外部のファイルをincludeするような記述ができるようになったことで、「対象アプリケーションが実際に起動しないとAppleScript用語辞書全体を取得することができない」という状況に。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
<dictionary xmlns:xi="http://www.w3.org/2003/XInclude">
	<!-- We override some standard commands to add several optional properties. -->
	<suite name="Standard Suite" code="????" description="Common classes and commands for all applications.">
		<xi:include href="file://localhost/System/Library/ScriptingDefinitions/CocoaStandard.sdef" xpointer="xpointer(/dictionary/suite/node()[not((self::command and (@name = 'open')) or (self::class and (@name = 'window')))])"/>

▲最近のMicrosoft Officeアプリケーションでは、sdefのサイズ縮小のためかxi:includeの記述が見られる

Adobeのアプリケーションには、sdefファイルを起動後にプログラムで生成しているものもあるため、起動前の状態でsdefファイル単独でブラウズできてもあまり意味がないケースが生じてしまいます。

つまり、Viewを単体で利用できても不十分かつ部分的なAppleScript用語辞書しか表示できないのではないか? という疑問を持つわけです。


▲1:17秒あたりでToolbar上のコマンドからAppleScript用語辞書の表示を行わせています。これは、Script Editorに辞書の表示を行わせる処理です

実際、スクリプトエディタに指定アプリケーションのAppleScript用語辞書を表示するような命令は行えるので、結局はそちらを使うことになるのではないかと考えるものです。苦労して使い方を突き止めたとしても、実用性がなかったら残念なことです。そして、その可能性がきわめて高そうな気配がしているのです。

Posted in GUI OSA | Tagged 10.14savvy 10.15savvy 11.0savvy | Leave a comment

Pixelmator Pro AppleScriptコンテストで優勝

Posted on 10月 11, 2020 by Takaaki Naganoya

LateNight Software主催の「Pixelmator Pro AppleScriptコンテスト」で優勝しました。応募作品はPixelmatorもぐらたたきゲームです。

応募するにあたって、まず最初に、「まともにPixelmator Proの機能を活用する」か「Pixelmator Proの機能を無視する」かの2つの方向のどちらを採用するかを考えました。

100行以内というレギュレーションがけっこう厳しかったので、前者のアプローチだとすぐに限界に達するように思われました。それ以前に、使いこなしてもいない、ほぼ初見のアプリケーションを相手に有用なAppleScriptを書くのはほぼ無理といってよいでしょう。実際に対象のアプリケーションを使いこなして、そのアプリケーションが想定しているワークフローをこなしてみて、自分の意図するデータを作って、その作業の中で不満に思ったり効率がよくない点をAppleScriptで補っていくのが「普通のAppleScript」の書かれ方でしょう。

短期間でコンテストに投稿するとなると、ウケ狙いでアプリケーション全体の機能を理解せず一部の機能に着目してまったく関係のない用途のものを作る必要があると判断しました。

もうちょっと使いこなすための期間が長ければ、Pixelmator Proの機能を使い込んで、Pixelmator Proならではのソリューションも出てきたと思います。

なので、Pixelmator Pro AppleScriptコンテストの賞品であるところのPixelmator Pro v1.8を使えれば、「本来こういうものがあるべき」というScriptを書くことも可能だと思われます。

告知ページには、

To celebrate the introduction of AppleScript support in Pixelmator Pro 1.8 I’m giving away three copies of Pixelmator Pro. 

と、明記されているので「Pixelmator Pro」(macOS版)が賞品だと思っていたのですが、なぜか送られてきたのが「Pixelmator Photo」(iOS版)のコードで、何か手違いが生じただけだと思いたいのですが、どんなものなんでしょう? → 報告したらちゃんとPixelmator Proのコードが届きました。ねんのため

Pixelmatorもぐら叩きゲームについて


◀︎開発中のFMバトラー(1999年)

1999年のMacWorldExpo/Tokyoでデモを行った「FMバトラー」で、すでに「まったくゲーム用ではないアプリケーション(FileMaker Pro)を使ってゲームを作るという経験がありました。

基本的には、Pixelmator Pro書類上に並べたレイヤーの表示状態を制御して、パラパラアニメを表示。その一方でModifier Keyのキースキャンを行なって、ユーザーからの操作を受け取っています。

レギュレーションに「Script Debugger上で動作すること」という項目があり、Modifier Keyのスキャンであれば最前面にいないScript Debuggerでも問題なくスキャンできるため、対応が可能でした。

プログラムは、とにかく短く書くことが課題で、初期段階ではキースキャン部分だけで20行を超えていたものを大幅に短くしています。

もぐら叩きの本体部分もモグラが3段階で迫ってくるという設定を作り、step 1とstep 2の状態でユーザーからの入力があったら「お手つき」的な失敗を行ったという処理をしています。step 3の状態でのみもぐらの撃退が可能で、そのことをデータで表現しています。

set moleList to {{"Mole1", false, 20}, {"Mole2", false, 10}, {"Mole3", true, 20}}

良くも悪くも「Pixelmator Proでゲームを作ろう」という着想自体がすべてであり、プログラム自体はそれほど複雑でも高尚でもありません。

–> Download Piyomaru Whack-3-moles Game(実行に必要なPixelmator Pro書類)

プログラム自体を掲載していてもあまり参考にならないとは思いますが、本来作りたかった「もぐらが同時に3匹出てくるもぐら叩きゲーム」は見てみたいので、より高度なバージョンに書き換えた人がいればぜひ見せてください(^ー^;

最後に、Pixelmator Proもぐらたたきのグラフィックについて。8bit時代のピコピコゲーム(この部分、Google翻訳で非日本語話者に意味が通じるのだろうか?)を彷彿とさせる簡単さで「たいした手数はかけていない」ことが伝わることを重視しています。Pixelmator Proは写真の加工など高い能力を持ったグラフィックソフトなわけですが、あえてグラフィックソフトらしい写実的かつ写真をベースとした生々しいもぐらの絵を使うことは避けました。

また、あからさまにゲームであることがわかるよう背景も単純な色とし、一般的なPixelmator Proの利用シーンとは異なる状況下にあることをユーザーに知らせるように設計しました。絵心のある人ならもっと凝ったグラフィックを描いて表示するはずですが、そういう作り込み要素を排することで「自分にも作れそうだ」という印象を持ってもらうことを重視しています。あと、生き物の殺生を思わせるような生々しい表現(流血とか)は避けています。

AppleScript名:Mole Game v1.1.1a.scpt
–  Created by: Takaaki Naganoya
–  Created on: 2020/09/29
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit" — for NSEvent

set aScore to 0
set aMiss to 0
set maxMole to 3 —change mole attack number
set delayCount to 300 –delay speed. Faster machine needs larger number.

tell application "Pixelmator Pro"
  activate
  
if (exists of document "Piyomaru Whack-3-moles Game") = false then
    display dialog "There is no Piyomaru document" buttons {"OK"} default button 1 with icon 1
    
return
  end if
  
  
tell document "Piyomaru Whack-3-moles Game"
    set visible of layer "Mole1" to false
    
set visible of layer "Mole2" to false
    
set visible of layer "Mole3" to false
    
set visible of layer "Mole3Hit" to false
    
set visible of layer "Mole3Miss" to false
    
    
repeat 10 times
      tell layer "Title"
        set its visible to true
        
set keyRes to keyscanWait(delayCount, true) of me
        
set its visible to false
        
set keyRes to keyscanWait(delayCount, true) of me
        
if keyRes = true then exit repeat
      end tell
    end repeat
    
    
delay 1
    
    
set moleList to {{"Mole1", false, 20}, {"Mole2", false, 10}, {"Mole3", true, 20}}
    
repeat maxMole times
      repeat with i in moleList
        copy i to {layerName, hitLogic, delayTime}
        
set visible of layer layerName to true
        
set keyRes to keyscanWait((random number from 1 to delayTime) * delayCount, hitLogic) of me
        
set visible of layer layerName to false
        
        
if keyRes = true then
          set hitF to true
          
set aScore to aScore + 1
          
beep
          
set visible of layer "Mole3Hit" to true
          
delay 1
          
set visible of layer "Mole3Hit" to false
          
exit repeat
        else if keyRes = false then
          set aMiss to aMiss + 1
          
repeat 3 times
            set visible of layer "Mole3Miss" to true
            
delay 0.5
            
set visible of layer "Mole3Miss" to false
            
delay 0.5
          end repeat
          
set keyRes to true –To Skip See off action
          
exit repeat
        end if
      end repeat
      
      
if keyRes is not equal to true then
        set aMiss to aMiss + 1
        
repeat 3 times
          set visible of layer "Mole3Miss" to true
          
delay 0.5
          
set visible of layer "Mole3Miss" to false
          
delay 0.5
        end repeat
      end if
    end repeat
    
    
display dialog "Score:" & (aScore as string) & return & "Miss:" & (aMiss as string) with title "GAME OVER" buttons {"OK"} default button 1 with icon 1
    
  end tell
end tell

on keyscanWait(delayLoop, hitLogic)
  repeat delayLoop times
    set commandStatus to not ((((current application’s NSEvent’s modifierFlags() as integer) div (current application’s NSShiftKeyMask as integer)) mod 2) = 0)
    
if commandStatus = true then return hitLogic
  end repeat
  
return missing value
end keyscanWait

★Click Here to Open This Script 

Posted in GAME | Tagged 10.15savvy Pixelmator Pro | 1 Comment

LAN上の別のMacでYouTubeムービー再生をハンズオーバー v2

Posted on 10月 8, 2020 by Takaaki Naganoya

Safariの最前面のウィンドウで再生中のYouTubeムービーの情報を取得し、LAN上の別のMacで再生を引き継ぐ(ハンズオーバーする)AppleScriptです。

macOS 10.13以降、リモートAppleEvents経由でGUIアプリケーションを直接操作する機能が復活しました(Mac OS X 10.7〜10.12ぐらいまでAppleScriptアプレット間のみリモート通信が許可されていた状態)。

メインマシンで再生中のYouTubeムービーを、LAN上の他のマシンに引き継がせてみました。再生を引き継がれる方のマシンでは、システム環境設定の「共有」で「リモートApple Events」の項目をオンにしています(自分のマシンではすべてこの項目をオンにしています)。

(1)リモートマシン上のユーザーのパスワード

AppleScript書類のコメント(Finderコメント)にパスワードを書いておくと、それを読み取って使用するようにしてみました。

(2)リモートマシン上のSafariの起動

リモートマシン上のアプリケーションの操作は、ただリモートマシン上のアプリケーションを指定すればOKなのですが、操作対象のアプリケーションが起動していない場合にはエラーになります。これは、とても困る仕様です。

そこで、リモートマシンのFinder経由でアプリケーションファイルをオープンすることで、リモートマシン上でSafariを起動します。オープン対象をapplication file “Safari”と指定するとエラーになりますが、application file id “com.apple.Safari”と指定するとエラーになりません。

(3)YouTubeで再生中の情報取得

以前調査しておいた内容をそのまま使っています。再生中ならPauseし、再生中の位置(時間)情報を取得し、文字列で指定するために加工してYouTubeのURLに追加しています。URLの加工部分は少々手抜きをしています。

とくに問題なく、メインマシンから他のマシン(macOS 10.15.7/macOS 11.0beta9)にLAN経由で再生をハンズオーバーできました。

実際に、コントロール先のマシン名(Bonjour名)をremoteMachineNameに、ユーザー名をremoteUserNameに、パスワードを実行するAppleScript書類のFinderコメントに書き込んで実行してください。スクリプトエディタ上でもスクリプトメニューからでも問題なく実行できています。

あとは、Safari上のYouTube再生をフルスクリーンで行えるとよいのですが、少し試した範囲ではできなかったので、また地道に調べておく感じでしょうか。

AppleScript名:LAN上の別のMacでYouTubeムービー再生をハンズオーバー v2.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/10/08
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

property |NSURL| : a reference to current application’s |NSURL|
property NSMetadataItem : a reference to current application’s NSMetadataItem

set remoteMachineName to "MacMini2014.local"
set remoteUserName to "maro"

–ScriptのCommentに書いておいたパスワードを拾って使う
set mePath to (path to me)

–FinderからCommentは拾えるが、メタデータ経由で取得する処理も試してみた
set remoteUserPass to getFinderComment(POSIX path of mePath) of me

tell application "Safari"
  if running then
    tell front document
      set aURL to URL
      
–最前面のウィンドウがYouTubeの場合のみ処理
      
if aURL does not start with "https://www.youtube.com/" then
        display notification "エラー: YouTubeを再生していないため、ハンズオーバーしませんでした"
        
return
      end if
      
      
–再生中のポジションを取得
      
set tRes to (do JavaScript "document.querySelector(’#movie_player video’).currentTime;")
      
      
–再生状況を取得
      
set pRes to (do JavaScript "document.querySelector(’#movie_player video’).paused;")
      
      
if pRes = false then
        –再生中であればPauseする
        
set aRes to (do JavaScript "document.querySelector(’#movie_player .ytp-play-button’).click();")
      end if
      
      
openYouTubeOnRemoteMachine(remoteUserName, remoteUserPass, remoteMachineName, tRes, aURL) of me
    end tell
  end if
end tell

–指定のリモートマシン上のSafariでYouTubeの指定ムービーの指定箇所からの再生を行う
on openYouTubeOnRemoteMachine(remoteUser, remotePass, remoteMachineLocal, newDuration, newURL)
  set remoteMachineName to "eppc://" & remoteUser & ":" & remotePass & "@" & remoteMachineLocal
  
  
–URLの加工。ちょっと手抜きをした
  
if newDuration is not 0 then
    set tText to retTimeText(newDuration) of me
    
if newURL contains "&" then
      set sepChar to "?"
    else
      set sepChar to "&"
    end if
    
    
set newURL to newURL & sepChar & "t=" & tText
  end if
  
  
using terms from application "Safari"
    tell application "Safari" of machine remoteMachineName
      if not running then
        –起動していなかったらあらためてSafariを起動
        
launchRemoteSafari(remoteMachineName) of me
      end if
      
      
try
        close every document
      end try
      
      
set aWin to make new document
      
      
tell aWin
        set URL to newURL
        
–フルスクリーン再生をためしてみたが、こういう書き方ではなかった模様(URLオープンを待つ必要もある)
        
–set aRes to (do JavaScript "document.querySelector(’#movie_player playFullscreen’).click();")
      end tell
      
    end tell
  end using terms from
end openYouTubeOnRemoteMachine

–リモートマシン上でSafariを起動する
on launchRemoteSafari(aMachine)
  using terms from application "Finder"
    tell application "Finder" of machine aMachine
      open application file id "com.apple.Safari"
    end tell
  end using terms from
end launchRemoteSafari

–数値を「h」「m」「s」でフォーマットして返す
on retTimeText(aTime)
  set aHour to aTime div 3600
  
set aMinute to (aTime – (aHour * 3600)) div 60
  
set aSeconds to (aTime mod 60)
  
  
set aString to ""
  
  
if aHour > 0 then
    set aString to aHour & "h"
  end if
  
  
if aMinute > 0 then
    set aString to aString & (aMinute as integer) & "m"
  end if
  
  
if aSeconds > 0 then
    set aString to aString & (aSeconds as integer as string) & "s"
  end if
  
  
return (aString as string)
end retTimeText

–Finderコメントをメタデータ経由で取得
on getFinderComment(aPOSIX)
  set aURL to |NSURL|’s fileURLWithPath:aPOSIX
  
set aMetaInfo to NSMetadataItem’s alloc()’s initWithURL:aURL
  
set metaDict to (aMetaInfo’s valuesForAttributes:{"kMDItemFinderComment"}) as record
  
if metaDict = {} then return ""
  
set aComment to kMDItemFinderComment of (metaDict)
  
return aComment
end getFinderComment

★Click Here to Open This Script 

Posted in Internet JavaScript Remote Control | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy Finder NSMetadataItem NSURL Safari | 14 Comments

AppleScriptによるクリップボード処理

Posted on 10月 6, 2020 by Takaaki Naganoya

Classic Mac OSの頃は「しかたなく」クリップボードを使って行う処理がありましたが、最近(Mac OS X移行後)では極力使わないようにしています。文字コード変換、スタイル付きテキストのプレーンテキスト化などクリップボードを経由しないとできない処理がたくさんありました。画像の形式変換ですらクリップボードを経由して処理していた記憶があります。

仕方なく使っていましたが、「なんでこれしきの処理でクリップボードを経由しないといけない?」と不満だらけでした。クリップボードを経由する処理があるということは、人間がGUI経由で作業をしている裏で動かすScriptを作りにくくなるということです。クリップボード処理を多用していた頃のAppleScriptのプログラムは、絶対に人がマシンに手を触れないようにして動かす必要がありました(最前面のアプリケーションを変更してしまうと処理が破綻するなど)。

クリップボード経由の処理は確実さという意味で100%といえませんし、挙動が非同期っぽくて、値が反映されるまでに時間差があるため、クリップボードの内容変更をAppleScript側から監視して反映されるまでループで待つなどのケアが必要になります。

また、クリップボードを利用する方法によって100倍以上も差が出ます。遅い方法を選択すると、遅いばかりではなく信頼性もいまひとつです。

(1)Cocoa Scripting

Cocoaの機能を呼び出して、クリップボード(ペーストボード)の操作を行います。多彩な機能を呼び出すことができ、スピードも最速です。ただし、初回実行時のみ遅くなる傾向があるのと、HDD搭載機では極端に遅くなる場合がある(SSD必須)ので注意が必要です。

(2)AppleScript内蔵標準コマンドを利用

クリップボードにデータを入れる「set the clipboad」、クリップボードからデータを取り出す「the clipboard」、クリップボードの情報を取得する「clioboard info」などがあります。スピードも遅くないのですが、本コマンドでクリップボード内容を捕捉できるまでに(クリップボードの内容が反映されるまでに)若干時間がかかります。

(3)do shell scriptコマンド経由でpbcopyコマンドを実行

shell commandの「pbcopy」「pbpaste」を呼び出して実行します。可もなく不可もなく。スピードは(1)(2)にくらべると10倍以上遅いですが、問題にはなりにくいでしょう。ただ、これをあえて使う状況が考えられません。

(4)GUI Scripting経由でメニュー操作してコピー/ペースト

もっとも遅くて信頼性のない方法です。最速の①や②にくらべると、100倍以上も遅くなります。信頼性もなく、あまり多用できないため、本当に最後の最後に部分的に使うぐらいです。AppleScriptからは生成できないオブジェクトをアプリケーションの書類上で移動させる場合などに、仕方なくGUIを操作してコピー&目的の場所(別のページなど)でペーストを行うような感じでしょうか。それでも、各オブジェクトを逐一コピー&ペーストするのではなく、まとめてコピー&まとめてペーストすべきでしょう。コピー&ペーストの回数を減らすことが安全動作につながります。

その他、クリップボードを用いた処理を行う場合には、処理の最初にクリップボード内容を退避しておき、処理後に退避内容を戻すなどのケアも必要になります。


▲(c)秋本治、集英社

注:AppleScriptの書類形式が通常形式かバンドル書類形式かで実行速度に差が出ることはありません。ただし、アプリケーション内部のメニューやフォルダアクション、SwitchControlなどの各実行環境において「通常形式のみ。バンドル形式は受け付けない」といった制約が生じることはあります。実行速度については、Automatorやショートカット上のAppleScript実行アクションで動かすと、とりわけ遅くなります

AppleScript名:①ASOCでクリップボード操作.scpt
–Created 2015-08-03 by Shane Stanley
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit" — for NSPasteboard

my restoreClipboard:{"ABC"}

–クリップボードに内容を設定する
on restoreClipboard:theArray
  — get pasteboard
  
set thePasteboard to current application’s NSPasteboard’s generalPasteboard()
  
  
— clear it, then write new contents
  
thePasteboard’s clearContents()
  
thePasteboard’s writeObjects:theArray
end restoreClipboard:

★Click Here to Open This Script 

AppleScript名:②set the clipboardコマンド.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/10/06
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

set the clipboard to "ABC"

★Click Here to Open This Script 

AppleScript名:③do shell script経由でpbcopy.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/10/06
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

do shell script "echo ’ABC’ | pbcopy"

★Click Here to Open This Script 

AppleScript名:④GUI Scripting経由でメニュー操作.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/10/06
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

activate application "Safari"
tell application "System Events"
  tell process "Safari"
    click menu item "コピー" of menu 1 of menu bar item "編集" of menu bar 1
  end tell
end tell

★Click Here to Open This Script 

Posted in Clipboard | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy | Leave a comment

AppleScriptでリアルタイムキースキャンを行いCotEditor書類上にカーソル描画

Posted on 10月 4, 2020 by Takaaki Naganoya

Modifier Keyのリアルタイムキースキャンを行なって、CotEditor書類上に文字でカーソル描画するAppleScriptです。30 x 30 の文字数のテキストを作成し、CotEditor書類に随時転送することで書き換えています。

AppleScriptでキースキャンといえば、Script/Applet起動時にoptionやcontrolなどのmodifier keys(装飾キー)が押されているかどうかを確認して、動作内容を変更するような用途でした。AppleScriptでGUIを作るのが大変だとか、AppleScriptで気軽にGUIを呼び出せない時代には、割と使われてきた手段です。

そんな中、macOS 10.10以降でCocoaの機能が気軽に利用できるようになってきたことで、Cocoaのキースキャン機能が利用できるようになりました。前述のModifier KeysのスキャンはmacOS側のセキュリティ機構でも問題視していないようで、気軽に使えそうです。ちなみに、SHIFTキーの左右は区別できません。

先日Pixelmator Proで「もぐら叩きゲーム」を作った際にも、このModifier Keysのスキャンは利用しましたが、実際にどの程度使い物になるのか確認しておきたいと考え、AppleScriptからの操作が高速なアプリケーションで試してみることにしてみました。

CotEditorにテキストで描画した画面を転送し、毎回テキスト内容をすべて書き換えることで本格的なゲームの用途に使えるのではないかと考えました。自分ではほとんどゲームを作ったこともないので、別にゲームを量産するつもりはありませんが……。テトリスぐらいならCotEditorのメニューから呼び出すAppleScript内で実行できそうな感じがします。

→ 冗談半分でAppleScriptで作られたTetrisを探してみたら、見つかりました

CotEditorでなくても、他のエディタでも同様の操作はできると思います。

AppleScript名:KeyScan TEST v3.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/10/03
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit" — for NSEvent
use scripting additions

–Initialize
set curPosX to 1
set curPosY to 1
set curMax to 30

set rText to ""
repeat curMax times
  set rText to rText & "🛑"
end repeat

tell application "CotEditor"
  write to console "Real-time Keyscan test with Modifier Keys
  [ Control ]    : Move Left
  [ Shift ]    : Move Right
  [ Option ]    : Move Up
  [ Command ]  : Move Down

  [ Caps Lock ]  : Quit this script"
  
  
make new document
  
activate
end tell

–Main Loop
repeat
  set leftF to my checkModifier:"control"
  
set rightF to my checkModifier:"shift"
  
set upF to my checkModifier:"option"
  
set downF to my checkModifier:"command"
  
  
set quitF to my checkModifier:"caps"
  
  
if quitF = true then return
  
  
if leftF = true then
    if curPosX > 1 then
      set curPosX to curPosX – 1
    end if
  else if rightF = true then
    if curPosX ≤ curMax then
      set curPosX to curPosX + 1
    end if
  end if
  
  
if upF = true then
    if curPosY > 1 then
      set curPosY to curPosY – 1
    end if
  else if downF = true then
    if curPosY < curMax then
      set curPosY to curPosY + 1
    end if
  end if
  
  
  
–make display text
  
set aText to ""
  
repeat with i from 1 to curMax + 1
    if i = curPosX then
      set aText to aText & "🛑"
    else
      set aText to aText & "㍳"
    end if
  end repeat
  
  
  
set bText to ""
  
repeat with y from 1 to curMax
    if y = curPosY then
      set bText to bText & rText & return
    else
      set bText to bText & aText & return
    end if
  end repeat
  
  
my displayText(bText)
  
end repeat

–テキスト画面描画
on displayText(aText)
  tell application "CotEditor"
    tell front document
      set contents to aText
    end tell
  end tell
end displayText

–複数同時検出に対応
on checkModifier:keyName
  if keyName = "option" then
    set theMask to current application’s NSAlternateKeyMask as integer
  else if keyName = "control" then
    set theMask to current application’s NSControlKeyMask as integer
  else if keyName = "command" then
    set theMask to current application’s NSCommandKeyMask as integer
  else if keyName = "shift" then
    set theMask to current application’s NSShiftKeyMask as integer
  else if keyName = "caps" then
    set theMask to current application’s NSEventModifierFlagCapsLock as integer
  else if keyName = "num" then
    set theMask to current application’s NSEventModifierFlagNumericPad as integer
  else if keyName = "help" then
    set theMask to current application’s NSEventModifierFlagHelp as integer
  else if keyName = "fn" then
    set theMask to current application’s NSEventModifierFlagFunction as integer
  else
    return false
  end if
  
  
set theFlag to current application’s NSEvent’s modifierFlags() as integer
  
if ((theFlag div theMask) mod 2) = 0 then
    return false
  else
    return true
  end if
end checkModifier:

★Click Here to Open This Script 

Posted in System | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy CotEditor NSEvent | Leave a comment

Mac App StoreでTable Dripper v1.1が審査中

Posted on 10月 2, 2020 by Takaaki Naganoya

Mac App StoreにWebの表データ(tableタグで書かれた表)のインタラクティブ・スクレーパーである「Table Dripper」のバージョン1.1を申請し、目下審査中です。

データスクレイパーの多くは、定期巡回してまとめてサイトのデータを取ってくるものですが、Table DripperはWebブラウザで表示中の、いま目の前にある見えている表データを取り出すことに特化しています。

v1.0の審査は10日ぐらいかかったのですが、今回はもう少し早く結果が出て欲しいところです。

v1.0がAppleの承認を経て公開になったあとで、あとから「やっぱりこのアプリ、Mac App Storeの規約に反しているのでー」と言ってきたので、その部分に手を加えてアップデートしました。

temporary items folderにユーザーがアクセスできてしまうことを問題視したようです。他のアプリケーションの審査では指摘されていた項目ではあったものの、当時Mac App Storeの審査に1人で同時に3本ぐらい突っ込んでおり、他のレビューでは指摘されていた内容でした。

ちなみに、ダルそうに電話してきたApple側の担当者は「Table Dripper」という単語を読めませんでした(おかわいらしい!)。「Sandboxの仕様で話はわかるが、どう回避しろと?」と問えば、自分はそんなことは知らない、とのこと。

なるほどー、文字が読めない人間に電話させてくるのかー、知能のない人間を担当にして反論を封じるとはなかなか洒落たことをするものであります。言葉のわからないにゃんこちゃんに反論はできませんので。

これを、難しい専門用語で「サンドボックス環境」ならぬ「サンドバック担当」と呼びます。


▲起動時にDrip Folder(作業用の表データ書き込み先フォルダ)の選択を求められるようになりました。Sandboxの仕様上、動作を変えた部分


▲5つのWebブラウザをサポート。FireFoxやOperaはAppleScriptのサポートが弱い(do javascriptに相当するコマンドがない)ためにサポートできません


▲表データの解釈機能を大幅に強化。取り込み時に行ヘッダーを削除する機能を追加


▲表データをHTML形式でも取り込めるようにしました(CSVに解釈できない場合への対処)


▲行ヘッダー削除のパターンを図示(ねんのため)

Posted in news PRODUCTS | Tagged 10.14savvy 10.15savvy 11.0savvy | Leave a comment

Pixelmator Pro AppleScriptコンテストに「もぐら叩きゲーム」を応募

Posted on 9月 29, 2020 by Takaaki Naganoya

LateNight Software主催のPixelmator Pro AppleScriptコンテストに応募してみました。

応募内容は、「もぐら叩きゲーム」です。

Pixelmator Proというグラフィックソフトを使ってもぐら叩きゲーム。不可能ではありません。

Pixelmator ProのAppleScript用語辞書をながめていたら、レイヤーごとの表示/非表示を制御できることがわかったので、レイヤーをセルに見立ててパラパラアニメーション的なものを表示しつつCocoaの機能を使ってキースキャンするとできそうだと思っていました。作ってみたら、問題なくできてしまったと。

このもぐら1匹バージョンのもぐら叩きは1時間ぐらいで出来たのですが、3匹バージョンを試してみたところ、とても100行に収まりきらない感じだったので、3匹バージョン構想は破棄しました(時間かけるような内容でもないですし)。

コンテストのレギュレーションを詳細にチェックすると、1つの外部ファイルの読み込みはOKということになっており、表示用のPixelmator Pro書類がこれに該当するかどうか、という点が気になっていました。

こういうレギュレーションの機敏については、コンテスト開催側の胸先三寸で決められる部分なので、主催者側に判断をおまかせするしかありません。

あとは、環境に応じて時間待ちループ時間を大幅に変えないとダメそうです。AppleScriptObjCのプログラムは、HDDで動いているMac上だと極端に遅くなる傾向があるので、たまたま手元でmacOS 10.15.7を動かしている隔離環境(10.15のテスト環境)だとずいぶん動作が遅い(実際にはAppleScriptの実行が速すぎてウェイト入れまくっているんですが)印象を受けました。

このあたり、実行環境のパフォーマンスを計測して時間待ちの長さを適宜調節すべきなんですが、そういうパフォーマンス計測だけで数十行ぐらいは平気でかかってしまうので、100行以内というレギュレーションだとかなり無理な感じがします。Pixelmator Proに新規書類作成などのコマンドを送ってみて、どのぐらいの時間で処理できるかをその場で計測し、パフォーマンスを計ってウェイト時間を調整するべきなんでしょう。

ただ、コンテスト用のScriptだし、なるべくシンプルなものがいいんでしょう。音がないとさびしいので、iTunesなりMusic.appをコントロールしてBGMを鳴らそうと思っていたんですが、行数が足りなくてダメでした。

Pixelmator Pro向けには、KamenokoのデータをPixelmator Proのネイティブオブジェクトで内容を再現するものを試作して動かしています。ただ、1書類の内容を再構成すると40秒ぐらいかかるのと、Pixelmator Proのオブジェクトで再現するよりPDFベースでコピペしたほうが綺麗だったので、そのプログラムはお蔵入りしています。

この手の「とてもゲームが作れるようには見えない」アプリケーションを使って別のものを仕立てるのは、実は慣れたもので……

Mac World Expo/Tokyoでデモした「FMバトラー」(ファイルメーカーProをAppleScriptでコントロールしてホームページ対戦ゲームに仕立てたデモプログラム)など、これまでにもいろいろ作ってきました。

さらに、Cocoaの機能がAppleScriptから直接呼べるようになったので、複数キーの同時入力受付(正確には、ShiftやControlなどのModifier Keyのキースキャン)といったあからさまにゲームが作りやすそうな機能を利用できるようになったので、過去の無理やりつくったデモ用ゲーム風システムよりも、今回は作りやすかったといえます。

でも、真剣に「Pixelmator Proで込み入ったゲームを作れるんだろうか?」と試してみたところ、そこまでのパワーはありませんでした。オブジェクトの属性値の変更も、様子を見ながら限定されたものを操作するのは向いているものの、大量のオブジェクト操作を行うとアプリケーション側がついてきません。

きしくも、応募作品のもぐら叩きゲームは「奇跡的にちょうどいいバランス」で成立していることがわかりました。

後日、「外部プログラムの威力を利用して画像認識機能をPixelmator Proに足してみては?」と、Web APIとかdarknet(YOLO v3 model)を併用して画像認識した内容をレイヤー名に反映させたりと試していたところ……Pixelmator Proにやられました。

Pixelmator Proにはデフォルトで画像認識機能が入っていて、簡単な動物などの写真はインポートした瞬間に画像認識されて、それっぽいレイヤー名を自動で命名することが判明!

Pixelmator Proのバンドルパッケージを開けてみると、いくつもCore ML Modelのファイルが入っており、深層学習データを併用してさまざまな処理を行なっていることが伺われました。


▲Finder上からPixelmator Pro書類に画像をドラッグ&ドロップすると、その場で画像認識されて「それっぽい」レイヤー名が自動で割り振られる。「犬」とか「鳥」といった名前はPixelmator Proが自動でつけたもの


▲「どうせ認識しないだろ」と思って、ガンダムの画像をドロップしたら「おもちゃ」と認識。たった34MBの深層学習データでどうしたらここまで認識できるのやら。学習データだけでなく、別の手段も併用している???(画像取得元のURLの情報を取っているとか?)

もしかして、各種レイヤーの画像を随時(保存時にでも)画像認識して、ユーザーごとの画像⇄レイヤー名の関連性を学習して、再インポート時には過去の画像から類推して近いものを提案するのでは? などと思ってしまうところです。

これはオシャレです! センスよすぎです。さりげなさすぎて気づきませんでした。出しぬこうと悪だくみしてみたら、相手の方がはるかに上手だったということが判明したのでした。アプリケーションの機能で感動したのは久しぶりです。

Posted in GAME news | Tagged 10.15savvy Pixelmator Pro | Leave a comment

前後に存在するスペースと、文字列中に存在する2個以上の連続するスペースを削除して返す

Posted on 9月 29, 2020 by Takaaki Naganoya

それほど長くない文字列の空白文字列クリーニングを行うAppleScriptです。

 "    First model, with mechanical scroll wheel.           10 GB model released later                             ."

のようなデータを、

 "First model, with mechanical scroll wheel.  10 GB model released later ."

のようにクリーニングします。

フィールド文字列のクリーニング用なので、だいたい256バイト以内。長くても1024バイト程度のデータを想定しています。

とくに、データが長くなった場合に備えての高速化対応処理はしていませんが、それでもCocoaの正規表現系の機能を使った実装よりもだいたい5倍ぐらいは高速です。

画像処理ぐらいのデータ量があるとCocoa系の機能を使ったほうがはるかに高速ですが、この手の小ぶりなデータの処理にはNativeなAppleScriptの処理を行ったほうが高速です。

文字列の先頭と末尾に入っている無駄なスペース(空白文字)を除去し、文字列本体中に入っている「2つ以上連続して存在するスペース」についても除去します。

AppleScript名:前後に存在するスペースと、文字列中に存在する2個以上の連続するスペースを削除して返す.scpt
— Created 2020-09-27 by Takaaki Naganoya
— 2020 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

–指定文字列の前後に存在するスペースと、文字列本体中に存在する2個以上の連続するスペースを削除して返す
set a0Str to " First model, with mechanical scroll wheel. 10 GB model released later ."
set aRes to removeWhiteSpaceRepeatation(a0Str, " ") of me
–> "First model, with mechanical scroll wheel. 10 GB model released later ."

–クリーニング対象文字(たぶんスペース)が処理対象文字列の前後にあったり、途中に2つ以上連続して存在している場合には削除
on removeWhiteSpaceRepeatation(a0Str as string, aChar as string)
  if length of aChar is not equal to 1 then return false
  
  
set a1Str to trimFromHeadAndTail(a0Str, aChar) of me
  
–> "First model, with mechanical scroll wheel. 10 GB model released later ."
  
  
set sucList to detectSuccsessionOfSpace(a1Str, aChar) of me
  
–> {{43, 53}, {80, 108}}
  
  
if sucList = {} then return a1Str
  
  
set allRes to removeRepeatedSpaceChar(a1Str, sucList)
  
  
return allRes
end removeWhiteSpaceRepeatation

–同一文字(スペース)の連続出現リスト({{start pos 1, end pos 1}, {start pos 2, end pos 2}……})をもとにテキストを切り抜く
on removeRepeatedSpaceChar(a1Str as string, sucList as list)
  set aList to characters of a1Str
  
  
set aLen to length of aList
  
set outStr to ""
  
set aCount to 1
  
copy contents of item aCount of sucList to {sItem, eItem}
  
  
repeat with i in sucList
    copy i to {tmpS, tmpE}
    
if aCount = tmpS then
      –Skip
      
copy tmpE to aCount
    else
      set tmpStr to text (aCount) thru tmpS of a1Str
      
set outStr to outStr & tmpStr
      
copy tmpE to aCount
    end if
  end repeat
  
  
if tmpE < aLen then
    set tmpStr to text (tmpE + 1) thru -1 of a1Str
    
set outStr to outStr & tmpStr
  end if
  
  
return outStr
end removeRepeatedSpaceChar

–対象文字列で、2個以上同一文字(スペースを想定)が連続して存在する場合には削除する
on detectSuccsessionOfSpace(a1Str as string, sucTargChar as string)
  set aList to characters of a1Str
  
set aLen to length of aList
  
set newList to {}
  
  
set tmpS to 0
  
set tmpE to 0
  
set spcF to false –false:spaceではない。true:spaceをみつけた
  
set spcCount to 0
  
  
repeat with i from 1 to aLen
    set j to contents of item i of aList
    
    
if j = sucTargChar then –Space 1 char (must be a char)
      
      
if spcF = true then
        –スペースが連続している最中
        
set spcCount to spcCount + 1
      else
        –スペースの連続部分(?)の先頭をフェッチした状態
        
set spcF to true
        
set spcCount to 1
        
copy i to tmpS
      end if
      
    else
      –連続スペースの末端部分
      
if spcF = true then
        copy i to tmpE
        
if spcCount > 1 then
          set the end of newList to {tmpS, tmpE – 1}
        end if
        
set spcCount to 0
        
set spcF to false
      else
        –何もしない
      end if
    end if
    
  end repeat
  
  
return newList
end detectSuccsessionOfSpace

–文字列の先頭と末尾から連続するスペースを検索して削除する
on trimFromHeadAndTail(aStr as string, trimChar as string)
  set aLen to length of aStr
  
set aList to characters of aStr
  
  
–Find not target character from head to tail
  
set aCount to 1
  
repeat with i in aList
    set j to contents of i
    
if j is not equal to trimChar then
      exit repeat
    end if
    
set aCount to aCount + 1
  end repeat
  
  
if aLen ≤ aCount then return ""
  
  
–Find not target character from tail to head
  
set bCount to 1
  
repeat with ii in (reverse of aList)
    set jj to contents of ii
    
if jj is not equal to trimChar then
      exit repeat
    end if
    
set bCount to bCount + 1
  end repeat
  
  
set resStr to text aCount thru (aLen – bCount + 1) of aStr
  
return resStr
end trimFromHeadAndTail

–Written By Philip Aker
–文字置換ルーチン
on repChar(origText as string, targStr as string, repStr as string)
  set {txdl, AppleScript’s text item delimiters} to {AppleScript’s text item delimiters, targStr}
  
set temp to text items of origText
  
set AppleScript’s text item delimiters to repStr
  
set res to temp as text
  
set AppleScript’s text item delimiters to txdl
  
return res
end repChar

★Click Here to Open This Script 

Posted in Text | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy | Leave a comment

mergelyでdiff表示

Posted on 9月 27, 2020 by Takaaki Naganoya

alert dialog上のWebViewに、オープンソースのJavaScript Library「mergely」を呼び出すHTMLを表示し、指定の文字列のdiff表示を行うAppleScriptです。

–> Download diff_disp

CDN上のmergely.jsおよびcssを呼び出しているので、実行にはインターネット接続を必要とします。

Webダイアログ表示部分はscript bundleの中に入れてあるので、上記のアーカイブをダウンロード&アーカイブ展開したものを実行してください。下記のリストではWebダイアログ部分は含んでいないので、Script Linkをクリックして内容をスクリプトエディタに転送して実行しても、必要なファイルが入っていないため動きません(Script Linkではバンドル構造を転送することはできません)。あくまで掲載リストは参考にしていただくためのものです。本Scriptの本体部分はバンドル内に同梱しているHTML(の中のJavaScript部分)です。

diff表示用の部品がOSに用意されていると楽ですが、macOS上のdiff表示用ツール「FileMerge」のdiff表示部品が再利用可能な状態で提供されていないため、よそで部品を探してくることに。FileMerge自体はAppleScript用語辞書を持っていないため、ダイレクトにaliasを指定して2つのファイルの差分表示を行わせることはできません(do shell scriptコマンド経由でオープンさせることは可能)。

サードパーティのGUIアプリケーションでdiff表示機能を持つものをコントロールする場合には、BBEditのdiff表示機能を呼び出すのが手頃で使いやすいでしょうか。

独立した(他のGUIアプリケーションに依存しない)ソリューションとして提供できる形態を想定すると、部品として組み込めるものを探すことになります。この条件に見合うdiff表示用部品はいろいろ探してはいるものの、なかなかいいものが見当たりません。UKDiffViewはAppleのFileMergeに似たルック&フィールを提供する最強クラスの部品ですが、メンテナンスされていなくて現行環境で動かすように書き換えるには手間がかかりそうです(自分には無理です)。

Double PDFをMac App Storeに申請したときには、Reviewでリジェクトをくらっていた中で苦し紛れに「Vimdiff」でdiff表示するバージョンを提出したこともありましたが、これは「Terminal.appをコントロールするアプリケーションは提出不可」というルールに明記されていない理由によりリジェクトを食らいました(セキュリティ上の理由だったか)。

mergelyは(使いこなせれば)なかなかいい部品に見えます。目下、自分はパラメータに改行を含んだ文字列を指定できていないので、そのあたり試行錯誤する必要があることでしょう。

AppleScript名:mergelyでdiff表示.scptd
set aStr to "左側のフィールドの文章をここに書いた。犬と猫を見かけた。"
set bStr to "右側のフィールドの文章をここに書いた。犬と蛇を見かけた。"
set aSize to {1024, 220}
dispDiff(aStr, bStr, aSize) of diffDispLib

script diffDispLib
  –  Created by: Takaaki Naganoya
  
–  Created on: 2020/09/27
  
—
  
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
  
–  https://mergely.com
  
use AppleScript version "2.7" — High Sierra (10.13) or later
  
use framework "Foundation"
  
use scripting additions
  
use webD : script "webDialogLib"
  
  
on dispDiff(aStr, bStr, aSize)
    using terms from scripting additions
      set mePath to path to me
      
set resPath to (mePath as string) & "Contents:Resources:index.html"
      
set myStr to (read (resPath as alias) as «class utf8») as string
    end using terms from
    
    
set aString to current application’s NSString’s stringWithFormat_(myStr, aStr, bStr) as string
    
set paramObj to {myMessage:"Browse diff", mySubMessage:"This is an mergely test", htmlStr:aString, viewSize:aSize}
    
    
webD’s displayWebDialog(paramObj)
  end dispDiff
end script

★Click Here to Open This Script 

Posted in dialog | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy | Leave a comment

iWork Appsのv10.2アップデートが公開される

Posted on 9月 23, 2020 by Takaaki Naganoya

AppleがKeynote/Pages/Numbersのv10.2アッップデートを公開しました。このv10.2から対象OSがmacOS 10.15以降になり、macOS 10.14では最新のKeynote v10.2を使えなくなったことになります。

Keynote v10.2のAppleScript系の機能の差分チェックを(sdefファイルベースで)行ってみたところ、iWorkアプリケーション中でKeynoteのみ機能追加されたことがわかりました。

Keynoteにムービー書き出し機能のAppleScriptオプション機能が追加される

exportコマンドのexport optionsで「movie codecs」と「movie framerates」の指定ができるように機能追加されています。

movie codecs enum
h.264 : H.264
AppleProRes422 : Apple ProRes 422
AppleProRes4444 : Apple ProRes 4444
AppleProRes422LT : Apple ProRes 422LT
AppleProRes422HQ : Apple ProRes 422HQ
AppleProRes422Proxy : Apple ProRes 422Proxy
HEVC : HEVC

movie framerates enum
FPS12 : 12 FPS
FPS2398 : 23.98 FPS
FPS24 : 24 FPS
FPS25 : 25 FPS
FPS2997 : 29.97 FPS
FPS30 : 30 FPS
FPS50 : 50 FPS
FPS5994 : 59.94 FPS
FPS60 : 60 FPS

風の噂によるとどうもARM Macはムービー書き出しが高速なようなので、そのあたりをアピールするためにもムービー書き出し系の機能の拡充は必要ということなのでしょう。

KeynoteのAppleScript用語辞書に構文確認をパスできないバグ持ち予約語が存在

同時に、「こんなんAppleScriptの処理系でコンパイル(構文確認)通るわけないやん、メーカーが何やってますのん?」という予約語がsdef内に書かれていることが一目でわかりました。

「h.264?」

この「h.264」の予約語はexportコマンドのexport optionsのmovie codecsのEnum内に書かれています。

        <enumeration name="movie codecs" code="Knmc">
            <enumerator name="h.264" code="Kmc1" description="H.264">
                <cocoa string-value="AVVideoCodecTypeH264" />
            </enumerator>

macOS 10.15.6上で確認したところ、見事に構文確認時にエラーになります。

Apple製のアプリケーションのAppleによるスクリプティング定義内容がまともに動きません。こうした事態は理解に苦しむものがあります。100%動作確認していないとしか思えません。

ここは、記号入りの予約語では言語処理系的に構文確認すらパスできないので、「h.264」ではなく記号を含まない「h264」ないし「H264」という予約語にすべきです。AppleScript系の機能を追加していただくのは前向きでよいと思いますが、メーカーとして一度も動作確認しないで機能をリリースするというのはいかがなものでしょう?

そんなところに凝っていないで、選択中のオブジェクトを取れる属性「selected objects」とか、テキストオブジェクトの縦書き制御属性「vertical」などをつけたほうが実用性があって助かります。機能追加自体はたいした作業ではありませんが、ぜひ動作確認した上でリリースしていただきたいところです。

AppleScript名:keynote movie export test
–Works with Keynote v10.2 or later
set aTagFile to ((path to desktop) as string) & "testOut.m4v"

tell application "Keynote"
  set exOpt to {compression factor:1.0, movie format:native size, class:export options}
  
–set exOpt to {compression factor:1.0, movie format:native size, movie codec:h.264, class:export options}–this cause error
  
export document 1 to file aTagFile as QuickTime movie with properties exOpt
  
end tell

★Click Here to Open This Script 

日頃からMac App Storeのレビューアーの血も涙もない(でも、ツッコミどころ満載の)リジェクトに遭っている身からすれば、こんなのリジェクト案件です。

個人的には信頼度の問題からmacOS 10.15は「パス」なので、macOS 11.0 Big SurがRelease時にコケないことを祈るのみです(メールが消えるとかいう話が一番OSの信頼度を下げる)。macOS 10.13, “Vista”という史上最悪・最低の大失敗をやらかして以来、「Release版のOSがBetaよりも低品質」という昨今のmacOS。10.13もBetaの時にはよかったのに、Release版で大崩壊を起こして見るも無残な姿に成り果てました。10.14もBetaの段階でGUI Scriptingの認証系でひどいバグがあって、「とても使えない」と判断。10.14.6まで待ってようやく手を出す気になったほど。

macOS 11.0, Big SurはBeta段階でも珍しく好印象で(GUIまわりの仕様はコロコロ変わるけど)、macOS 10.15みたいにBeta段階で「もう、これはダメ!」という話も聞きません(Relase時に紹介記事を書かなかったOSは10.15がはじめてです。10.15の崩壊度はひどかった)。macOS 11.0, Big Surには、macOS 10.13のような「Release版の大崩壊」を起こしてほしくないものです。

Posted in Bug sdef | Tagged 10.15savvy 11.0savvy Keynote Numbers Pages | Leave a comment

SFSymbolsフォントにAppleScript

Posted on 9月 23, 2020 by Takaaki Naganoya

macOS 10.15.x以降で使用できる、よく使われるアプリ内アイコンをフォント化した「SF Symbols」フォントが配布されており、このフォントにAppleScriptアイコンが用意されていることを見つけました(たいした発見ではありません。「へーそうなんだー」ぐらいの内容です)。

「SF Symbolsベータ」アプリケーションをインストールすると、さまざまなカテゴリに区分されたアイコン文字を閲覧、コピーすることができます。

このように、macOS 10.15.x以降にSFSymbolsフォントがインストールされていれば、Keynote書類上に文字情報をコピーすることも可能です(文字なので)。

もしやと思い、macOSの日本語Input Methodのユーザー辞書にこのAppleScriptアイコンを登録。

テキストエディタ(CotEditor)上で「あっぷるすくりぷと」と入力して変換すると、AppleScriptアイコンに変換されました。なるほど。たしかに文字ですわ。

–> ASInput demo movie

Posted in news | Tagged 10.15savvy 11.0savvy | Leave a comment

SFPSDWriterのじっけん v2

Posted on 9月 21, 2020 by Takaaki Naganoya

AppleScriptからPhotoshopのデータ(PSD)を出力するテストプログラムです。

AppleScriptにはPhotoshopのデータを書き出す関数や機能はとくに用意されていないため、Photoshopのデータを書くためにはPhotoshopにコマンドを送って実行してもらうのが定番です。

この定番の方法だと、Photoshopが存在しない環境でPhotoshopのデータを作ることができません。この問題を解決するためにはオープンソースで公開されている「Photoshopデータを書くプログラム部品」を呼び出すことになります。

Photoshopデータについては一定の需要があるためか、AdobeがPhotoshopデータ形式の詳細な資料を公開しているためか、Reader(読むプログラム)とWriter(書くプログラム)の2通りのプログラムが存在します。

■PSD Reader/Parser
PSD-Font-Reader
psdparse

■PSD Writer
FMPSD
PSDWriter
SFPSDWriter

ここでは、「SFPSDWriter」内に含まれる「SFPSDWriter」Frameworkを呼び出しています。

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

実行にあたっては、macOS 10.14以降ではScript Debuggerを用いるか、お使いのMacをSIP解除してScript Editor上で呼び出して実行する必要があります。

ちょっと書き換えるとXcode上でも呼び出せることでしょう。Mac App Storeに出すAppleScript Cocoaアプリケーション(Sandbox対応)内で利用する場合には、ファイル書き込みパスをユーザーに明示的に選択させる必要があるため、choose file nameダイアログでファイル名を入力・選択してもらうようにすべきです(デフォルト指定のファイル名をUUIDで自動生成するとか)。

本AppleScriptはKamenokoから書き出せるデータを増やすべく「Photoshop形式のデータを書けたらどうだろう?」と実験してみた残骸です。結局、PDFで書き出せるしPDFなら拡大縮小しても荒くなったりしないので、PDFのほうがいいという結論に。

Pixelmator Proのデータ形式とかPSD形式で書き出す実験は行っているのですが、処理結果を見るとどちらも「PDF形式のほうがいい」という結論に至っています。


▲ベクターデータではないので、拡大するとアラが見える

AppleScript名:SFPSDWriterのじっけん v2
— Created 2016-03-12 by Takaaki Naganoya
— Modified 2019-02-27 by Takaaki Naganoya
— Modified 2020–09-21 by Takaaki Naganoya
— 2020 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "SFPSDWriter" –https://github.com/shinyfrog/SFPSDWriter

property |NSURL| : a reference to current application’s |NSURL|
property NSString : a reference to current application’s NSString
property NSUUID : a reference to current application’s NSUUID
property NSImage : a reference to current application’s NSImage
property SFPSDWriter : a reference to current application’s SFPSDWriter
property NSWorkspace : a reference to current application’s NSWorkspace

property SFPSDResolutionUnitPPI : 1
property SFPSDResolutionUnitPPC : 2

set anWriter to (SFPSDWriter’s alloc()’s initWithDocumentSize:(current application’s CGSizeMake(1200, 400)) andResolution:72.0 andResolutionUnit:(SFPSDResolutionUnitPPI))

set aCount to 1

repeat with yPos from 0 to 400 by 110
  repeat with xPos from 0 to 1024 by 110
    set aImage to (current application’s NSImage’s alloc()’s initWithSize:{100, 100})
    
set aColor to current application’s NSColor’s redColor()
    
my drawCircleOnNSIMage(aImage, 100, 0, 0, aColor)
    
    (
anWriter’s addLayerWithNSImage:aImage andName:("Layer_" & aCount as string) andOpacity:1.0 andOffset:{x:(xPos as real), y:(yPos as real)})
    
set aCount to aCount + 1
  end repeat
end repeat

set aPSD to anWriter’s createPSDData()

set theName to NSUUID’s UUID()’s UUIDString()
set pathString to NSString’s stringWithString:("~/Desktop/output_" & theName & ".psd")
set newPath to pathString’s stringByExpandingTildeInPath()

aPSD’s writeToFile:newPath atomically:true

#  MARK: Call By Reference
on drawCircleOnNSIMage(aImage, aRadius, aXpos, aYpos, aColor)
  set aBezier to generateCircle(aRadius, aXpos, aYpos) of me
  (
aImage)’s lockFocus()
  
aColor’s |set|()
  
aBezier’s fill() –ぬりつぶし
  (
aImage)’s unlockFocus()
end drawCircleOnNSIMage

#  MARK: circleのBezier曲線を作成して返す
on generateCircle(theRadius, x, y)
  set aRect to current application’s NSMakeRect(x, y, theRadius, theRadius)
  
set aCirCle to current application’s NSBezierPath’s bezierPath()
  
aCirCle’s appendBezierPathWithOvalInRect:aRect
  
return aCirCle
end generateCircle

★Click Here to Open This Script 

Posted in file Image | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy Photoshop | Leave a comment

Pixelmator Pro 1.8 AppleScriptコンテスト開催

Posted on 9月 18, 2020 by Takaaki Naganoya

Late Night Software Blogの告知がTwitterに流れてきていました。Pixelmator Pro v1.8にてAppleScriptに対応したことを祝して、Late Night Software主催でPixelmator ProのAppleScriptプログラミングコンテストが開催されるとのこと。

Pixelmator Proはいわば「IllustratorとPhotoshopを足して2で割った」ようなアプリケーション。Photoshopの代用になる廉価なアプリケーション、という路線です(旧Macromedia FireWorksに近いかも)。基本的にはラスター画像の処理ソフトで、ビットマップイメージを作成するものです。ベクター図形や文字などもキャンバス上に配置できますが、最終的には画像化されます。ラスター画像に対して非破壊で各種フィルタ処理が行えることが売りです。Web画像素材やアプリケーションのアイコン画像作成といった用途、写真のレタッチなどに使われているようです。登場直後にAppleScript対応リクエストを出していたものの、今回10年越しぐらいで実現して腰を抜かしました。

さて、コンテストに話を戻します。Pixelmator Pro v1.8の試用版を使うことで、同アプリケーションのScriptを書いて試せるとのこと(やっています)。辞書内容は事前に確認していましたが、ツッコミどころがあまりないぐらい、さまざまな機能が載っていました。「え、こんな機能まで乗せてるの?」という謎の充実度を見せており(Pixelmator Pro本体に搭載されていないQRコードの検出機能とか)、AS機能の開発に元AppleのSal Soghoianが協力したという話もうなづけます。

以下、コンテストのレギュレーションです。

*締め切り日:2020年10月8日 00:00(PST、日本標準時より1時間早い。別名「Shane Stanley時間」)
*Late Night Softwareのフォーラムで「いいね」が押された数で競う(あ、これ女性と子供が有利なやつだ ^ー^;)
*賞品はPixelmator ProのMac App Storeクーポンコード。優勝者は複数(Winnersと書いてある)だが、どうも人数は決めていない様子。
→ 入賞枠は3とのこと(補足)
*コンテスト応募は、LateNight Softwareのフォーラムに「pixelmatorpro」と「contest」のタグをつけて投稿すること
*AppleScriptの行数は100行まで(えーー)。コメントと空き行は除く。継続記号(┐)で続けた行も区切ってカウントされる。1行が200文字を超えてはいけない
*全Script行数の25%以上、Pixelmator Proの機能を呼び出さなくてはならない
*ScriptはmacOS 10.15, Catalina上で動作しなくてはならない
*ScriptはすべてAppleScriptでなくてはならない(JXAやshell scriptその他はダメ)。ASOCはOK
*外部Script Librariesの使用禁止(BridgePlusが使えない。これは痛い)
*Scriptはサードパーティのソフトウェア使用禁止。macOS Catalinaの標準搭載アプリケーション(ただし、Keynote、Pages、Numbersは使用OK)および(当然)Pixelmator Proのコントロールはしてよいものとする
*Scriptは製作者提供の外部データを1つに限り読み込んでよいものとする
*インターネット上のデータの読み込みはOK
*ScriptのInfo欄にスクリーンショットを入れてもいいよ
*楽しんでくれ。嫌がらせや破壊行為はNG
*ルールの明示化のためにルール自体の補足・説明を(主催者が)随時行えるものとする
*Script Debugger上で動作すること

……巨大Scriptで一部のScripterがコンテストを蹂躙することを避けつつ、「このあたり、穴場だよね?」という箇所を埋めてあります。あっと驚く参加者(たぶん、最年少参加者)が優勝をもぎ取って、真の実力者(Edama2さんみたいな)が投稿したScriptが全力でスルーされつつPixelmator Pro Scriptingの肥やしになりそうな、よく考えられたレギュレーションです(コンテストってそういうもんなんで)。

そして、一部のScripterが巨大な外部ライブラリを使ってコンテストを荒らすことを防ぐ、いいレギュレーションだと思います(Piyomaru Software対策)。

macOS標準装備のScript Editorと、LateNight Softwareが提供しているScript Debuggerの間で、(主にCocoa Scriptingで)若干の挙動の違いがありますが、レギュレーションではScript Debugger上で動作することを明記しています。まー、こんな100行程度のScriptでCocoa Scripting使ってもたいした処理が書けないんで、Cocoaの使いこなしで発生する実力差を相殺したいんだと思います。

自分が参加するとしたら、優勝狙いではなく「AppleScriptでこんなことできないでしょ」という連中を一発で黙らせるような破壊力のあるものを投稿して、それでも優勝しないという内容でしょう。ただ、100行以内だと「秘密兵器」を仕込むほどの分量がありませんね。

「1つの外部ファイルを読み込んでよい」というあたりが狙い所でしょうか。ここで勝負が決まると思います。ベトナムとかマレーシアの女子中学生あたりが優勝しそうだと予想。

Pixelmator ProのAppleScript用語辞書にはサンプルコードが多数掲載されており、それらを試してみるだけでもかなりのことがわかってきます。ただ、サンプルは行数を減らして見せるよう書かれているため、表記ゆらぎが大きく、オブジェクト階層を素直にtell文で順序立てて書くようなScriptに書き直さないと「部品」としては使いにくい印象も受けました。

実際に、Pixelmator ProのScriptingを行って、Kamenokoのネイティブデータにアクセスしてデータ書き出しを行ってみましたが、これだけでも数百行のコード規模になっているので、100行だけだと実に過酷だと感じましたわー。

Posted in news | Tagged 10.15savvy Pixelmator Pro | Leave a comment

Safari 14が配布開始に

Posted on 9月 17, 2020 by Takaaki Naganoya

WebP、WebM、VP9などのデータフォーマットに対応したSafari v14がmacOS 10.14.x、10.15,x向けに配信されました。macOS標準のソフトウェアアップデート経由でアップデートできます。

AppleScript用語辞書(sdef)を前バージョンの13.1.3と比較してみたところ、とくに差異はみあたりません。

Posted in Release | Tagged 10.14savvy 10.15savvy 11.0savvy Safari | Leave a comment

Mac App Storeで「White Pages」を販売開始

Posted on 9月 12, 2020 by Takaaki Naganoya

例によってAppleScriptで開発したアプリケーション「White Pages」のMac App Storeでの販売を開始しました。macOS 10.13以降に対応しています。

PDFの空白ページを削除・出力するアプリケーションです。空白ページの検出のため、全ページを画像にレンダリングして、空白判定。空白判定には速度と精度で定評のある空白画像検出ルーチンを使用しています。

決して、ページごとに文字の有無を判断するだけのソフト(Fredrik Method)ではありません。それだと、グラフィックだけのページを「空白」と判定してしまいますので。

アイコンは、macOS 11.0, Big Surに合わせた形状。手の色を赤くしているのは、何らかの特定の人種を想起させるような塗り色を避けたためです。

Posted in PDF PRODUCTS | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy | Leave a comment

Mac App Storeで「Table Dripper」を販売開始

Posted on 9月 11, 2020 by Takaaki Naganoya

例によってAppleScriptで開発したアプリケーション「Table Dripper」のMac App Storeでの販売を開始しました。macOS 10.14以降に対応しています(動作原理的にmacOS 10.13対応は無理だった、、、)。

Safari/Google Chrome/Microsoft Edgeで表示中のWebサイトのTableデータをCSVに変換してダウンロードしてNumbers.appでオープンするアプリケーションです。

Mac App Storeの審査に10日かかって焦りました(機能のコンパクトさに反比例して審査期間が長い。たぶん、開発期間よりも審査期間の方が長い)。

すでに、他のChromiumベースのWebブラウザ「Brave」と「Vivaldi」への対応が済んでおり、次のアップデートでこれらにも対応します。AppleScript用語辞書(sdef)を持っているWebブラウザであっても、do javascript的なコマンドが実装されていないと、本アプリケーションでは対応できません(FireFox、Opera)。まして、AppleScriptにまったく対応していないWebブラウザでは、対応のしようがありません(Sleipnirなど)。

4つのアプリケーションをコントロールするアプリケーションをMac App Storeに申請したのははじめてです。

そろそろ、Script EditorとScript DebuggerをコントロールするアプリケーションをMac App Storeに申請することに。これも、審査が荒れる(期間が長くなる)ことが見込まれます。

Posted in PRODUCTS | Tagged 10.14savvy 10.15savvy 11.0savvy Google Chrome Microsoft Edge Safari | Leave a comment

現在のスライドと次のスライドでオーバーラップしている画像とグループを検出して位置をそろえる

Posted on 9月 10, 2020 by Takaaki Naganoya

Keynoteの最前面の書類で、現在表示中のスライドと次のスライドの間で、矩形座標が重なっている「画像」と「グループアイテム」(複数のオブジェクトをグループ化したアイテム)を検出して、現在のスライドの開始位置に場所をそろえるAppleScriptです。

# 最初掲載したもの(v1)は、動作しているものの処理内容に誤りがあったので修正しました(v2)

連続したスライド上に画面図を配置して、その画面図の位置をそろえるためのものです。何回か書いたような気がします。見た目より書くのが大変ではないので、ついつい書いてしまう処理です。

単にそれぞれの対象候補のオブジェクトの矩形開始座標と幅&高さをリスト化して、それをNSRectに変換して重ね合わせが発生していないかをCocoaの機能で判定しているだけです。この、一番めんどくさい部分をCocoaに丸投げしているので、おおよそ知性というものを感じさせないレベルのScriptです。

画像やグループアイテム 以外の表オブジェクト同士の重なりあいの検出を行うものに書き換えるのは簡単ですが、複数のオブジェクトの重なり合いが発生している場合には対処できません。

AppleScript名:現在のスライドと次のスライドでオーバーラップしている画像とグループを検出して位置をそろえる v2.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/09/10
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

tell application "Keynote"
  set dCount to count every document
  
if dCount = 0 then return –ドキュメントがオープンしていないと処理終了
  
  
tell front document
    set allNum to count every slide
    
if allNum < 2 then return –slideの枚数が少なかった場合に処理終了
    
    
set curSlide to current slide
    
if allNum = curSlide then return –current slideが末尾だった場合処理終了
    
    
set sNum to slide number of curSlide
    
set nextSlide to slide (sNum + 1)
    
    
–最初のページ(スライド)からオブジェクトを収集
    
tell current slide
      set curObj1 to every image
      
set curObj2 to every group
      
set curObjList to curObj1 & curObj2
      
if curObjList = {} then return
    end tell
    
    
–次のページ(スライド)からオブジェクトを収集
    
tell nextSlide
      set nextObj1 to every image
      
set nextObj2 to every group
      
set nextObjList to nextObj1 & nextObj2
      
if nextObjList = {} then return
    end tell
    
    
set nexObjRes to calcOverlappedObj(curObjList, nextObjList) of me
    
repeat with i in nexObjRes
      copy i to {origID, targID}
      
set aOrigObj to contents of item origID of curObjList
      
set aTargObj to contents of item origID of nextObjList
      
set origPos to position of aOrigObj
      
set position of aTargObj to origPos
    end repeat
    
    
set current slide to slide sNum
  end tell
end tell

–与えられた2つのリストに入っているKeynoteオブジェクトの矩形座標が重なっているものをIDペアで出力する
–同時に複数のオブジェクトが重なっていないことが前提
on calcOverlappedObj(objList1, objList2)
  tell application "Keynote"
    –最初のページのオブジェクトからオブジェクトIDとNSRectからなるリストを作成
    
set objRecList1 to {}
    
set aCount to 1
    
repeat with i in objList1
      if contents of i is not equal to {} then
        set {x1, y1} to position of i
        
set aRect to {origin:{x:x1, y:y1}, |size|:{|width|:(width of i), |height|:(height of i)}}
        
        
set the end of objRecList1 to {objID:aCount, rect:aRect}
      end if
      
set aCount to aCount + 1
    end repeat
    
    
–次のページのオブジェクトからオブジェクトIDとNSRectからなるリストを作成
    
set objRecList2 to {}
    
set aCount to 1
    
repeat with i in objList2
      if contents of i is not equal to {} then
        set {x1, y1} to position of i
        
set aRect to {origin:{x:x1, y:y1}, |size|:{|width|:(width of i), |height|:(height of i)}}
        
        
set the end of objRecList2 to {objID:aCount, rect:aRect}
      end if
      
set aCount to aCount + 1
    end repeat
    
    
–最初のページのオブジェクトと次のページのオブジェクトで矩形エリアが重なっているオブジェクトを抽出してそれぞれのIDをペアにしたリストを作成
    
set matchList to {}
    
repeat with i in objRecList1
      
      
set origRect to rect of i
      
set origID to objID of i
      
      
repeat with ii in objRecList2
        
        
set targRect to rect of ii
        
set targID to objID of ii
        
set tRes to detectRectanglesCollision(origRect, targRect) of me
        
        
if tRes = true then
          set the end of matchList to {origID, targID}
        end if
      end repeat
      
    end repeat
    
    
return matchList
  end tell
end calcOverlappedObj

–NSRect同士の衝突判定
on detectRectanglesCollision(aRect, bRect)
  set a1Res to (current application’s NSIntersectionRect(aRect, bRect)) as {record, list}
  
set tmpClass to class of a1Res
  
  
if tmpClass = record then
    –macOS 10.10, 10.11, 10.12
    
return not (a1Res = {origin:{x:0.0, y:0.0}, |size|:{width:0.0, height:0.0}})
  else if tmpClass = list then
    –macOS 10.13 or later
    
return not (a1Res = {{0.0, 0.0}, {0.0, 0.0}})
  end if
end detectRectanglesCollision

★Click Here to Open This Script 

Posted in list Record | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy Keynote | Leave a comment

指定Finderウィンドウがどのディスプレイ上に表示されているかをIDで返す(0はじまり)

Posted on 9月 7, 2020 by Takaaki Naganoya

指定座標がどのディスプレイ上に表示されているかをIDで返すAppleScriptです。

試しに、Finderの最前面のウィンドウの始点座標を取得して、どのディスプレイ上に表示されているかを地道にループで計算しています。

0はメニューを配置しているメインディスプレイで、その後のIDについてはNSScreen’s screens()の出現順に割り振られています。

MacBook Pro 10,1にディスプレイ3枚接続して(通常状態)、さらにUSB経由でiPadをDuet Displayで外部ディスプレイ化。4枚のディスプレイで動作確認しています。

本来、どのディスプレイ上にあるかをきっちり判定できるはずなのですが、最後のIDのものだけうまく判定できていないので例外処理しています。

このあたりの動作内容が怪しかったので、ながらく放置状態になっていましたが、実際にディスプレイを4枚つないで動作確認してみたら大丈夫そうだったので掲載することに。

AppleScript名:指定Finderウィンドウがどのディスプレイ上に表示されているかをIDで返す(0はじまり).scptd
— Created 2015-11-01 by Takaaki Naganoya
— 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

tell application "Finder"
  if (count every window) = 0 then return
  
tell front window
    set {xPos, yPos} to position
    
log {xPos, yPos}
  end tell
end tell

set dispID to getPointInWhichScreen(xPos, yPos) of me

–指定座標がどのディスプレイ上に表示されているかをIDで返す(0はじまり。0はメインディスプレイ)
on getPointInWhichScreen(xPos, yPos)
  set dList to getScreensResol() of me
  
  
set aPoint to current application’s NSMakePoint(xPos, yPos)
  
set dCount to 0
  
repeat with i in dList
    set dRes to current application’s NSPointInRect(aPoint, i) as boolean
    
    
if dRes = true then
      return dCount
    end if
    
set dCount to dCount + 1
  end repeat
  
  
return dCount – 1 –ちょっと怪しいが、動作している様子
end getPointInWhichScreen

on getScreensResol()
  set dispList to (current application’s NSScreen’s screens()) as list
  
set dList to {}
  
repeat with i in dispList
    set framePref to i’s visibleFrame()
    
set {xPos, yPos} to first item of framePref
    
set theInfo to (i’s deviceDescription()’s NSDeviceSize) as record
    
set a1Rect to {origin:{x:xPos, y:yPos}, |size|:theInfo}
    
set the end of dList to a1Rect
  end repeat
  
return dList
end getScreensResol

★Click Here to Open This Script 

Posted in System | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSScreen | Leave a comment

PDFにパスワードが設定されている場合には、そのパーミッション情報を取得する

Posted on 8月 31, 2020 by Takaaki Naganoya

指定のPDFをチェックし、オープンするのにパスワードが設定されているとか、コピーが禁止されていないかといったパーミッションを調査するAppleScriptです。

API Lebel in this script Desc
(no api) openPermission document allows opening
allowsCopying copyPermission document allows copying of content to the Pasteboard
allowsPrinting printPermission document allows printing
allowsCommenting commentPermission document allows to create or modify document annotations, including form field entries
allowsContentAccessibility contentAccessPermission document allows to extract content from the document
allowsDocumentAssembly assemblyPermission document allows manage a document by inserting, deleting, and rotating pages
allowsDocumentChanges docchangePermission document allows modify the document contents except for document attributes
allowsFormFieldEntry formPermission document allows modify form field entries even if you can’t edit document annotations

PDFのオープン自体にパスワードロックがかかっている状態を検出するAPIがとくになかったので、いろいろ試行錯誤してOpenをロックしてある状態を検出してみました。

検出は、パスワード未指定でUnlockを試みるというもので、実際にパスワードを設定したPDFを相手に試行錯誤して求めてみました。

このUnlock操作に対してfalseが返ってくることでPDFオープンに対してパスワードが設定されているものと判断しています。

AppleScript名:PDFにパスワードが設定されている場合には、そのパーミッション情報を取得する
— Created 2015-11-02 13:48:32 +0900 by Takaaki Naganoya
— 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "QuartzCore"

set aPath to (choose file of type {"com.adobe.pdf"} with prompt "Select PDF to check")

set aRes to my retProtectedPDFPermissions(aPath)
–>  missing value (パスワードは設定されていない)

–> {openPermission:false, copyPermission:true, printPermission:true, commentPermission:true, contentAccessPermission:true, assemblyPermission:true, docchangePermission:true, formPermission:true}–オープンするためにはパスワードが必要(openPermission)

–指定のPDFにパスワードが設定されているかどうかをチェック
on retProtectedPDFPermissions(aPath)
  set aURL to current application’s |NSURL|’s fileURLWithPath:(POSIX path of aPath)
  
set aPDFdoc to current application’s PDFDocument’s alloc()’s initWithURL:aURL
  
set anEncF to aPDFdoc’s isEncrypted()
  
if anEncF = false then return missing value
  
  
set passLocked to aPDFdoc’s unlockWithPassword:""
  
  
set cpPerm to aPDFdoc’s allowsCopying() as boolean
  
set prPerm to aPDFdoc’s allowsPrinting() as boolean
  
set cmPerm to aPDFdoc’s allowsCommenting() as boolean
  
set caPerm to aPDFdoc’s allowsContentAccessibility() as boolean
  
set daPerm to aPDFdoc’s allowsDocumentAssembly() as boolean
  
set dcPerm to aPDFdoc’s allowsDocumentChanges() as boolean
  
set ffPerm to aPDFdoc’s allowsFormFieldEntry() as boolean
  
  
return {openPermission:passLocked, copyPermission:cpPerm, printPermission:prPerm, commentPermission:cmPerm, contentAccessPermission:caPerm, assemblyPermission:daPerm, docchangePermission:dcPerm, formPermission:ffPerm}
end retProtectedPDFPermissions

★Click Here to Open This Script 

Posted in file PDF | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSURL PDFDocument | Leave a comment

Mac App Storeで新アプリケーション「RBC」(Rename by contents)を販売開始

Posted on 8月 25, 2020 by Takaaki Naganoya

Mac App Storeに新アプリケーション「Rename by contents」を提出しました。Now On Saleです。

論文PDFのリネーム用ツールであり、「PDFの1ページ目の一番大きな文字の文をファイル名として採用する」というものです。macOS 10.13以降用で、Intel 64バイナリでビルドしてあります。全部AppleScriptで書いてあるので、ARM 64e向けにビルドし直すのもとくに問題ありません。

–> Watch Demo Movie

このアプリケーションほか、小物アプリケーションをMac App Storeに提出する方向で作業をすすめていますが、今回の審査は一番手間取りました。割と日常的に使っている小物アプリケーションは、小物アプリケーションらしくいろいろUIの味付けを変えているのですが、そういうアレンジしている部分を「HIG(Human Interface Guideline)に反する」という理由でリジェクトされました。

たとえば、こうした小物アプリケーションの場合に、メインウィンドウを閉じられたくない(処理がめんどくさいから)という事情があり、メインウィンドウのクローズボタンを無効にしていることがよくあります。

ウィンドウさえクローズされなければ問題は発生しないので、クローズ機能自体にフタをしてしまえばよいという話です。ただ、HIGの原則からいえば「クローズボタンがないのはダメ」なので、Mac App Store版のアプリケーションではこの「クローズボタンの無効化」は禁じ手ということになります。

クローズボタンを有効化して、メインウィンドウが閉じられたらアプリケーションを自動終了させる処理をコピペで書き足して、最終的にリジェクトを回避できました。

ちなみに、これとほぼ同時に作りはじめた別のアプリケーション「Foreign Love」(指定アプリケーションを他の言語環境で起動)は、現行のSandboxの仕様上、Sandbox環境では機能を発揮できないことが判明してオクラ入りしました。

ほかにもこまごまとしたリジェクト理由でAppleのレビュー担当(名前は知らない。毎回違うはず)とやりとりしていましたが、正直なところ小さいアプリケーションをMac App Storeに通すほうが大変な気がしました。ただ、この手の申請作業に慣れてきたような気がします。

あと、XcodeのOSACompile ビルドオプション、「Save as Execute-only」でデフォルトだとビルド時に「ソースを開示したままビルド」になっているので、AppleScriptのコードを全表示させたビルドをさせようとするのに何回も煮え湯を飲まされました。とても怖いdeath。

Posted in PRODUCTS | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy | Leave a comment

Post navigation

  • Older posts
  • Newer posts

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

Google Search

Popular posts

  • 開発機としてM2 Mac miniが来たのでガチレビュー
  • macOS 15, Sequoia
  • Pages本執筆中に、2つの書類モード切り替えに気がついた
  • Numbersで選択範囲のセルの前後の空白を削除
  • メキシカンハットの描画
  • Pixelmator Pro v3.6.4でAppleScriptからの操作時の挙動に違和感が
  • AppleScriptによる並列処理
  • Safariで「プロファイル」機能を使うとAppleScriptの処理に影響
  • macOS 15でも変化したText to Speech環境
  • AppleScript入門③AppleScriptを使った「自動化」とは?
  • デフォルトインストールされたフォント名を取得するAppleScript
  • macOS 15 リモートApple Eventsにバグ?
  • 【続報】macOS 15.5で特定ファイル名パターンのfileをaliasにcastすると100%クラッシュするバグ
  • AppleScript入門① AppleScriptってなんだろう?
  • macOS 14で変更になったOSバージョン取得APIの返り値
  • Script Debuggerの開発と販売が2025年に終了
  • NSObjectのクラス名を取得 v2.1
  • macOS 15:スクリプトエディタのAppleScript用語辞書を確認できない
  • 有害ではなくなっていたSpaces
  • AVSpeechSynthesizerで読み上げテスト

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 (135) CotEditor (66) Finder (51) iTunes (19) Keynote (119) NSAlert (61) NSArray (51) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (53) NSDictionary (28) NSFileManager (23) NSFont (21) NSImage (41) NSJSONSerialization (21) NSMutableArray (63) NSMutableDictionary (22) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (119) NSURL (98) NSURLRequest (23) NSUTF8StringEncoding (30) NSView (33) NSWorkspace (20) Numbers (76) Pages (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
  • process
  • PRODUCTS
  • QR Code
  • Raw AppleEvent Code
  • Record
  • rectangle
  • recursive call
  • regexp
  • Release
  • Remote Control
  • Require Control-Command-R to run
  • REST API
  • Review
  • RTF
  • Sandbox
  • Screen Saver
  • Script Libraries
  • 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年6月
  • 2025年5月
  • 2025年4月
  • 2025年3月
  • 2025年2月
  • 2025年1月
  • 2024年12月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年6月
  • 2024年5月
  • 2024年4月
  • 2024年3月
  • 2024年2月
  • 2024年1月
  • 2023年12月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年6月
  • 2023年5月
  • 2023年4月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年12月
  • 2019年11月
  • 2019年10月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年5月
  • 2018年4月
  • 2018年3月
  • 2018年2月

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

メタ情報

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

Forum Posts

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

メタ情報

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