macOS標準搭載の画像/PDFビューワーの「Preview.app」で表示中のPDFの、現在表示中のページの番号を取得するAppleScriptです。
本来、Preview.appのような超低機能アプリケーションから強引に情報を(GUI Scriptingまで使って)取得する意味はありません。PDFビューワーとしてまっとうな機能を持っているSkimを使って表示中のページ番号を取得するのが筋です。
ただ、どうしてもPreviewでないといけないケースで、仕方なく作ったものですが、英語環境でも日本語環境でも同様に動くために作ってみたらこんな感じに。指定アプリケーション単体で言語環境を指定して起動できると、各言語環境における動作確認が手軽に行えてよいと思うものの、手段がありそうで見つかりません(Xcode上でそういう起動ができるので、不可能ではないと思うのですが)。
仕方なくGUI Scripting経由でウィンドウのタイトルを取得して、ファイル名とページ情報を文字列処理で分離しています。このあたり、英語環境と日本語環境でセパレータ(括弧)が異なるので、分離したページ情報から数字判定を行なって取得しています。Preview.appのアプリケーションバンドル内にこうしたフォーマットのテキストが存在していれば、そちらを使うべきです(見つかっていないので現状こんな感じで)。
GUI Scripting内でプロセス名を指定する箇所で、ローカライズされたプロセス名をCocoaの機能を用いて取得しています。これで、英語環境と日本語環境については問題なく共通Scriptでカバーできています。
AppleScript名:Previewで現在表示中のPDFのページ番号を抽出する.scptd |
— – Created by: Takaaki Naganoya – Created on: 2020/04/29 — – Copyright © 2020 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use framework "AppKit" use scripting additions set pNum to retPreviewDispPageNumber() of me on retPreviewDispPageNumber() set aLocName to getLocalizedName("com.apple.Preview") of me tell application "Preview" if (count every document) = 0 then return false end tell tell application "System Events" tell process aLocName tell window 1 set aTitle to title end tell end tell end tell set aPageInfo to pickUpFromToStr(aTitle, "(", ")") of me –English env if aPageInfo = false then set aPageInfo to pickUpFromToStr(aTitle, "(", ")") of me –double witdh parenthesis (Japanese env) end if set pList to words of aPageInfo set hitF to false repeat with i in pList set nRes to chkNumeric(i) of me if nRes = true then set hitF to true exit repeat end if end repeat if hitF = false then return return i as integer end retPreviewDispPageNumber on getLocalizedName(aBundleID as string) set pRes to getProcessByBUndleID(aBundleID) of me if pRes = false then return "" set pName to pRes’s localizedName() return pName as string end getLocalizedName –指定プロセスを取得する on getProcessByBUndleID(aBundleID) set appArray to current application’s NSRunningApplication’s runningApplicationsWithBundleIdentifier:aBundleID if appArray’s |count|() > 0 then set appItem to appArray’s objectAtIndex:0 return appItem else return false end if end getProcessByBUndleID on pickUpFromToStr(aStr as string, s1Str as string, s2Str as string) set a1Offset to offset of s1Str in aStr if a1Offset = 0 then return false set bStr to text (a1Offset + (length of s1Str)) thru -1 of aStr set a2Offset to offset of s2Str in bStr if a2Offset = 0 then return false set cStr to text 1 thru (a2Offset – (length of s2Str)) of bStr return cStr as string end pickUpFromToStr –数字のみかチェック on chkNumeric(checkString) set digitCharSet to current application’s NSCharacterSet’s characterSetWithCharactersInString:"0123456789" set ret to my chkCompareString:checkString baseString:digitCharSet return ret as boolean end chkNumeric on chkCompareString:checkString baseString:baseString set aScanner to current application’s 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: |