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

map scripter script Library

Posted on 12月 14, 2019 by Takaaki Naganoya

macOS添付の地図.app(Maps.app)をAppleScript的な用語で操作するAppleScriptライブラリ「map scripter」の配布を開始しました。macOS 10.10以降(作成+動作確認は10.14)で、動作するはずです。

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

Maps.appのコントロールは非同期のURL Eventsで行われるため、本ライブラリを通じてMaps.appを操作しても、macOSの「セキュリティ」ダイアログは表示されません。そのかわり、100%操作できるという保証もありません(時間帯によって処理要求が返ってこなかったりします。とくに、グルメ系検索)。また、Maps.appの実行のためにインターネット接続が必須です。

Maps.appは外部からURL Eventのみでコントロール可能なアプリケーションです。操作の方法がエキセントリックすぎるので、一般的なAppleScript対応アプリケーションと同様の英語的な用語でアクセスできるようにしてみました。例によって、実行結果イメージやサンプルScriptをsdefの中に入れてあります。

macOS 10.15.2上で動作させたときに、「display around here」コマンドが、

のようなエラーを表示することがあります。これは、どうも位置情報サービスに要求を出したのに拒否されたという種類のOS側のエラーのようで、システム環境設定の「セキュリティとプライバシー」>「プライバシー」>「位置情報サービス」のあたりで認証が行われなくてはならないはずのもの(認証済み)が、エラーを起こしているようで、、、、macOS側のバグと言っていい挙動だと思います。

Maps.app以外でも、AppleScript系の機能実装がおかしいApple純正のアプリケーションに対し、Framework経由でデータアクセスするようなライブラリがあると便利かもしれませんが、そこまでやったらフリー配布はちょっと勘弁してほしい感じがします。

AppleScript名:display map by address.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/12/14
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use mapLib : script "map scripter"

display map by address "東京都港区六本木6丁目10番1号" map type normal zoom level 25

★Click Here to Open This Script 

AppleScript名:display map route.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/12/14
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use mapLib : script "map scripter"

display map route from "豊島園" to "目黒" using public

★Click Here to Open This Script 

AppleScript名:display point.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/12/14
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use mapLib : script "map scripter"

display point query "レストラン" latitude 31.5719562 longitude 130.56257084

★Click Here to Open This Script 

AppleScript name:display around here.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/12/14
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use mapLib : script "map scripter"

display around here query "ラーメン"

★Click Here to Open This Script 

com.apple.Maps

Posted in geolocation | Tagged 10.12savvy 10.13savvy 10.14savvy 10.15savvy Maps | Leave a comment

ダークモードの検出 v4

Posted on 12月 13, 2019 by Takaaki Naganoya

現在のアピアランスがDark ModeかLight Modeかを検出するAppleScriptです。macOS 10.14以降用です。

System Eventsに問い合わせれば簡単に確認できますが、アプレット内/Cocoa Application内でSystem Eventsを呼び出すとセキュリティダイアログが表示されてしまうので、このぐらいで表示されてしまうのは癪なので、Cocoaの機能を利用して検出してみました。

AppleScript名:ダークモードの検出 v4
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/12/13
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.7" — Mojave (10.14) or later
use framework "Foundation"
use scripting additions

set apRes to retLightOrDark() of me

on retLightOrDark()
  set curAppearance to ((current application’s NSAppearance)’s currentAppearance()’s |name|()) as string
  
set aDark to (current application’s NSAppearanceNameDarkAqua) as string
  
  
if curAppearance = aDark then
    return true
  else
    return false
  end if
end retLightOrDark

★Click Here to Open This Script 

System Eventsを使うとこんな感じになりますが、、、

AppleScript名:ダークモードの検出 v3
set apRes to retLightOrDark() of me

on retLightOrDark()
  tell application "System Events"
    tell appearance preferences
      return dark mode –returns true in dark mode
    end tell
  end tell
end retLightOrDark

★Click Here to Open This Script 

Posted in System | Tagged 10.14savvy 10.15savvy | 2 Comments

Continuity Camera AS

Posted on 12月 12, 2019 by Takaaki Naganoya

Xcode上でCocoa AppleScriptアプリケーションを作成し、macOS 10.14から搭載された「Continuity Camera」の機能を利用して、iOSデバイス上で撮影した写真をその場でMacに転送・保存してみました。

–> ContinityCameraAS(Xcode 11 Project)

Continuity Cameraをサポートする部分のObjective-CのコードはThomas Zoechling氏のBlog上のものを利用させていただいております。

本当は通常のスクリプトでdisplay dialog的なダイアログを表示して、その上に作成したNSImageViewでContinuity Cameraを呼び出せるとよかったのですが、なかなかそこまで噛み砕いて解釈できなかったので、Xcode上のアプリそのままです。

Continuity CameraのプロジェクトをXcode上でビルド&実行すると、なにもないっぽいWindowが表示されますが、下地にNSImageViewを敷いてあるような気がします。このウィンドウの真ん中の方でControl-クリックあるいはマウスの右ボタンをクリックすると、コンテクストメニューが表示され、そこでカメラから画像取り込みを行うデバイスを選択し、それらの周辺デバイスで撮影した写真をそのまま取り込めます。

Continuity Camera機能は、同じiCloud IDで関連づけたiOSデバイスのカメラを無線LANのネットワークごしにMacから利用するものと理解しています(Bluetoothもオンにする必要があるかもしれない)。

ウィンドウ上の「Save Image」ボタンをクリックすると、その内容をデスクトップにPNG画像で保存します。

AppleScriptアプリケーションでもContinuity Cameraを利用できることがわかったので、このプログラムにAppleScript用語辞書(sdef)をつけてScriptableなアプリケーションに仕立て上げれば、通常のAppleScriptからcapture cameraといったコマンドで取り込めてよいのではないでしょうか。

コンテクストメニューの先にある機能に直接アクセスするためには、もう少し調べる必要がありそうではあります。

AppleScript名:AppDelegate.applescript
—
— AppDelegate.applescript
— continityCameraAS
—
— Created by Takaaki Naganoya on 2019/10/21.
— Copyright © 2019 Takaaki Naganoya. All rights reserved.
—

script AppDelegate
  property parent : class "NSObject"
  
  
— IBOutlets
  
property theWindow : missing value
  
property theImageV : missing value
  
  
on applicationWillFinishLaunching:aNotification
    — Insert code here to initialize your application before any files are opened
  end applicationWillFinishLaunching:
  
  
  
on applicationShouldTerminate:sender
    — Insert code here to do any housekeeping before your application quits
    
return current application’s NSTerminateNow
  end applicationShouldTerminate:
  
  
  
on clicked:aSender
    set imgRes to theImageV’s image()
    
set dtPath to POSIX path of (path to desktop)
    
log {"dtPath", dtPath}
    
set fRes to retUUIDfilePath(dtPath, "png") of me
    
log {"fRes", fRes}
    
set sRes to saveNSImageAtPathAsPNG(imgRes, fRes) of me
  end clicked:
  
  
  
–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 retUUIDfilePath(aPath, aEXT)
    set aUUIDstr to (current application’s NSUUID’s UUID()’s UUIDString()) as string
    
set aPath to ((current application’s NSString’s stringWithString:aPath)’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:aEXT
    
return aPath
  end retUUIDfilePath
  
end script

★Click Here to Open This Script 

Posted in AppleScript Application on Xcode Image | Tagged 10.14savvy 10.15savvy | Leave a comment

マウスカーソルの現在座標を取得する

Posted on 12月 12, 2019 by Takaaki Naganoya

マウスカーソルの現在座標を取得するAppleScriptです。

各種アプリケーションで座標系が微妙に(左上が原点だったり、左下が原点だったり)違いますが、Cocoaの座標系は左下が原点です。

# macOS 12からは左上が原点になるのだそうで

ただ、取得したところで何に使うかというあたりに疑問があります。そんなに使った記憶がありません。スクリプトエディタ上で本Scriptを実行した場合には、実行ボタンを押したときのマウスカーソルの座標が返ってきますし、Script Menuから実行した場合には、実行時のメニュー選択のマウスカーソルの座標が返ってくるだけです。

ちょっとひとひねりして、タイマー割り込みで定期的に取得したところで、何か意味のあるデータが取れるわけでもありません(ジェスチャー検出まで昇華できる気がまったくしない)。

逆に、マウスカーソルの座標の取得でどれだけ「いいこと」があるか教えてほしいもんです。

2021/5/22追記:
ついに、本処理が役立つ用途が見つかりました。「マウスカーソルが存在するディスプレイの内容だけスクリーンキャプチャを撮る」というものです。

ふつう、マルチディスプレイ環境でShift-Command-3のキーボードショートカットによるスクリーンキャプチャ撮影を行うと、それぞれのディスプレイごとに独立した画像ファイルが生成されます。

これが望ましい場合もあれば、そうでない場合もあるので……現在マウスカーソルが存在するディスプレイIDをマウスカーソルの座標値から計算し、マウスカーソルが存在するディスプレイのスクリーンショットのみ撮影するAppleScriptを書いて実行できました。Stream Deckのアクションから呼び出して、ワンボタンで実行できています。

このアクションはなかなか使い勝手がいいですし、本Scriptを書いておかなかったら気楽に実現することはできませんでした。

AppleScript名:マウスカーソルの現在座標を取得する
— Created 2018-02-03 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

set mLoc to current application’s NSEvent’s mouseLocation()
–> {x:114.1171875, y:1142.87109375}

★Click Here to Open This Script 

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

macOS 10.15.2でPDFViewでオープン中のPDFで発生したURLリンクバグが新たなバグを呼ぶ

Posted on 12月 11, 2019 by Takaaki Naganoya

macOS 10.15には、PDFViewでオープン中のPDFで、URLリンクをクリックして発生したURLイベントが正常にデコードされないというバグがあります。本日リリースされたmacOS 10.15.2アップデートでもまともに修正されていないため、その内容についての解説です。

# BugReporter経由でバグ報告ずみです。が、、、

macOS 10.15のPDFViewのバグ

macOS 10.15.0で観測されたこのバグは、URL自体がURLエンコードされたまま、デコードされずにアプリケーションに伝わるというものでした。httpなどのメジャーなURLスキームを持つURL以外のマイナーなもの、具体的にいえば「applescript://」URLスキームで失敗することを確認しています。

「applescript://」URLスキームは本Blog掲載のプログラムリストすべてに添付しているURLリンクで、プログラムリスト末尾のリンクをクリックすると内容がスクリプトエディタに転送される仕組みです。

つまり、WkWebViewなりWebViewなりの、WebView系のGUI部品から「applescript://」URLイベントが発生した場合には、macOS 10.15上でも正常に処理できています。

これが、PDFView上では正常に(従来のmacOSと同様には)動作していないというのがmacOS 10.15上のバグです。

macOS 10.15.2でバグが変質

では、macOS 10.15.2 Updateでこれが修正されたかといえば、

 ・まったくデコードされないでデータが転送される、という不具合はなくなった
 ・しかし、デコードの仕方に問題が残っている。3通りの反応が返ってくる、「頭の悪い修正」が行われた

  CASE 1:正常にデコードされて伝わる(内容はすべて伝わる)
  CASE 2:デコードされた内容が途中で途切れる
  CASE 3:何も伝わらない

CASE 1の反応が返ってくるものは毎回CASE 1の反応が返ります。同様に、CASE 2の反応が返ってくるものは毎回CASE 2。CASE 3も同様です。なにやら、URLデコードした文字列の内容に応じて「データが欠損する」という新たな不具合が発生するようです。

自助努力によるPDFViewのバグ回避は?

OSの基礎的な部分ではなく、PDFViewというバグ連発の部品で発生している状況です。Appleの社内は縦割り組織で、社員が他のチームにアクセスする権限はありません。そのため、コアOSチームとPDFViewのチーム(チーム名は具体的には知りません)が連携する可能性には期待できません。WebViewでは発生していないことから、PDFViewが単独で何かの実装を行なったときにバグを発生させたものと見ています。

macOS 10.15のPDFViewにおけるURLリンクのクリックで発生するバグを回避するために、自前で簡易PDFビューワーを作成しましたが、PDFView上でオープンしたPDF内のURLリンクをクリックした時点でデータが欠損(CASE 2、3)しているため、リンククリックから発生するイベントを横取りして何らかの処理を行なっても補えません。

Appleが従来どおりの実装を行わず、正常に動作しない不具合やバグばかり新たに作り出す理由はわかりませんが、Appleには不用意にバグを追加することはできても、「そのバグが何であるかを認識し、修正する能力がない」と考えたほうがよいでしょう。

CASE 2の「途中で途切れる」パターンについては、現在表示中のページ(currentPage=単独ページはScripting Bridgeのバグにより取得できないので、見開きページがどれかという判定に)上のすべてのURLリンクを取得し、デコードした内容をすべて取り出して前方一致検索で該当すると思われる内容をスクリプトエディタに転送することは不可能ではありません。

不可能ではないものの、途中で途切れたデータを単なる前方一致検索するだけでは同一のものが複数検出される可能性もあり、ユーザーに対して「あなたがクリックした内容は以下のうちのどれですか?」と間抜けな問い合わせを行う必要が発生してしまいます。

CASE 3についてはお手上げです。何かがクリックされたことしかわかりません。「PDF上のURLリンクのクリックを受信する」という動作には一切期待しないほうがよさそうです。

PDFView上のリンククリック挙動修正に期待できない

PDF上のURLリンクをクリックするとmacOS 10.15のバグに遭遇してしまうので、「applescript://」URLをクリックしても別の機能にフォワードしたほうがよいでしょう。

PDFViewで表示中のPDFの見開きページがどこかはわかるので、そのページ範囲にある「applescript://」URLリンクをすべて取り出し、その内容もデコードして、すべてスクリプトエディタに転送するのがよいでしょう。

最初のバグ状態よりも状況が悪化しているような気もしますが、どんなもんなんでしょう?

Posted in Bug URL | Tagged 10.15savvy PDFView | Leave a comment

choose multiple list lib

Posted on 12月 10, 2019 by Takaaki Naganoya

choose from listの複数リスト版。複数のポップアップメニューをダイアログ上で選択するUser Interfaceを提供する、「choose multiple list」AppleScriptライブラリです。macOS 10.13以降対応です。


▲選択リスト数は可変

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

AppleScript name:sample 1.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/12/10
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.7" — High Sierra (10.13) or later
use framework "Foundation"
use scripting additions
use mulList : script "choose multiple list"

set selList to {{"Red", "Blue", "Yellow", "Brown", "White", "Cyan", "Grey"}, {"Red", "Blue", "Yellow", "Brown", "White", "Cyan", "Grey"}}
set tList to {"1st Segments", "2nd Segments"}

set aRes to choose multiple list selList main message "Select Items Demo" sub message "Select each selection. Same selection items *NOT* allowed" with title lists tList height 140 width 400 return type item contents without allow same items
–> {"Red", "Yellow"}

★Click Here to Open This Script 

AppleScript name:sample 2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/12/10
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.7" — High Sierra (10.13) or later
use framework "Foundation"
use scripting additions
use mulList : script "choose multiple list"

set selList to {{"Red", "Blue", "Yellow", "Brown", "White", "Cyan", "Grey"}, {"Red", "Blue", "Yellow", "Brown", "White", "Cyan", "Grey"}}
set tList to {"1st Segments", "2nd Segments"}

set aRes to choose multiple list selList main message "Select Items Demo" sub message "Select each selection. Same selection items allowed" with title lists tList height 140 width 400 return type item numbers with allow same items
–> {1, 1}

★Click Here to Open This Script 

テキストエディタ上でオープン中のテキストのdiff表示を行う場合のファイル選択のために作成したものです。


▲もっと汎用的に差分表示用の部品として活用するために、AppleScript用語辞書の添付が切実に望まれるApple製アプリケーション第1位のFileMerge

AppleScript名:CotEditor –> FileMergeでDiff表示.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/12/10
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.7" — High Sierra (10.13) or later
use framework "Foundation"
use scripting additions
use mulList : script "choose multiple list"

tell application "CotEditor"
  set dCount to count every document
  
if dCount < 2 then
    display dialog "A few documents…" with title "Error" buttons {"OK"} default button 1
    
return
  else if dCount = 2 then
    –オープン中の書類が2つある場合
    
set aPath to file of document 1
    
set bPath to file of document 2
    
    
set aPOSIX to POSIX path of aPath
    
set bPOSIX to POSIX path of bPath
  else
    –オープン中の書類が2つ以上存在している場合
    
set dList to {}
    
set adList to file of every document
    
    
repeat with i in adList
      set the end of dList to POSIX path of i
    end repeat
    
    
set selList to {dList, dList}
    
set tList to {"Document #1", "Document #2"}
    
    
set aRes to choose multiple list selList main message "Select two files to display diff" sub message "Select each file. Same selection items NOT allowed" with title lists tList height 140 width 700 return type item contents without allow same items
    
    
copy aRes to {aPOSIX, bPOSIX}
    
  end if
end tell

tell application "FileMerge" to activate
do shell script "/usr/bin/opendiff " & quoted form of aPOSIX & " " & quoted form of bPOSIX & " &"

★Click Here to Open This Script 

Posted in dialog GUI list Script Libraries | Tagged 10.13savvy 10.14savvy 10.15savvy CotEditor FileMerge | Leave a comment

choose style lib

Posted on 12月 9, 2019 by Takaaki Naganoya

指定のRTFから書式スタイル名(フォント名、フォントサイズ)を抽出し、そのスタイルをダイアログ上にポップアップメニューで一覧表示し、指定スタイル該当箇所を抽出したプレビュー表示を行いつつ、選択スタイル関連の情報を取得できるAppleScriptライブラリです。動作環境は、macOS 10.13以降です。

–> Download chooseStyleLib(library and sample RTF. Library have to install to ~/Library/Script Libraries)

前バージョンは正常動作するランタイム環境が限定されており、スクリプトエディタ上でCommand-Control-Rで実行する必要がありましたが、このライブラリ版ではScript Debugger上でもScript Menuからでも実行できますし、AppleScript用語辞書(sdef)を書いたので、簡潔かつ手軽に呼び出せるようになりました。

また、AppleScript用語辞書には本Blogと同様の色分け記述で、「★Click Here to Open This Script」をクリックすれば内容がスクリプトエディタに転送されるURLリンク入りのSample Scriptを掲載し、さらに本Blog上の画面キャプチャをリンクしてあるため、実行時の画面イメージも把握できるようになっています。

まんべんなく、すべてのコマンドにSample Scriptを掲載しています。

前バージョンではポップアップメニューにスタイルを適用してWYSIWYGメニューを作成していました。クリックしてメニュー表示を行なっているときにはスタイルが表示されていい感じでしたが、クリックしていない時にはボタンのサイズよりも大きいサイズは欠けて表示されるので、実用性がいまひとつ。そのため、本バージョンではWYSIWYGメニューの機能は省略しました。

ポップアップしていない時にはWYSIWYG表示にならないように機能を両立できるとよかったのですが、、、、

また、前バージョン同様に、「巨大なRTFを指定された場合でも足切りをしない」ようになっているので、あまり巨大なRTFを指定しないようにしてください。

choose style fromコマンド

指定のRTFからスタイル{フォント名,フォントサイズ}を抽出し、ダイアログ上のポップアップメニューで選択したスタイル{フォント名,フォントサイズ}を返します。

AppleScript name:sample1 choose style from.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/12/08
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
–  http://piyocast.com/as/
use AppleScript version "2.7" — High Sierra (10.13) or later
use framework "Foundation"
use scripting additions
use chooseStyle : script "chooseStyle"

set aFile to choose file of type {"public.rtf"}

set bRes to choose style from aFile main message "Select Style" sub message "Select style you want to filter" width 400 height 200
–> {"HelveticaNeue-Bold", 16.0}

★Click Here to Open This Script 

choose contens by style fromコマンド

指定のRTFからスタイル{フォント名,フォントサイズ}を抽出し、ダイアログ上のポップアップメニューで選択したスタイルの該当箇所のテキストを返します。

AppleScript name:sample2 choose contens by style from.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/12/08
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
–  http://piyocast.com/as/
use AppleScript version "2.7" — High Sierra (10.13) or later
use framework "Foundation"
use scripting additions
use chooseStyle : script "chooseStyle"

set aFile to choose file of type {"public.rtf"}

set fRes to choose contens by style from aFile main message "Select Style" sub message "Select style you want to filter" width 400 height 300
–> "Built-in filters"–text returns

★Click Here to Open This Script 

filter by styleコマンド

指定のRTFファイルから指定のスタイル{フォント名,フォントサイズ}で指定した箇所のテキストを返します。本コマンドはダイアログ表示を行わず、ただRTFからテキスト抽出するだけです。

AppleScript name:sample3 filter by style.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/12/08
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
–  http://piyocast.com/as/
use AppleScript version "2.7" — High Sierra (10.13) or later
use framework "Foundation"
use scripting additions
use chooseStyle : script "chooseStyle"

set aFile to choose file of type {"public.rtf"}

set bRes to choose style from aFile main message "Select Style" sub message "Select style you want to filter" width 400 height 200
–> {"HelveticaNeue-Bold", 16.0}

copy bRes to {fName, fSize}

set aRes to filter by style aFile font name fName font size fSize
–>"Built-in filters"

★Click Here to Open This Script 

extract stylesコマンド

指定のRTFファイルからすべてのスタイル{フォント名,フォントサイズ}を抽出します。本コマンドもダイアログ表示は行いません。

AppleScript name:sample4 extract styles.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/12/08
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
–  http://piyocast.com/as/
use AppleScript version "2.7" — High Sierra (10.13) or later
use framework "Foundation"
use scripting additions
use chooseStyle : script "chooseStyle"

set aFile to choose file of type {"public.rtf"}
return extract styles aFile
–> {{"HelveticaNeue-Bold", 24.0}, {"HelveticaNeue", 16.0}, {"HelveticaNeue-Bold", 20.0}, {"HelveticaNeue-Bold", 16.0}, {"HelveticaNeue-Italic", 16.0}, {"LucidaGrande", 16.0}, {"Menlo-Regular", 13.6}}

★Click Here to Open This Script 

Posted in dialog GUI RTF Script Libraries | Tagged 10.14savvy 10.15savvy | Leave a comment

PDFフォームに入力して別名保存 v2

Posted on 12月 7, 2019 by Takaaki Naganoya

入力フォームつきのPDFにデータ入力して別名保存するAppleScriptです。

他のGUIアプリを操作してフォーム入力するのではなく、直接PDFKitの機能を利用してフォームPDFへの記入を行なっています。

テキスト入力フォーム、チェックボックス、コンボボックスへの入力に対処してみましたが、リストボックスの項目選択はまだ行えていません。


▲Adobe AcrobatでPDFフォームサンプルをオープンしたところ


▲本ScriptでサンプルフォームPDFを処理したところ


▲Script Debugger上で表示したPDFフォーム上の各種プロパティ。フォーム欄のタイプを名前ではなく各種属性値で判定したいところ

AppleScript名:PDFフォームに入力して別名保存(テキストフィールド、チェックボックス、コンボボックス)
— Created 2019-12-05 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "Quartz"

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

set aHFSPath to (choose file of type {"com.adobe.pdf"} with prompt "Choose a PDF with Form")
set aPOSIX to POSIX path of aHFSPath
set aURL to (|NSURL|’s fileURLWithPath:aPOSIX)

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

set anoList to (firstPage’s annotations()) as list
if anoList is not equal to {missing value} then –指定PDF中にAnotationが存在する場合のみ処理
  repeat with i in anoList
    set aName to (i’s fieldName()) as string
    
    
set adicList to i’s annotationKeyValues
    
set aType to (adicList’s valueForKey:"/Type") as string
    
set aSubType to (adicList’s valueForKey:"/Subtype") as string
    
set aFormType to (adicList’s valueForKey:"/FT") as string
    
    
log {aType, aSubType, aFormType}
    
if aName ends with "Text Box" then –OK
      set aState to (i’s widgetStringValue()) as string
      
      
if aState = "" then
        (i’s setWidgetStringValue:"Piyomaru")
        
set bState to (i’s widgetStringValue()) as string
      end if
      
    else if aName ends with "Check Box" then –OK
      log {"Check Box"}
      
set aState to (i’s buttonWidgetState()) as boolean
      
if aState = false then
        (i’s setButtonWidgetState:true)
        
set bState to (i’s buttonWidgetState()) as boolean
      end if
      
    else if aName ends with "Combo Box" then
      log {"Combo Box"}
      
set tmpList to (i’s choices()) as list
      (
i’s setWidgetStringValue:(contents of some item of tmpList))
      
set cVal to (i’s widgetStringValue()) as string
      
log cVal
      
    else if aName ends with "List Box" then
      log {"List Box"}
      
set tmpList to (i’s choices()) as list
      
log {"tmpList", tmpList}
      
      
–(i’s setWidgetStringValue:(contents of some item of tmpList))
      
    end if
  end repeat
end if

–PDFの保存先のファイル名を入力させる(あらかじめパス文字列を作成しておいてもよい)
set newFileName to POSIX path of (choose file name with prompt "Input File name to save")
if newFileName does not end with ".pdf" then
  set newFileName to newFileName & ".pdf"
end if

–フォーム内容を変更したPDFを指定のパスに新規保存
set pdfRes to (aPDFdoc’s writeToFile:newFileName) as boolean

★Click Here to Open This Script 

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

PDFフォームに入力して別名保存

Posted on 12月 5, 2019 by Takaaki Naganoya

入力フォームつきのPDFにデータ入力して別名保存するAppleScriptです。

PDFフォームといっても、別に入力したその場でどこかのサーバーにデータが送信されるわけでもなく、ただ紙に筆記用具で名前を書き込むがごとく、記入欄にデータが入力されたPDFが出来上がるだけです。

サンプルのフォーム入りPDFをみつくろって、チェックボックス項目だけ値を変更して、別名保存してみました。

本AppleScriptではフォームのうちチェックボックスのものの値だけ書き換えてみましたが、テキスト入力型の記入欄に文字データを突っ込むのも難しくはありません(多値ポップアップメニューからの選択がめんどくさい)。

AppleScript名:PDFフォームに入力して別名保存
— Created 2019-12-05 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "Quartz"

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

set aHFSPath to (choose file of type {"com.adobe.pdf"} with prompt "Choose a PDF with Form")
set aPOSIX to POSIX path of aHFSPath
set aURL to (|NSURL|’s fileURLWithPath:aPOSIX)

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

set anoList to (firstPage’s annotations()) as list
if anoList is not equal to {missing value} then –指定PDF中にAnotationが存在する場合のみ処理
  repeat with i in anoList
    set aName to (i’s fieldName()) as string
    
    
if aName ends with "Check Box" then
      set aState to (i’s buttonWidgetState()) as boolean
      
if aState = false then
        (i’s setButtonWidgetState:true)
        
set bState to (i’s buttonWidgetState()) as boolean
      end if
    end if
  end repeat
end if

–PDFの保存先のファイル名を入力させる(あらかじめパス文字列を作成しておいてもよい)
set newFileName to POSIX path of (choose file name with prompt "Input File name to save")
if newFileName does not end with ".pdf" then
  set newFileName to newFileName & ".pdf"
end if

–フォーム内容を変更したPDFを指定のパスに新規保存
set pdfRes to (aPDFdoc’s writeToFile:newFileName) as boolean

★Click Here to Open This Script 

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

macOS 10.15上のPhotos.app経由でインポートした写真のファイル名が大文字に強制変更される

Posted on 12月 3, 2019 by Takaaki Naganoya

macOS 10.15は毎日新たな(よくない方の)発見があって驚かされます。そんなmacOS 10.15上のPhotos.appでインポートした写真のファイル名に含まれる英小文字がすべて英大文字に変更されるというバグが報告されています。

macOS 10.14.6上のPhotos.app経由で同じ写真をインポートすると、iCloud経由でシンクロされてmacOS 10.15.1上のPhotos.appに配信されてもファイル名はオリジナルのままです。

Posted in Bug | Tagged 10.15savvy Photos | Leave a comment

iTunes Libraryの再生回数をジャンルごとに集計、ジャンル名名寄せ付き

Posted on 12月 2, 2019 by Takaaki Naganoya

iTunesLibrary.framework経由でiTunes/Music.appのライブラリのジャンルごとの再生回数を集計するAppleScriptです。

7,000曲程度入っているライブラリで、ジャンル名の名寄せも含め、開発環境(MacBook Pro Retina 2012, Core i7 2.66GHz@macOS 10.14.6)で0.7秒程度で終了します。2,500曲程度入っているMac mini 2014 Core i5 2.6GHz@macOS 10.15.1で0.6秒程度です。

macOS 10.14まで(iTunes.app)と、macOS 10.15以降(Music.app)でも同様にiTunesLibrary.framework経由でライブラリへのアクセスが行えます。

AppleScript名:iTunes Libraryの再生回数をジャンルごとに集計、ジャンル名名寄せ付き
— Created 2019-11-10 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "iTunesLibrary"
–https://developer.apple.com/reference/ituneslibrary/itlibmediaitem?language=objc

property NSArray : a reference to current application’s NSArray
property NSString : a reference to current application’s NSString
property NSScanner : a reference to current application’s NSScanner
property NSPredicate : a reference to current application’s NSPredicate
property NSDictionary : a reference to current application’s NSDictionary
property NSCountedSet : a reference to current application’s NSCountedSet
property NSMutableArray : a reference to current application’s NSMutableArray
property NSSortDescriptor : a reference to current application’s NSSortDescriptor
property NSMutableCharacterSet : a reference to current application’s NSMutableCharacterSet

–ジャンル名寄せリスト(2要素から構成される2D List)
set genreNayoseList to {{"World", "ワールド"}, {"Anime", "アニメ"}, {"Electronic", "エレクトロニック"}, {"R&B/ソウル", "R&B/ソウル"}, {"Kayokyoku", "歌謡曲"}, {"Electronic", "エレクトロニック"}, {"Vocal", "ヴォーカル"}, {"Classical", "クラシック"}, {"Dance", "ダンス"}, {"Soundtrack", "サウンドトラック"}, {"Rock", "ロック"}}

set library to current application’s ITLibrary’s libraryWithAPIVersion:"1.0" |error|:(missing value)
if library is equal to missing value then return

set aRes1 to (library’s applicationVersion()) as string –>  "12.10.1.37" @ macOS 10.15
set aRes2 to (library’s apiMinorVersion()) –> 1
set aRes3 to (library’s apiMajorVersion()) –> 1

set playLists to library’s allPlaylists()
set gArray to library’s allMediaItems()’s genre
set aRes to countItemsByItsAppearance(gArray) of me

set bRes to genreNayoseAndUnify(aRes, genreNayoseList) of me
–> {{genreName:"サウンドトラック", numberOfTimes:1965}, {numberOfTimes:1209, genreName:"Podcast"}, {genreName:"ロック", numberOfTimes:1128}, {genreName:"クラシック", numberOfTimes:705}, {numberOfTimes:517, genreName:"ポップ"}, {genreName:"アニメ", numberOfTimes:533}, {numberOfTimes:383, genreName:"J-Pop"}, {numberOfTimes:292, genreName:"Pop"}, {numberOfTimes:279, genreName:"社会/文化"}, {numberOfTimes:252, genreName:missing value}, {genreName:"ワールド", numberOfTimes:246}, {numberOfTimes:187, genreName:"ジャズ"}, {genreName:"エレクトロニック", numberOfTimes:168}, {numberOfTimes:125, genreName:"R&B"}, {numberOfTimes:104, genreName:"ニューエイジ"}, {numberOfTimes:81, genreName:"Unclassifiable"}, {genreName:"歌謡曲", numberOfTimes:60}, {numberOfTimes:57, genreName:"Children’s"}, {numberOfTimes:54, genreName:"オルタナティブ"}, {numberOfTimes:38, genreName:"Holiday"}, {numberOfTimes:32, genreName:"Data"}, {numberOfTimes:31, genreName:"イージーリスニング"}, {genreName:"ヴォーカル", numberOfTimes:31}, {numberOfTimes:19, genreName:"iTunes U"}, {numberOfTimes:17, genreName:"フォーク"}, {numberOfTimes:15, genreName:"ブルース"}, {numberOfTimes:15, genreName:"ディズニー"}, {numberOfTimes:15, genreName:"シンガーソングライター"}, {numberOfTimes:14, genreName:"Easy Listening"}, {numberOfTimes:14, genreName:"ラテン"}, {numberOfTimes:14, genreName:"Electronica/Dance"}, {numberOfTimes:14, genreName:"個人ジャーナル"}, {genreName:"ダンス", numberOfTimes:12}, {numberOfTimes:10, genreName:"アクション/アドベンチャー"}, {numberOfTimes:9, genreName:"J-POP"}, {numberOfTimes:9, genreName:"New Age"}, {numberOfTimes:7, genreName:"演歌"}, {numberOfTimes:6, genreName:"少年"}, {numberOfTimes:6, genreName:"青年"}, {numberOfTimes:6, genreName:"キッズ/ファミリー"}, {numberOfTimes:5, genreName:"Video"}, {numberOfTimes:5, genreName:"プログラミング"}, {numberOfTimes:4, genreName:"ホリデー"}, {numberOfTimes:4, genreName:"カントリー"}, {numberOfTimes:4, genreName:"科学/医学"}, {numberOfTimes:3, genreName:"ビジネス"}, {numberOfTimes:3, genreName:"コメディ"}, {numberOfTimes:3, genreName:"Game Music"}, {numberOfTimes:3, genreName:"Latin"}, {genreName:"R&B/ソウル", numberOfTimes:5}, {numberOfTimes:2, genreName:"#NIPPONSEI @ IRC.MIRCX.COM"}, {numberOfTimes:2, genreName:"Technology"}, {numberOfTimes:2, genreName:"ヒップホップ/ ラップ"}, {numberOfTimes:2, genreName:"ヒップホップ/ラップ"}, {numberOfTimes:2, genreName:"日本"}, {numberOfTimes:2, genreName:"ドラマ"}, {numberOfTimes:1, genreName:"社会科学"}, {numberOfTimes:1, genreName:"コンピュータ/テクノロジー"}, {numberOfTimes:1, genreName:"Tech ニュース"}, {numberOfTimes:1, genreName:"科学/自然"}, {numberOfTimes:1, genreName:"その他"}, {numberOfTimes:1, genreName:"児童書フィクション"}, {numberOfTimes:1, genreName:"レゲエ"}, {numberOfTimes:1, genreName:"Lifestyle & Home"}, {numberOfTimes:1, genreName:"ホリデーミュージック"}, {numberOfTimes:1, genreName:"マネジメント/リーダーシップ"}, {numberOfTimes:1, genreName:"インストゥルメンタル"}, {numberOfTimes:1, genreName:"SF/ファンタジー"}, {numberOfTimes:1, genreName:"146"}, {numberOfTimes:1, genreName:"健康/フィットネス"}, {numberOfTimes:1, genreName:"148"}, {numberOfTimes:1, genreName:"NHK FM(東京)"}, {numberOfTimes:1, genreName:"Seattle Pacific University – Latin"}, {numberOfTimes:1, genreName:"チルドレン・ミュージック"}, {numberOfTimes:1, genreName:"名作"}, {numberOfTimes:1, genreName:"Folk"}}

–ジャンルのリストを出現回数で集計
on countItemsByItsAppearance(aList)
  set aSet to NSCountedSet’s alloc()’s initWithArray:aList
  
set bArray to NSMutableArray’s array()
  
set theEnumerator to aSet’s objectEnumerator()
  
  
repeat
    set aValue to theEnumerator’s nextObject()
    
if aValue is missing value then exit repeat
    
bArray’s addObject:(NSDictionary’s dictionaryWithObjects:{aValue, (aSet’s countForObject:aValue)} forKeys:{"genreName", "numberOfTimes"})
  end repeat
  
  
–出現回数(numberOfTimes)で降順ソート
  
set theDesc to NSSortDescriptor’s sortDescriptorWithKey:"numberOfTimes" ascending:false
  
bArray’s sortUsingDescriptors:{theDesc}
  
  
return bArray as list
end countItemsByItsAppearance

on genreNayoseAndUnify(aList as list, genreNayoseList as list)
  set gList to FlattenList(genreNayoseList) of me
  
  
set didProc to {}
  
  
set a2List to {}
  
  
repeat with i in aList
    set aGenre to genreName of i
    
    
if (aGenre is in gList) and (aGenre is not in didProc) then
      
      
repeat with ii in genreNayoseList
        set jj to contents of ii
        
        
if aGenre is in jj then
          copy jj to {g1, g2}
          
          
          
if chkAlphabet(g1) of me = true then
            set targG to g2
            
set targG2 to g1
          else
            set targG to g1
            
set targG2 to g2
          end if
          
          
          
set s1Res to searchByGenreName(aList, targG) of me
          
set s2Res to searchByGenreName(aList, targG2) of me
          
          
          
set s3Res to addMutipleLists({s1Res, s2Res}) of me
          
          
set tmpClass to class of s3Res
          
if tmpClass = list then
            set s3Res to contents of first item of s3Res
          end if
          
          
set outRec to {genreName:targG, numberOfTimes:s3Res}
          
set the end of didProc to g1
          
set the end of didProc to g2
          
          
exit repeat
        end if
        
      end repeat
      
      
set the end of a2List to outRec
    else
      if (aGenre is not in didProc) then
        set the end of a2List to contents of i
      end if
    end if
  end repeat
  
  
return a2List
end genreNayoseAndUnify

on searchByGenreName(aList as list, aGenreName as string)
  set predicatesStr to "genreName == ’" & aGenreName & "’"
  
set anArray to (NSArray’s arrayWithArray:aList)
  
set aPred to (NSPredicate’s predicateWithFormat:predicatesStr)
  
set bRes to (anArray’s filteredArrayUsingPredicate:aPred)
  
if (bRes as list) = {} then return {}
  
  
set bbRes to first item of bRes
  
return (numberOfTimes of bbRes) as list
end searchByGenreName

on addMutipleLists(s1List)
  script spdAdd
    property s1List : {}
    
property s3List : {}
  end script
  
  
copy s1List to (s1List of spdAdd) –init
  
  
set s1Len to length of first item of (s1List of spdAdd)
  
set (s3List of spdAdd) to makeZero1DList(s1Len, 0) of me
  
  
repeat with i in (s1List of spdAdd)
    set tmpLen to length of i
    
if tmpLen is not equal to s1Len then return false
    
    
repeat with ii from 1 to s1Len
      set tmp1 to contents of item ii of (s3List of spdAdd)
      
set tmp2 to contents of item ii of i
      
      
set item ii of (s3List of spdAdd) to (tmp1 + tmp2)
    end repeat
  end repeat
  
  
return (s3List of spdAdd)
end addMutipleLists

–指定要素を指定回数追加したリストを作成する
on makeZero1DList(itemMax, itemElem)
  set allData to {}
  
repeat itemMax times
    set the end of allData to itemElem
  end repeat
  
return allData
end makeZero1DList

–By Paul Berkowitz
–2009年1月27日 2:24:08:JST
–Re: Flattening Nested Lists
on FlattenList(aList)
  set oldDelims to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to {"????"}
  
set aString to aList as text
  
set aList to text items of aString
  
set AppleScript’s text item delimiters to oldDelims
  
return aList
end FlattenList

— アルファベットのみか調べて返す
on chkAlphabet(checkString)
  set aStr to NSString’s stringWithString:checkString
  
set allCharSet to NSMutableCharacterSet’s alloc()’s init()
  
allCharSet’s addCharactersInRange:(current application’s NSMakeRange(ASCII number of "a", 26))
  
allCharSet’s addCharactersInRange:(current application’s NSMakeRange(ASCII number of "A", 26))
  
set aBool to my chkCompareString:aStr baseString:allCharSet
  
return aBool as boolean
end chkAlphabet

on chkCompareString:checkString baseString:baseString
  set aScanner to NSScanner’s localizedScannerWithString:checkString
  
aScanner’s setCharactersToBeSkipped:(missing value)
  
aScanner’s scanCharactersFromSet:baseString intoString:(missing value)
  
return (aScanner’s isAtEnd()) as boolean
end chkCompareString:baseString:

★Click Here to Open This Script 

Posted in list | Tagged 10.12savvy 10.13savvy 10.14savvy 10.15savvy NSArray NSCountedSet NSDictionary NSMutableArray NSMutableCharacterSet NSPredicate NSScanner NSSortDescriptor NSString | Leave a comment

1Dリスト内の項目を指定セグメント単位で合成(加算)

Posted on 12月 2, 2019 by Takaaki Naganoya

1D List(1次元配列)のデータを指定セグメント単位で合成(加算)するAppleScriptです。

何を言っているのか作った本人にしか通じない雰囲気が漂っていますが、単にデータの集計単位を変更するためのものです。

24時間を1時間単位で集計したデータを3時間単位で区切って集計するとか、午前午後(2セグメント)でまとめて集計するとかといった用途に使います。

いちじるしく、日常的に書き捨てしているレベルの処理ではありますが、再利用できる部品にまとめておきました。

AppleScript名:1Dリスト内の項目を指定セグメント単位で合成
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/12/02
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
set aList to {0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 20, 10, 5, 3, 2, 1}
set a2List to gatherEachItemsBy(aList, 3) of me
–> {0, 0, 3, 12, 21, 33, 35, 6}

set a3List to gatherEachItemsBy(aList, 2) of me
–> {0, 0, 0, 1, 5, 9, 13, 18, 23, 30, 8, 3}

set a4List to gatherEachItemsBy(aList, 4) of me
–> {0, 1, 14, 31, 53, 11}

set a4List to gatherEachItemsBy(aList, 5) of me
–> false

set a5List to gatherEachItemsBy(aList, 6) of me
–> {0, 15, 54, 41}

set a6List to gatherEachItemsBy(aList, 7) of me
–> false

set a7List to gatherEachItemsBy(aList, 8) of me
–> {1, 45, 64}

set a8List to gatherEachItemsBy(aList, 12) of me
–> {15, 95}

set a9List to gatherEachItemsBy(aList, 24) of me
–> {110}

set a10List to gatherEachItemsBy(aList, 0) of me
–> {110}

on gatherEachItemsBy(aList as list, aStep as number)
  set bList to {}
  
set aLen to length of aList
  
  
if aStep = 0 then set aStep to aLen
  
if aLen mod aStep is not equal to 0 then return false
  
  
repeat with i from 1 to aLen by aStep
    set tmpV to 0
    
    
repeat with ii from 0 to (aStep – 1)
      set anItem to item (i + ii) of aList
      
set tmpV to tmpV + anItem
    end repeat
    
    
set the end of bList to tmpV
  end repeat
  
  
return bList
end gatherEachItemsBy

★Click Here to Open This Script 

Posted in list | Tagged 10.12savvy 10.13savvy 10.14savvy 10.15savvy | Leave a comment

指定のフォントとサイズに該当するテキストを抽出する v3

Posted on 12月 1, 2019 by Takaaki Naganoya

指定のRTFファイルから書式情報を取得し、フォント名とフォントサイズのペアをスタイルを反映させたポップアップメニューで選択。RTFの内容を解析したのち、ダイアログが表示されます(ここの所要時間は読ませるRTFのサイズ次第)。ポップアップメニューで書式を選ぶと、すぐさま抽出した箇所をすべてまとめて表示します。

–> Watch Demo Movie

–> Download Script Bundle with Sample data

ダイアログ表示前に書式ごとの抽出を完了し、個別のTabViewに抽出後の文字データを展開しておくので、ポップアップメニューから選択すると、展開ずみのデータを入れてあるTabViewに表示を切り替えるだけ。切り替え時に計算は行わないため、すぐに抽出ずみの文字データが表示されるという寸法です。

今回は短いサンプルデータを処理してみましたが、サンプル抽出時にあらかじめ範囲指定するなどして、データ処理規模を限定することで処理時間を稼ぐこともできることでしょう。

テキストエディットでオープン中のRTF書類のパスを取得して、それを処理対象にしてもいいでしょう。

ただし、やっつけで作ったのでスクリプトエディタ上でCommand-Control-Rで実行しないと動きません(メインスレッド実行をプログラムで強制しても、途中でクラッシュしてしまいます)。それほど時間もかけずに作ったやっつけプログラムなので、あまり原因追求も行えずそのままです。

AppleScript名:アラートダイアログ+Tab View v3.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/09/16
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use rtfLib : script "readStyledTextLib"
use parseLib : script "parseAttrLib"

property NSFont : a reference to current application’s NSFont
property NSView : a reference to current application’s NSView
property NSAlert : a reference to current application’s NSAlert
property NSColor : a reference to current application’s NSColor
property NSMenu : a reference to current application’s NSMenu
property NSArray : a reference to current application’s NSArray
property NSTabView : a reference to current application’s NSTabView
property NSPredicate : a reference to current application’s NSPredicate
property NSTextView : a reference to current application’s NSTextView
property NSMenuItem : a reference to current application’s NSMenuItem
property NSTabViewItem : a reference to current application’s NSTabViewItem
property NSPopUpButton : a reference to current application’s NSPopUpButton
property NSMutableDictionary : a reference to current application’s NSMutableDictionary
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSFontAttributeName : a reference to current application’s NSFontAttributeName
property NSKernAttributeName : a reference to current application’s NSKernAttributeName
property NSLigatureAttributeName : a reference to current application’s NSLigatureAttributeName
property NSMutableAttributedString : a reference to current application’s NSMutableAttributedString
property NSStrokeWidthAttributeName : a reference to current application’s NSStrokeWidthAttributeName
property NSUnderlineStyleAttributeName : a reference to current application’s NSUnderlineStyleAttributeName
property NSForegroundColorAttributeName : a reference to current application’s NSForegroundColorAttributeName

property TabPosition : 4 —0=Top, 1=Left, 2=Bottom, 3=Right, 4=None

property returnCode : 0

property aTabV : missing value
property selectedNum : {}

set aFile to choose file of type {"public.rtf"}

set aStyledStr to readRTFfile(aFile) of rtfLib
set paramObj to {myMessage:"Select Style", mySubMessage:"Select style you want to filter", viewWidth:800, viewHeight:400, myStyledStr:aStyledStr}

my dispTabViewWithAlertdialog:paramObj –for debug
–my performSelectorOnMainThread:"dispTabViewWithAlertdialog:" withObject:paramObj waitUntilDone:true
return selectedNum

on dispTabViewWithAlertdialog:paramObj
  –Receive Parameters
  
set aMainMes to (myMessage of paramObj) as string –Main Message
  
set aSubMes to (mySubMessage of paramObj) as string –Sub Message
  
set aWidth to (viewWidth of paramObj) as integer –TextView width
  
set aHeight to (viewHeight of paramObj) as integer –TextView height
  
set aStyledStr to (myStyledStr of paramObj)
  
  
set attrResTmp to getAttributeRunsFromAttrString(aStyledStr) of parseLib
  
set attrList to attributes of attrResTmp
  
set menuStyle to menuList of attrResTmp
  
  
set selectedNum to {}
  
  
set aView to NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))
  
  
–Ppopup Buttonをつくる
  
set a1Button to NSPopUpButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, aHeight – 20, 400, 20)) pullsDown:false
  
a1Button’s removeAllItems()
  
  
–WYSIWHG popup menuをつくる
  
set a1Menu to NSMenu’s alloc()’s init()
  
repeat with i from 1 to (length of menuStyle)
    set {tmpFont, tmpSize} to contents of item i of menuStyle
    
set aTitle to (tmpFont & " " & tmpSize as string) & " point"
    
set aMenuItem to (NSMenuItem’s alloc()’s initWithTitle:aTitle action:"actionHandler:" keyEquivalent:"")
    
    
set attributedTitle to makeRTFfromParameters(aTitle, tmpFont, tmpSize, NSColor’s blackColor()) of me
    
    (
aMenuItem’s setEnabled:true)
    (
aMenuItem’s setTarget:me)
    (
aMenuItem’s setTag:(i as string))
    (
aMenuItem’s setAttributedTitle:(attributedTitle))
    (
a1Menu’s addItem:aMenuItem)
  end repeat
  
  
–Ppopup Buttonにmenuをつける
  
a1Button’s setMenu:a1Menu
  
  
–Make Tab View
  
set aTabV to NSTabView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight – 30))
  
aTabV’s setTabViewType:(TabPosition)
  
  
  
–TabViewに中身を入れる
  
repeat with i from 1 to (length of menuStyle)
    set {tmpFont, tmpSize} to contents of item i of menuStyle
    
set tmpKey to (tmpFont as string) & "/" & (tmpSize as string)
    
set tmpArry to filterRecListByLabel1(attrList, "styleKey2 == ’" & tmpKey & "’") of me
    
set tmpStr to (tmpArry’s valueForKeyPath:"stringVal") as list
    
    
set aTVItem to (NSTabViewItem’s alloc()’s initWithIdentifier:(i as string))
    (
aTVItem’s setLabel:(i as string))
    
    
    
set aTextView to (NSTextView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth – 10, aHeight – 10)))
    (
aTextView’s setRichText:true)
    
set tmpAttr to makeRTFfromParameters(tmpStr as string, tmpFont, tmpSize, NSColor’s blackColor()) of me
    (
aTextView’s textStorage()’s appendAttributedString:tmpAttr)
    
    (
aTVItem’s setView:aTextView)
    
    (
aTabV’s addTabViewItem:aTVItem)
  end repeat
  
  
  
aView’s setSubviews:{a1Button, aTabV}
  
aView’s setNeedsDisplay:true
  
  
  
— set up alert
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    –for Messages
    
its setMessageText:(aMainMes)
    
its setInformativeText:(aSubMes)
    
    
–for Buttons
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
    
–Add Accessory View
    
its setAccessoryView:(aView)
    
    
–for Help Button
    
its setShowsHelp:(true)
    
its setDelegate:(me)
  end tell
  
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
if (my returnCode as number) = 1001 then error number -128
  
  
set selectedNum to contents of item ((a1Button’s indexOfSelectedItem()) + 1) of menuStyle
end dispTabViewWithAlertdialog:

on doModal:aParam
  set (my returnCode) to aParam’s runModal()
end doModal:

on alertShowHelp:aNotification
  display dialog "Help Me!" buttons {"OK"} default button 1 with icon 1
  
return false –trueを返すと親ウィンドウ(アラートダイアログ)がクローズする
end alertShowHelp:

–Popup Action Handler
on actionHandler:sender
  set aTag to tag of sender as integer
  
aTabV’s selectTabViewItemAtIndex:(aTag – 1)
end actionHandler:

–書式つきテキストを組み立てる
on makeRTFfromParameters(aStr as string, aFontName as string, aFontSize as real, aColor)
  –フォント
  
set aVal1 to NSFont’s fontWithName:(aFontName) |size|:aFontSize
  
set aKey1 to (NSFontAttributeName)
  
  
–色
  
set aVal2 to aColor
  
set aKey2 to (NSForegroundColorAttributeName)
  
  
–カーニング
  
set aVal3 to 0.0
  
set akey3 to (NSKernAttributeName)
  
  
–アンダーライン
  
set aVal4 to 0
  
set akey4 to (NSUnderlineStyleAttributeName)
  
  
–リガチャ
  
–set aVal5 to 2 –全てのリガチャを有効にする
  
–set akey5 to ( NSLigatureAttributeName)
  
  
–枠線(アウトライン)
  
–set aVal6 to outlineNum
  
–set akey6 to ( NSStrokeWidthAttributeName)
  
  
  
set keyList to {aKey1, aKey2, akey3, akey4}
  
set valList to {aVal1, aVal2, aVal3, aVal4}
  
set attrsDictionary to NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList
  
  
set attrStr to NSMutableAttributedString’s alloc()’s initWithString:aStr attributes:attrsDictionary
  
return attrStr
end makeRTFfromParameters

–リストに入れたレコードを、指定の属性ラベルの値で抽出
on filterRecListByLabel1(aRecList as list, aPredicate as string)
  set aArray to NSArray’s arrayWithArray:aRecList
  
set aPredicate to NSPredicate’s predicateWithFormat:aPredicate
  
set filteredArray to aArray’s filteredArrayUsingPredicate:aPredicate
  
set bList to filteredArray
  
return bList
end filterRecListByLabel1

★Click Here to Open This Script 

Posted in Color dialog Font GUI Require Control-Command-R to run RTF | Tagged 10.14savvy 10.15savvy NSAlert NSArray NSColor NSFont NSFontAttributeName NSForegroundColorAttributeName NSKernAttributeName NSLigatureAttributeName NSMenu NSMenuItem NSMutableAttributedString NSMutableDictionary NSPopUpButton NSPredicate NSRunningApplication NSStrokeWidthAttributeName NSTabView NSTabViewItem NSTextView NSUnderlineStyleAttributeName NSView | 1 Comment

macOS標準装備のAppleScript専用補助アプリケーション「Image Events」がデフォルトではファイルにアクセスできない設定に

Posted on 12月 1, 2019 by Takaaki Naganoya

macOSには、GUIをもたないAppleScript専用の補助アプリケーションが標準装備されていますが、macOS 10.15になって正常に(期待通りに)動作しない状態でリリースされているので注意が必要というお話です。

macOSには、「●●Scripting」といったClassic Mac OSから引き継いだツール群と、「●●Events」といったMac OS X移行時に搭載されたAppleScriptからの呼び出し専用のツール群が、/System/Library/CoreServicesフォルダに入っています。

  10.4 10.5 10.6 10.7 10.8 10.9 10.10 10.11 10.12 10.13 10.14 10.15 11.0
ColorSyncScripting ⬛︎ ⬛︎            
Database Events ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎
Digital Hub Scripting ⬛︎ ⬛︎            
FontSync Scripting ⬛︎ ⬛︎            
Image Events ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ★ ★
Keychain Scripting ⬛︎ ⬛︎ ⬛︎          
System Events ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎ ⬛︎
URL Access Scripting ⬛︎ ⬛︎ ⬛︎          

▲「最新事情がわかるAppleScript 10大最新技術 Ver.2.0」より抜粋(36ページ掲載)、最新OSに合わせて改定

最新版のmacOS 10.15でもSystem Events、Image Events、Database Eventsの3つが残っており、System Eventsはよく使われています。

Image Eventsはごくまれに、Database Eventsに至ってはほぼ実戦で利用したことがありませんが、存在していることは確認しています。

そんなImage Eventsが、macOS 10.15上でデフォルト設定ではユーザー指定の画像ファイルにアクセスできなくなっていることが確認されています。

システム環境設定の「セキュリティとプライバシー」>「セキュリティ」>「フルディスクアクセス」にImage Eventsを登録すればアクセスできるようにはなりますが、「セキュリティ強化」の美名のもとに機能の自家中毒を起こしている状態といえるでしょう。

一方、Database Eventsではそんなことはなく、Database Events経由で作成したデータベースに問題なくアクセスできますし、Database Eventsの唯一にして最大の機能である「AppleScriptのフィルタ参照でデータベースのしぼりこみ検索を行う」機能も健在です(それしかできないので)。

AppleScriptによる画像処理は、ICCプロファイルを重視してAdobe Photoshopで行うか、RGB画像をスピーディーにCocoa Frameworkで処理するかの方向に二分されており、Image Eventsで行うような基礎的な画像処理はCocoa Frameworkで肩代わりされる方向にあります。Image Eventsは入門者向けのなんちゃって画像処理レベルで用いられるものであり、個人的にはほとんど利用していません。事情を知らない入門者がハマる落とし穴が新しく1つ作られたといったところでしょうか。


▲openコマンドの引数はfile(実際にはalias)と書かれているが、furlで渡さないとオープンされないImage Events


▲SQLiteラッパーで、素朴すぎて機能がまったく不明だったDatabase Events。まさかフィルタ参照で絞り込みを行う専用ツールだったとは(ソート命令も検索命令もない謎仕様)

Posted in Bug Security | Tagged 10.15savvy Database Events Image Events | 2 Comments

指定のフォントとサイズに該当するテキストを抽出する v2

Posted on 11月 30, 2019 by Takaaki Naganoya

macOS標準搭載のテキストエディタ「テキストエディット」の最前面のドキュメントから書式情報を取得し、フォント名とフォントサイズのペアをスタイルを反映させたポップアップメニューで選択。選択したスタイルが該当する箇所を抽出したのちにテキスト化してTextViewで結果を表示します。

–> Download Code-signed AppleScript applet executable with libraries


▲Sample RTF(なんでもOK)


▲添付のAppleScriptアプレットは、初回実行時に制御許可のダイアログが表示されます。OKすれば、2回目以降はダイアログ表示されません


▲書式情報をRTF書類から読み込んで、スタイルを反映させたポップアップメニューで表示。サンプル文をRTF書類から取得しているものの、改行部分だけがヒットしたりとなかなかうまくありません


▲一覧から選択


▲RTF書類から指定書式に相当するテキストを抽出して出力

AppleScript名:指定のフォントとサイズに該当するテキストを抽出する v2.scptd
— Created 2019-11-29 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use wgMenuLib : script "wysiwygMenuLib" –WYSIWYGポップアップメニューダイアログ ライブラリ
use dtLib : script "dTextView" –TextView表示ライブラリ

script spd
  property fontList : {}
  
property fontSizes : {}
  
property textList : {}
  
property outList : {}
  
property combiList : {}
end script

set (outList of spd) to {}
set (fontList of spd) to {}
set (fontSizes of spd) to {}
set (textList of spd) to {}
set (combiList of spd) to {}

–TextEdit書類から書式情報を根こそぎ取得
tell application "TextEdit"
  tell text of front document
    set (fontList of spd) to font of every attribute run –フォント名
    
set (fontSizes of spd) to size of every attribute run –文字サイズ
    
set (textList of spd) to character of every attribute run –文字
  end tell
end tell

–ポップアップメニュー選択用のデータを作成
set aLen to length of (fontList of spd)
set menuList to {}
set sampleList to {}
repeat with i from 1 to aLen
  set tmpFont to contents of item i of (fontList of spd)
  
set tmpSize to contents of item i of (fontSizes of spd)
  
set tmpSample to (contents of item i of (textList of spd)) as string
  
set tmpList to {tmpFont, tmpSize}
  
if {tmpList} is not in (combiList of spd) then
    set the end of (combiList of spd) to tmpList
    
set the end of menuList to (tmpFont & " — " & tmpSize as string) & " point ex.:" & tmpSample
  end if
end repeat

–WYSIWYGポップアップメニューで項目選択
set paramObj to {myMessage:"Select Attribute", mySubMessage:"Select target attribute", segmentMes:{menuList}, segmentTitles:{"Select combination of font name and size"}, segmentAttributes:(combiList of spd)}
set fRes to makeMenuAndcheck(paramObj) of wgMenuLib
if fRes = 0 then return

copy item (first item of fRes) of (combiList of spd) to {aFont, aSize}

–取得した条件にもとづいて、根こそぎ取得した書式と照合を行いつつループ
repeat with i from 1 to length of (fontList of spd)
  set tmpFont to contents of item i of (fontList of spd)
  
set tmpSize to contents of item i of (fontSizes of spd)
  
  
–文字サイズをざっくり判定することで「大、中、小」といったおおまかな切り分けも可能
  
if {tmpFont, tmpSize} = {aFont, aSize} then
    set tmpCon to (contents of item i of (textList of spd)) as string
    
if tmpCon does not contain "•" then –ごみ取り
      set the end of (outList of spd) to tmpCon
    end if
  end if
end repeat

–結果をTextViewで表示
set aStr to retListedText(outList of spd, return) of me
set eRes to (display text view aStr main message "Result" sub message "" with properties {font name:aFont, size:aSize, width:800, height:400})

on retListedText(aList, aSeparator)
  set aText to ""
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aSeparator
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retListedText

★Click Here to Open This Script 

Posted in dialog GUI list RTF | Tagged 10.13savvy 10.14savvy 10.15savvy | Leave a comment

Double PDF v2.0完成に近づく

Posted on 11月 29, 2019 by Takaaki Naganoya

Mac App Storeで販売したはいいものの、途中(macOS 10.13)でド派手なバグをOS(PDFView)に作られ、AppleのDevelopper Supportに正式に連絡してもなしのつぶてでそのままMac App Storeに置かれている「Double PDF」。さすがに現状のままだとまずすぎるので、macOS 10.14/10.15上で動作するように改修作業を行なっている今日このごろ(macOS 10.13.xでは、動くことは動くんですがOS自体の未修正バグが多すぎて動作保証いたしかねます)。

# OSをアップデートすると機能が落ちるとは何事だろう?

PDFViewのド派手なバグ(currentPageを取得できない)を回避するために、自前でAppleScriptでいろいろ回避コードを走らせているので、ページめくりのスピードが落ちています(個人的にこれのために作ったので、テンションが落ちるところです)。

初版では画像処理にGPUImage.frameworkを同梱して利用していましたが、GPUImage1だとOpenGL経由でGPUの機能にアクセスしており、OpenGL自体が最新のmacOS 10.15では非推奨となっており、Mac App Storeでリジェクトされる危険性があります(より新しい代替APIであるMetalを使わないと因縁を付けられる気が、、、)。

そこで、GPUImageに依存しているコードをすべて書き換え、GPUImageを完全に取り外しました。これには、よくよく調べたら、PDFの各ページをグレースケール画像に変換する箇所でしか利用していなかったことが大きいです。これで、名実ともに「すべてAppleScriptで記述したアプリケーション」に。

GPUImageの除去は使い勝手には一切影響しません。若干の前向きな機能追加も行なっておきましょう。

これまでに意見として寄せられていないものの、どうもグレースケール画像で比較を行うことに不満を持っていたユーザーが一定数いるものとにらんでいたので、カラーのまま比較する機能を追加しました。

正直なところ、「カラー比較モード」は個人的には不要と思っている(文字主体の書籍の校正用に作った)のですが、念のためです。

Double PDFはデータ上のささいな違いを「見逃す」ように作ってあります。これは、Adobe AcrobatのPDF比較機能が、見た目には影響を及ぼさないデータ上の些細な違いばかりピックアップして実用性がまったくないことから思いついたものです。見た目に影響のない差異を見逃して、見た目や文字で差が発生している箇所を指摘するツールという味付けになっています。

画像サイズを小さくした上でグレースケール化して比較するのはそのための重要な機能です。ただ、間違って色が変わったことを検出したいような用途もあることでしょう。

あとは、PDFからテキスト抽出をしたときに、PDF書き出し時の環境(OSバージョン)によってはNo Width Spaceが検出されるものがあるため、No Width Spaceの削除機能を追加しました。

細かい箇所でまだ不具合点(右側のビューワーのノンブルが表示されないことがある)がありますが、とりあえず出してみてもよさそうな気配はしています。

地味なところで画像素材をDark Mode対応させました。Credits.rtfのダークモード対応など、地味に工数が増えるのは勘弁してほしいです。あとは、外部アプリケーション操作要求を行うためのInfo.plistのエントリ追加などもあります。これを追加しないと外部アプリケーションへの操作要求のダイアログ自体が出ない=一切操作できないので要注意点です。

ほかにも、現行のXcodeでCocoa AppleScriptアプリケーションのプロジェクトを作ると、デフォルトではソースコード開示状態のビルドセッティングになってしまうので、これも要チェック点でしょう。まさかと思ってこの設定を再確認してみたら、execute onlyになっていませんでした。怖すぎ、、、

Posted in AppleScript Application on Xcode Image PDF | Tagged 10.12savvy 10.13savvy 10.14savvy 10.15savvy | Leave a comment

指定のNSImageをグレースケールに

Posted on 11月 29, 2019 by Takaaki Naganoya

指定のNSImageをグレースケール画像にしたのちNSImageで出力するAppleScriptです。

GPUImageをプログラムから取り外すにあたって必要になったので用意しました。ふだん、画像変換系のScriptはNSImageで入力したのちにファイルに出力するように組んであったのですが、入出力ともにNSImageにしてあるプログラムが手元に存在していなかったので。

GPUImageが自分にとって使いやすかったのは、入出力にNSImageが使えたからだと思います。CGImageだとAppleScriptからアクセスできないですし、CIImageもアクセスできないわけではないですが、ちょっと遠回りになります。

AppleScript名:指定のNSImageをグレースケールに
— Created 2019-07-09 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property NSString : a reference to current application’s NSString
property NSImage : a reference to current application’s NSImage
property NSColorSpace : a reference to current application’s NSColorSpace
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep
property NSColorRenderingIntentPerceptual : a reference to current application’s NSColorRenderingIntentPerceptual

set aFile to POSIX path of (choose file of type {"public.image"} with prompt "Select Image A")
set aImage to NSImage’s alloc()’s initWithContentsOfFile:aFile

set gImage to convNSIMageAsGray(aImage) of me

–NSImageをグレースケールに変換してNSImageで返す
on convNSIMageAsGray(anImage)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to NSBitmapImageRep’s imageRepWithData:imageRep
  
  
set bRawimg to convBitMapToDeviceGrey(aRawimg) of me
  
  
set bImage to NSImage’s alloc()’s initWithSize:(bRawimg’s |size|())
  
bImage’s addRepresentation:bRawimg
  
  
return bImage
end convNSIMageAsGray

–NSBitmapImageRepをグレースケールに変換する
on convBitMapToDeviceGrey(aBitmap)
  set aSpace to NSColorSpace’s deviceGrayColorSpace()
  
set bRawimg to aBitmap’s bitmapImageRepByConvertingToColorSpace:aSpace renderingIntent:(NSColorRenderingIntentPerceptual)
  
return bRawimg
end convBitMapToDeviceGrey

★Click Here to Open This Script 

Posted in Color Image | Tagged 10.13savvy 10.14savvy 10.15savvy NSBitmapImageRep NSColorRenderingIntentPerceptual NSColorSpace NSImage NSString | Leave a comment

URLエンコードずみ文字列チェック

Posted on 11月 29, 2019 by Takaaki Naganoya

与えられた文字列がURLエンコードずみ文字列かどうかをチェックするAppleScriptです。

なんでそんなものが必要になったかといえば、macOS 10.15のPDFView上で発生した(”applescript://” schemeの)URL EventがデコードされずにOSデフォルト指定のスクリプトエディタに転送される、URLデコード不良バグが発生。これに対処した簡易PDFビューワーも用意しましたが、macOS 10.15.2 Beta3でこのバグが修正されているように見えます。

# 一度発生したバグは、今後もAppleが再発しないよう継続して監視する必要があります

すると、今度は簡易PDFビューワー側でURLイベントをデコードしてからScript Editorに転送している処理が「余計」になってしまいます。再デコードした文字列は途中で途切れてしまうので、処理対象の文字列がURLエンコードされたものかどうかをチェックする必要が出てきました。

このままOSにURLデコード不良バグが残存するよりは、こうしたプログラムでチェックしてから処理するほうがよいでしょう。

AppleScript名:URLエンコードずみ文字列チェック.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/11/29
—
–  Copyright © 2019 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 NSString : a reference to current application’s NSString

set aStr to "applescript://com.apple.scripteditor?action=new&script=display%20dialog%20%22TEST%22"
set aRes to chkEncodedURLorNot(aStr) of me
–> true –URL Encoded

set bStr to "display dialog \"TEST\""
set bRes to chkEncodedURLorNot(bStr) of me
–> false –Not URL encoded

on chkEncodedURLorNot(aStr)
  set nsStr to NSString’s stringWithString:aStr
  
set decodedStr to nsStr’s stringByRemovingPercentEncoding()
  
  
if (nsStr’s isEqualToString:decodedStr) then
    return false –encoded URL
  else
    return true –Not encoded URL
  end if
end chkEncodedURLorNot

★Click Here to Open This Script 

Posted in Text URL | Tagged 10.13savvy 10.14savvy 10.15savvy NSString NSURL | Leave a comment

[作業中]Double PDF 改修中

Posted on 11月 28, 2019 by Takaaki Naganoya

AppleがPDFViewのScripting Bridge関連データにバグを作り、レポートしても一向に直さないため、Mac App Storeに出しているものの、macOS 10.13以降のOSでは正常動作しない、Piyomaru Software謹製のPDF差分ブラウザ「Double PDF」。

Appleが作ったバグのせいで基礎的な動作が阻害されてしまっているので、機能アップは一切考えないで(機能アップ版として別のものを作っていたので)、Double PDFについては現在のOSで動くレベルで改修をすすめています(作業量が見えない、、、、)。

–> Demo Movie of Current Version of Double PDF v2.0 (on macOS 10.14.6)

AppleScriptの箱庭世界でモノを作っている分には環境変化は割と穏やかですが、直接Cocoaの機能に手を出しはじめると、OSバージョンごとの無意味な名称改変とか、予告なしの仕様変更とか、このような未改修のバグに直面することがあり、Mac OS X 10.3で「is in」という基礎的かつ重要な演算子にバグを作られた時と同質の負の感情を喚起されるものがあります。

正式にDevelopper Supportの窓口から詳細に症状を伝えてレポートしても無視されているので、AppleのDevelopper Supportもバグの報告でパンクしているということでしょうか。macOS 10.13以降、バグレポートしても返事も来ないのが日常化してしまったので(AppleScript関連ではないバグがほとんどなのですが)、バグを直す気がないんでしょうか。


▲macOS 10.14.6上で改修中。まだ画面操作まわりに着手しただけ


▲macOS 10.15.1上で動作確認。最近のmacOSはBetaで動作確認してもRelease版の品質がBeta以下なので、Beta上で確認する意義が、、、

Appleによって破壊された機能は、PDFViewまわりの基礎的な機能。

- (IBAction)goToFirstPage:(nullable id)sender;
- (IBAction)goToLastPage:(nullable id)sender;
- (IBAction)goToNextPage:(nullable id)sender;
- (IBAction)goToPreviousPage:(nullable id)sender;

@property (nonatomic, readonly, nullable) PDFPage *currentPage;

などです(他にもあるかも。いや、確実にある)。つまり、PDFビューワー機能を作ろうとすると、いろいろ苦労させられる状態です。

苦労が必要ということは、余計に処理時間が必要ということで、処理速度はオリジナル版よりも遅くなっています。とくに、PDFのページめくりが、、、


▲開発時に資料を作っておかなかったらもっと大変、、、、、

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

ジャンル名名寄せ v2

Posted on 11月 27, 2019 by Takaaki Naganoya

iTunes/Musicのライブラリに入っている楽曲データのジャンル分けのゆらぎ吸収を行う、ジャンル名のいわゆる「名寄せ」を行うAppleScriptです。


▲1つのアルバム中でもジャンル名に表記ゆれがあるのは勘弁してほしい

iTunes/Musicライブラリ中の全楽曲の最終再生日時を24時間の各時で集計を行い、ジャンルごとに再生時間に偏りがないかどうかを分析するため、さらにジャンルごろに集計してみました。

「名寄せ」(なよせ)は昔から情報処理に見られる泥臭い地道な処理で、データ上の表記ゆれを吸収するための処理です。地名などの固有名詞で多く見られます(念のためにWikipediaで調べたら、異なる業界では割とブラックな言葉として用いられている模様)。

このジャンル名が英語で入っていたり日本語で入っていたりと、ゆらぎが発生しているので、同様のジャンル名であれば同じものとして合算して集計してみました。

また、英語で表記されたジャンル名ではなく日本語で表記されたものを採用(=すべてアルファベットで書かれたものを不採用)しています。まだ、それほどいじめ抜いていない(自分の環境でしかテストしていない)ので、ジャンル名の名寄せリストはもう少し鍛えておく必要があるものと思っています。

AppleScript名:ジャンル名名寄せ v2
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/11/24
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.5" — El Capitan (10.11) or later
use framework "Foundation"
use scripting additions

property NSArray : a reference to current application’s NSArray
property NSString : a reference to current application’s NSString
property NSScanner : a reference to current application’s NSScanner
property NSPredicate : a reference to current application’s NSPredicate
property NSMutableCharacterSet : a reference to current application’s NSMutableCharacterSet

–ジャンル名寄せリスト(2要素から構成される2D List)
set genreNayoseList to {{"World", "ワールド"}, {"Anime", "アニメ"}, {"Electronic", "エレクトロニック"}, {"R&B/ソウル", "R&B/ソウル"}, {"Kayokyoku", "歌謡曲"}, {"Electronic", "エレクトロニック"}, {"Vocal", "ヴォーカル"}, {"Classical", "クラシック"}, {"Dance", "ダンス"}, {"Soundtrack", "サウンドトラック"}}

–名寄せ対象リスト(genreNameを名寄せ)
set aList to {{genreName:"シンガーソングライター", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 0, 0, 0, 1, 5, 0, 0, 0, 0}}, {genreName:"ロック", playingList:{2, 2, 0, 0, 0, 1, 0, 0, 4, 3, 9, 5, 11, 11, 22, 19, 48, 17, 28, 15, 2, 11, 13, 1}}, {genreName:"Soundtrack", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}}, {genreName:"World", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}}, {genreName:"演歌", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {genreName:"ホリデーミュージック", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {genreName:"ディズニー", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0}}, {genreName:"J-Pop", playingList:{4, 0, 1, 1, 2, 1, 5, 3, 2, 3, 27, 19, 14, 26, 17, 20, 28, 32, 40, 25, 10, 10, 6, 6}}, {genreName:"ヒップホップ/ ラップ", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {genreName:"Electronic", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {genreName:"アニメ", playingList:{7, 1, 0, 0, 7, 2, 0, 0, 0, 9, 23, 45, 17, 10, 17, 50, 48, 65, 53, 27, 12, 16, 23, 45}}, {genreName:"ポップ", playingList:{3, 0, 0, 0, 0, 0, 0, 3, 1, 6, 2, 9, 7, 0, 11, 7, 8, 10, 7, 5, 3, 1, 0, 1}}, {genreName:"Kayokyoku", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}}, {genreName:"ヒップホップ/ラップ", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}}, {genreName:"Dance", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}}, {genreName:"ダンス", playingList:{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 2, 0, 0}}, {genreName:"R&B/ソウル", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {genreName:"Anime", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0}}, {genreName:"チルドレン・ミュージック", playingList:{0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {genreName:"Classical", playingList:{1, 1, 0, 0, 2, 1, 8, 1, 0, 0, 11, 5, 2, 0, 4, 9, 13, 2, 2, 0, 0, 0, 0, 0}}, {genreName:"ニューエイジ", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 0, 0, 0, 0}}, {genreName:"Pop", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}}, {genreName:"ヴォーカル", playingList:{0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 7, 0, 0, 1, 6, 0, 0, 3, 1, 0, 3, 0, 0, 0}}, {genreName:"サウンドトラック", playingList:{23, 31, 0, 0, 0, 2, 1, 0, 7, 7, 27, 29, 26, 25, 28, 48, 66, 76, 56, 16, 8, 31, 6, 10}}, {genreName:"歌謡曲", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 2, 4, 5, 5, 4, 6, 6, 7, 1, 0, 0, 0}}, {genreName:"ホリデー", playingList:{0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0}}, {genreName:"Folk", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}}, {genreName:"ジャズ", playingList:{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 16, 7, 3, 9, 0, 5, 10, 20, 10, 2, 1, 0, 0}}, {genreName:"エレクトロニック", playingList:{0, 1, 3, 0, 0, 0, 0, 1, 4, 13, 8, 13, 2, 18, 6, 13, 10, 16, 25, 7, 8, 0, 2, 10}}, {genreName:"ワールド", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 1, 0, 5, 5, 7, 6, 0, 0, 0, 0, 0}}, {genreName:"インストゥルメンタル", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}}, {genreName:"Vocal", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}}, {genreName:"クラシック", playingList:{0, 0, 1, 1, 0, 3, 2, 0, 4, 3, 13, 11, 24, 1, 21, 14, 24, 38, 21, 7, 5, 8, 4, 5}}, {genreName:"オルタナティブ", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 1, 0, 0, 6, 9, 0}}, {genreName:"R&B/ソウル", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}}

set bList to genreNayoseAndUnify(aList, genreNayoseList) of me
–> {{genreName:"シンガーソングライター", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 0, 0, 0, 1, 5, 0, 0, 0, 0}}, {genreName:"ロック", playingList:{2, 2, 0, 0, 0, 1, 0, 0, 4, 3, 9, 5, 11, 11, 22, 19, 48, 17, 28, 15, 2, 11, 13, 1}}, {genreName:"サウンドトラック", playingList:{23, 31, 0, 0, 0, 2, 1, 0, 7, 7, 28, 29, 26, 25, 28, 48, 66, 77, 56, 16, 8, 31, 6, 10}}, {genreName:"ワールド", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 1, 0, 5, 5, 8, 6, 0, 0, 0, 0, 0}}, {genreName:"演歌", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {genreName:"ホリデーミュージック", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {genreName:"ディズニー", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0}}, {genreName:"J-Pop", playingList:{4, 0, 1, 1, 2, 1, 5, 3, 2, 3, 27, 19, 14, 26, 17, 20, 28, 32, 40, 25, 10, 10, 6, 6}}, {genreName:"ヒップホップ/ ラップ", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {genreName:"エレクトロニック", playingList:{0, 1, 3, 0, 0, 0, 0, 1, 4, 13, 8, 13, 2, 19, 6, 13, 10, 16, 25, 7, 8, 0, 2, 10}}, {genreName:"アニメ", playingList:{7, 1, 0, 0, 7, 2, 0, 0, 0, 9, 23, 52, 17, 10, 17, 50, 49, 67, 54, 27, 12, 16, 23, 45}}, {genreName:"ポップ", playingList:{3, 0, 0, 0, 0, 0, 0, 3, 1, 6, 2, 9, 7, 0, 11, 7, 8, 10, 7, 5, 3, 1, 0, 1}}, {genreName:"歌謡曲", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 2, 4, 5, 5, 4, 6, 7, 7, 1, 0, 0, 0}}, {genreName:"ヒップホップ/ラップ", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}}, {genreName:"ダンス", playingList:{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0}}, {genreName:"R&B/ソウル", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {genreName:"チルドレン・ミュージック", playingList:{0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {genreName:"クラシック", playingList:{1, 1, 1, 1, 2, 4, 10, 1, 4, 3, 24, 16, 26, 1, 25, 23, 37, 40, 23, 7, 5, 8, 4, 5}}, {genreName:"ニューエイジ", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 0, 0, 0, 0}}, {genreName:"Pop", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}}, {genreName:"ヴォーカル", playingList:{0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 7, 0, 0, 1, 6, 1, 0, 3, 1, 0, 3, 0, 0, 0}}, {genreName:"ホリデー", playingList:{0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0}}, {genreName:"Folk", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}}, {genreName:"ジャズ", playingList:{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 16, 7, 3, 9, 0, 5, 10, 20, 10, 2, 1, 0, 0}}, {genreName:"インストゥルメンタル", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}}, {genreName:"オルタナティブ", playingList:{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 1, 0, 0, 6, 9, 0}}}

on genreNayoseAndUnify(aList as list, genreNayoseList as list)
  set gList to FlattenList(genreNayoseList) of me
  
  
set didProc to {}
  
  
set a2List to {}
  
  
repeat with i in aList
    set aGenre to genreName of i
    
    
if (aGenre is in gList) and (aGenre is not in didProc) then
      
      
repeat with ii in genreNayoseList
        set jj to contents of ii
        
        
if aGenre is in jj then
          copy jj to {g1, g2}
          
          
          
if chkAlphabet(g1) of me = true then
            set targG to g2
            
set targG2 to g1
          else
            set targG to g1
            
set targG2 to g2
          end if
          
          
set s1Res to searchByGenreName(aList, targG) of me
          
set s2Res to searchByGenreName(aList, targG2) of me
          
          
set s3Res to addMutipleLists({s1Res, s2Res}) of me
          
          
set outRec to {genreName:targG, playingList:s3Res}
          
set the end of didProc to g1
          
set the end of didProc to g2
          
          
exit repeat
        end if
        
      end repeat
      
      
set the end of a2List to outRec
    else
      if (aGenre is not in didProc) then
        set the end of a2List to contents of i
      end if
    end if
  end repeat
  
  
return a2List
end genreNayoseAndUnify

on searchByGenreName(aList as list, aGenreName as string)
  set predicatesStr to "genreName == ’" & aGenreName & "’"
  
set anArray to (NSArray’s arrayWithArray:aList)
  
set aPred to (NSPredicate’s predicateWithFormat:predicatesStr)
  
set bRes to (anArray’s filteredArrayUsingPredicate:aPred)
  
  
set bbRes to first item of bRes
  
return (playingList of bbRes) as list
end searchByGenreName

on addMutipleLists(s1List)
  script spdAdd
    property s1List : {}
    
property s3List : {}
  end script
  
  
copy s1List to (s1List of spdAdd) –init
  
  
set s1Len to length of first item of (s1List of spdAdd)
  
set (s3List of spdAdd) to makeZero1DList(s1Len, 0) of me
  
  
repeat with i in (s1List of spdAdd)
    set tmpLen to length of i
    
if tmpLen is not equal to s1Len then return false
    
    
repeat with ii from 1 to s1Len
      set tmp1 to contents of item ii of (s3List of spdAdd)
      
set tmp2 to contents of item ii of i
      
      
set item ii of (s3List of spdAdd) to (tmp1 + tmp2)
    end repeat
  end repeat
  
  
return (s3List of spdAdd)
end addMutipleLists

–指定要素を指定回数追加したリストを作成する
on makeZero1DList(itemMax, itemElem)
  set allData to {}
  
repeat itemMax times
    set the end of allData to itemElem
  end repeat
  
return allData
end makeZero1DList

–By Paul Berkowitz
–2009年1月27日 2:24:08:JST
–Re: Flattening Nested Lists
on FlattenList(aList)
  set oldDelims to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to {"????"}
  
set aString to aList as text
  
set aList to text items of aString
  
set AppleScript’s text item delimiters to oldDelims
  
return aList
end FlattenList

— アルファベットのみか調べて返す
on chkAlphabet(checkString)
  set aStr to NSString’s stringWithString:checkString
  
set allCharSet to NSMutableCharacterSet’s alloc()’s init()
  
allCharSet’s addCharactersInRange:(current application’s NSMakeRange(ASCII number of "a", 26))
  
allCharSet’s addCharactersInRange:(current application’s NSMakeRange(ASCII number of "A", 26))
  
set aBool to my chkCompareString:aStr baseString:allCharSet
  
return aBool as boolean
end chkAlphabet

on chkCompareString:checkString baseString:baseString
  set aScanner to NSScanner’s localizedScannerWithString:checkString
  
aScanner’s setCharactersToBeSkipped:(missing value)
  
aScanner’s scanCharactersFromSet:baseString intoString:(missing value)
  
return (aScanner’s isAtEnd()) as boolean
end chkCompareString:baseString:

★Click Here to Open This Script 

Posted in list Record | Tagged 10.13savvy 10.14savvy 10.15savvy NSArray NSMutableCharacterSet NSPredicate NSScanner NSString | 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%クラッシュするバグ
  • Script Debuggerの開発と販売が2025年に終了
  • AppleScript入門① AppleScriptってなんだろう?
  • macOS 14で変更になったOSバージョン取得APIの返り値
  • NSObjectのクラス名を取得 v2.1
  • macOS 15:スクリプトエディタのAppleScript用語辞書を確認できない
  • 有害ではなくなっていたSpaces
  • Xcode上のAppleScriptObjCのプログラムから、Xcodeのログ欄へのメッセージ出力を実行

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