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.11savvy

指定のiOSアプリからジャンル情報を取得

Posted on 6月 20, 2021 by Takaaki Naganoya

M1 Macで、Mac App StoreからインストールしたiOSアプリから、ジャンル情報を取得するAppleScriptです。

iOSアプリケーションでは、Info.plist内にジャンル情報が記載されておらず、バンドル内の別ファイルに記載されています。これを読み取ることで、ジャンル情報を取得できます。

なかなか素敵な機能なのですが、Xcode上のCocoa-AppleScriptアプリケーション内で実行すると、Sandboxの制限によりデータアクセスができません。


▲macOSのFinder上でiOSアプリのバンドル内部を表示させたところ。メタデータが添付されているのがわかる

ただし、Macのアプリケーションのジャンル情報と項目が異なっていたり、相互に存在しないジャンルなどもあるため、そのままMac上でも同様のジャンルであると判定することは避けたほうがよいでしょう。

AppleScript名:指定のiOSアプリからジャンル情報を取得.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2021/06/20
—
–  Copyright © 2021 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.7"
use scripting additions
use framework "Foundation"

set aFile to POSIX path of (choose file)
set gID to getGenreNumFromiOSApp(aFile) of me

on getGenreNumFromiOSApp(aPOSIX)
  set metaDataPOSIX to aPOSIX & "Wrapper/iTunesMetadata.plist"
  
set aRec to retDictFromPlist(metaDataPOSIX) of me
  
if aRec = missing value then return missing value
  
set aGenreID to genre of aRec
  
return aGenreID
end getGenreNumFromiOSApp

on retDictFromPlist(aPlistPath)
  set thePath to current application’s NSString’s stringWithString:aPlistPath
  
set thePath to thePath’s stringByExpandingTildeInPath()
  
set theDict to current application’s NSDictionary’s dictionaryWithContentsOfFile:thePath
  
if theDict = missing value then return missing value
  
return theDict as record
end retDictFromPlist

★Click Here to Open This Script 

(Visited 47 times, 1 visits today)
Posted in file iOS App System | Tagged 10.11savvy | Leave a comment

Wikipedia経由で2つの単語の共通要素を計算するcommon elements Lib Script Library

Posted on 2月 28, 2020 by Takaaki Naganoya

現在作成中のアプリケーションの副産物として生まれた「common elements Lib」AppleScript Libraryです。2つの単語の共通要素を計算して返します。

# v1.1にアップデートしました(ダウンロード先URLはかわらず)。ページ下部のテンプレート部分の余計なリンクを拾わないように改善したため、テンプレート部分のリンクが多い項目に対して大きな効果を発揮します

–> Download archive

アーカイブをダウンロードして展開し、~/Library/Script Librariesフォルダに「common elements Lib.scptd」を入れるとAppleScriptから呼び出せるようになります。

macOS 10.10以降で動作するはずですが、開発は10.14上で、動作確認は10.13/10.14/10/15上でのみ行なっています。

この、2つのキーワードの共通要素を求める処理は「マッキー演算」と呼んでおり、男性アイドルグループ「SMAP」と、男性シンガーソングライター「槇原敬之」(マッキー)氏の共通要素を演算で求めることを目的として企画されました。「SMAP」はWikipedia上でも最大級の要素数を持つ項目であり、1,400項目以上のリンク要素を擁しています。

Wikipedia REST APIの仕様ではリンク要素を500項目までしか一度に取得できません。SMAPを処理するためには、複数ページにまたがるリンク取得の処理をこなすことが必要であり、「マッキー演算」は言葉のバカっぽさとは裏腹に、それなりの技術力が要求される、そこそこむずかしい処理なのです。

本ライブラリを用いて、WikipeidaにREST API経由で検索司令を出すわけですが、英語のスペルの単語を受け付けるWikipediaもあれば、日本語やアラビア語Wikipediaなどのようにその言語向けの書き換えを行ったデータで検索するものもあり、割とまちまちであることがわかりました。そのあたりは、sdefに書いておいたサンプルScriptを見ていただくのがよいでしょう。

本ライブラリでは、演算対象とする単語はWikipediaに掲載されているものに限られています。実際に、日本語環境で「スティーブ・ジョブズ」と「ラリー・テスラー」の共通項目を計算すると、

--> {"パロアルト研究所", "Smalltalk", "アメリカ合衆国", "Lisa (コンピュータ)", "アップル・ニュートン", "Macintosh", "アップル (企業)", "Macworld", "スタンフォード大学"}

「スティーブ・ジョブズ」と「ロス・ペロー」の共通項目を計算すると、

--> {"NeXT", "アル・ゴア", "統合典拠ファイル", "実業家", "IBM", "ゼネラルモーターズ", "SNAC", "アメリカ合衆国", "国際標準名称識別子", "孫正義", "ソフトバンク", "国立国会図書館", "フランス国立図書館", "アメリカ議会図書館管理番号", "CiNii", "バーチャル国際典拠ファイル"}

のような結果を返してきます。

冒頭で述べた「SMAP」と「槇原敬之」の共通項目を計算すると、

--> {"スポーツニッポン", "ABO式血液型", "テレビ朝日", "東京都", "社長", "エフエム東京", "ミュージックステーション", "J-POP", "第42回NHK紅白歌合戦", "大阪城ホール", "日本", "We are SMAP!", "ミリオンセラー", "小倉博和", "インターネットアーカイブ", "日本武道館", "ニッポン放送", "リクルートホールディングス", "日刊スポーツ", "第58回NHK紅白歌合戦", "フジテレビジョン", "世界に一つだけの花"}

のようになります。

おおよその主要言語に対応していますが、ロシア語をはじめとするキリル文字の言語を指定すると、なぜか結果が返ってきません。これが、キリル文字のエンコーディングに関する(こちら側の実装がまずい)問題なのか、サーバー側がREST APIをサポートしていないのか(Wikipediaサーバー側の問題)はわかりません。
→ ロシア語のクエリーも処理できることを確認しました

ここでは、だいたいの「いい感じのキーワード」を例として出していますが「George Lucas」と「Steven Spielberg」などの近い単語を指定すると結果が400個以上返ってきます。
→ v1.1における改良により、400個以上のリンクを66個まで減少させました(不要なフッター部分のリンクを拾わないようにした)

膨大な項目から必要な要素を選択するInterfaceをみつくろってテストをしてはいるのですが、iOS上でよさそうに見えてもMac上で動かすといまひとつだったり、なかなか合うものが見つかりません(超多項目選択UI)。

–> Watch Demo

こうした計算結果をもっと減らす方法や、これらの多項目の計算結果からGUI上で項目選択する方法などが自分たちでは見つからなかったので、ライブラリとして公開して広く意見やアイデアを募ろうと考えました。多言語のWikipediaへの問い合わせを行ったり、問題点を洗い出すことも目的の1つです。前述のとおり、ロシア語系のWikipediaに対するアクセスに問題がある点については調査が必要です。

余談ですが、Steve JobsとLarry Teslerの関連項目演算を行おうとしても、Larry Teslerの項目がなかったり、Xerox PARCへのリンクがないために演算結果にこれが含まれない言語のWikipediaがいくつか見られました。コンピュータ史上重要な偉人への敬意をこめ、ぜひ追記していただきたいと考えるものです(という話を日本語で書いても意味がない?)。

AppleScript name:sample.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/02/28
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
— http://www.piyocast.com

use comLib : script "common elements Lib"

–English
set aWord to "Steve Jobs"
set bWord to "Larry Tesler"
set commonResEN to list up common elements with {aWord, bWord} with language "en"
–> {"The New York Times", "Computer History Museum", "Alan Kay", "International Standard Book Number", "California", "Steve Jobs", "Computer mouse", "John Markoff", "Ethernet", "Stanford University", "Counterculture of the 1960s", "Fortune (magazine)", "Tablet computer", "Apple Lisa", "Apple Inc.", "Associated Press", "Graphical user interface", "International Standard Serial Number", "Apple Computer", "Macintosh 128K", "Xerox Alto"}

–日本語(Japanese)
set aWord to "スティーブ・ジョブズ" –Steve Jobs
set bWord to "ラリー・テスラー" –Larry Tesler
set commonResJP to list up common elements with {aWord, bWord} with language "jp"
–> {"パロアルト研究所", "Smalltalk", "アメリカ合衆国", "Lisa (コンピュータ)", "アップル・ニュートン", "Macintosh", "アップル (企業)", "Macworld", "スタンフォード大学"}

–中文(Simplified Chinese)
set aWord to "史蒂夫·乔布斯" –Steve Jobs
set bWord to "拉里·泰斯勒" –Larry Tesler
set commonResZH to list up common elements with {aWord, bWord} with language "zh"
–> {"母校", "美國", "帕羅奧多研究中心"}

—한국어(Korean)
set aWord to "스티브 잡스" –Steve Jobs
set bWord to "빌 게이츠" –Bill Gates
set commonResKO to list up common elements with {aWord, bWord} with language "ko"
—> {"가상 국제 전거 파일", "위키인용집", "게마인자메 노름다타이", "네덜란드 왕립도서관", "국제 표준 도서 번호", "IBM", "SNAC", "CiNii", "개인용 컴퓨터", "BIBSYS", "영어", "국제 표준 명칭 식별자", "오스트레일리아 국립도서관", "LIBRIS", "체코 국립도서관", "미국", "스페인 국립도서관", "뮤직브레인즈", "프랑스 국립도서관", "이스라엘 국립도서관", "일본 국립국회도서관", "미국 의회도서관 제어 번호", "전거 통제", "국립중앙도서관", "WorldCat Identities", "실리콘 밸리의 신화", "프랑스 대학도서관 종합목록", "위키미디어 공용"}

–svenska
set aWord to "Steve Jobs"
set bWord to "Ross Perot"
set commonResSV to list up common elements with {aWord, bWord} with language "sv"
–> {"USA", "IBM", "Forbes", "Entreprenör", "Libris (bibliotekskatalog)"}

–Deutsch
set aWord to "Steve Jobs"
set bWord to "Larry Tesler"
set commonResDE to list up common elements with {aWord, bWord} with language "de"
–> {"Objektorientierte Programmierung", "Apple", "Apple Macintosh", "Xerox PARC", "Virtual International Authority File", "The New York Times", "Kalifornien", "Apple Lisa"}

–français
set aWord to "Steve Jobs"
set bWord to "Larry Tesler"
set commonResFR to list up common elements with {aWord, bWord} with language "fr"
–> {"The New York Times", "Palo Alto Research Center", "Informaticien", "Californie", "Apple", "États-Unis", "Autorité (sciences de l’information)"}

–Nederlands
set aWord to "Steve Jobs"
set bWord to "Larry Tesler"
set commonResNL to list up common elements with {aWord, bWord} with language "nl"
–> {"Verenigde Staten (hoofdbetekenis)", "Palo Alto Research Center", "Apple Macintosh", "Xerox", "Apple Inc.", "Apple Lisa", "Apple Newton"}

–italiano
set aWord to "Steve Jobs"
set bWord to "Larry Tesler"
set commonResIT to list up common elements with {aWord, bWord} with language "it"
–>{"Apple", "Stati Uniti d’America", "Xerox Palo Alto Research Center", "Informatico"}

–español
set aWord to "Steve Jobs"
set bWord to "Ross Perot"
set commonResES to list up common elements with {aWord, bWord} with language "es"
–> {"Emprendedor", "Library of Congress Control Number", "Wikidata", "IBM", "Enciclopedia Británica", "Wikimedia Commons", "Empresario", "CiNii", "National Diet Library", "Estados Unidos", "National Library of the Czech Republic", "Virtual International Authority File", "Bibliothèque nationale de France", "International Standard Name Identifier", "Integrated Authority File", "Système universitaire de documentation", "ISBN"}

–polski
set aWord to "Steve Jobs"
set bWord to "Larry Tesler"
set commonResPL to list up common elements with {aWord, bWord} with language "pl"
–> {"Apple Inc.", "Virtual International Authority File", "Xerox PARC"}

–Tiếng Việt
set aWord to "Steve Jobs"
set bWord to "Larry Tesler"
set commonResVI to list up common elements with {aWord, bWord} with language "vi"
–> {"Hoa Kỳ", "Apple Lisa", "California", "Apple Inc."}

–Arabic
set aWord to "ستيف جوبز"
set bWord to "روس بيرو"
set commonResAR to list up common elements with {aWord, bWord} with language "ar"
–> {"مكتبة البرلمان الوطني", "رقم الضبط في مكتبة الكونغرس", "رائد أعمال", "المكتبة الوطنية لجمهورية التشيك", "ملف استنادي متكامل", "ملف استنادي دولي افتراضي", "المكتبة الوطنية الفرنسية", "سايني", "ديل", "آي بي إم", "لغة إنجليزية", "ضبط استنادي", "حزب سياسي", "مهنة", "مدرسة أم", "واي باك مشين", "الولايات المتحدة", "المحدد المعياري الدولي للأسماء", "دولار أمريكي"}

–português
set aWord to "Steve Jobs"
set bWord to "Larry Tesler"
set commonResPT to list up common elements with {aWord, bWord} with language "pt"
–> {"Macintosh", "Alan Kay", "Apple Newton", "Povo dos Estados Unidos", "Língua inglesa", "Estados Unidos", "Ciência da computação", "Apple", "Califórnia", "Base Virtual Internacional de Autoridade"}

–Català
set aWord to "Steve Jobs"
set bWord to "Larry Tesler"
set commonResCA to list up common elements with {aWord, bWord} with language "ca"
–> {"Control d’autoritats", "Virtual International Authority File", "Apple Macintosh", "Apple Inc", "Interfície gràfica d’usuari"}

–Bahasa Indonesia
set aWord to "Steve Jobs"
set bWord to "Larry Tesler"
set commonResNO to list up common elements with {aWord, bWord} with language "id"
–> {"California", "Biografi", "Amerika Serikat"}

–magyar
set aWord to "Steve Jobs"
set bWord to "Larry Tesler"
set commonResHU to list up common elements with {aWord, bWord} with language "hu"
–> {"Amerikai Egyesült Államok", "Informatikus", "Wikimédia Commons", "Stanford Egyetem", "Nemzetközi Virtuális Katalógustár"}

–euskara
set aWord to "Steve Jobs"
set bWord to "Larry Tesler"
set commonResEU to list up common elements with {aWord, bWord} with language "eu"
–> {"Xerox", "Informatikari", "Ingeles", "Apple Inc.", "Ameriketako Estatu Batuak", "Wikidata", "Smalltalk", "Virtual International Authority File", "Stanford Unibertsitatea", "Wikimedia Commons"}

–Türkçe
set aWord to "Steve Jobs"
set bWord to "Larry Tesler"
set commonResTR to list up common elements with {aWord, bWord} with language "tr"
–> {"The New York Times", "Apple", "Amerika Birleşik Devletleri", "Kaliforniya"}

★Click Here to Open This Script 

AppleScript name:sample2
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/02/28
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
— http://www.piyocast.com

use comLib : script "common elements Lib"

set sList to supported lang codes
–> {"en", "ceb", "sv", "de", "fr", "nl", "ru", "it", "es", "pl", "war", "vi", "jp", "zh", "ar", "pt", "uk", "fa", "ca", "sr", "no", "id", "ko", "fi", "hu", "sh", "cs", "ro", "eu", "tr", "ms", "eo", "hy", "bg", "he", "da", "ce", "zh-min-nan", "sk", "kk", "min", "hr", "et", "lt", "be", "el", "azb", "sl", "gl", "az", "simple", "ur", "nn", "hi", "th", "ka", "uz", "la", "ta", "vo", "arz", "cy", "mk", "tg", "lv", "ast", "mg", "tt", "af", "oc", "bs", "bn", "ky", "sq", "zh-yue", "tl", "new", "te", "be-tarask", "br", "ml", "pms", "nds", "su", "ht", "lb", "jv", "sco", "mr", "sw", "pnb", "ga", "szl", "ba", "is", "my", "fy", "cv", "lmo", "an", "ne", "pa", "yo", "bar", "io", "gu", "wuu", "als", "ku", "scn", "kn", "ckb", "bpy", "ia", "qu", "mn", "bat-smg", "vec", "wa", "si", "or", "cdo", "gd", "yi", "am", "nap", "ilo", "bug", "xmf", "mai", "hsb", "map-bms", "fo", "diq", "mzn", "sd", "li", "eml", "sah", "nv", "os", "sa", "ps", "ace", "mrj", "frr", "zh-classical", "mhr"}

–"ru", "uk", "sh", "bg" seems not to work… "ms" or later codes seems not to work (depends on Wikipedia Server spec)….

★Click Here to Open This Script 

(Visited 98 times, 1 visits today)
Posted in Internet Language Natural Language Processing REST API Script Libraries sdef | Tagged 10.10savvy 10.11savvy 10.12savvy 10.13savvy 10.14savvy 10.15savvy | 1 Comment

画面上の指定座標にマウスカーソルを強制移動させてクリック

Posted on 8月 22, 2019 by Takaaki Naganoya

マウスカーソルを指定座標に強制的に移動させて、マウスクリック(プレス)を行う補助アプリケーション+呼び出しAppleScriptです。

# ご注意:マウスカーソルの移動やクリックを行うのは、本来のAppleScriptの処理ではありません
# ご注意:他のマシン上で同じ動作を再現することが(初心者には)難しいため、おすすめしません

# 本ツールはCodeSignしてMac App Storeで近日リリースする予定です

必要悪! 画面上の部品や座標をクリックする機能

マウスカーソルの強制移動とクリックは、AppleScriptではなるべく避けるべき操作ですが、ごく一部の操作を実行するため、ごくごくまれに必要になることがあります。

macOS標準装備のAppleScript専用のツール「System Events」に「click」コマンドがあり、指定のGUI部品か、あるいは画面上の座標をクリックするようになっています。

ただし、これはあくまで「指定のGUI部品や指定座標をクリックしたというメッセージ」を対象(アプリケーション)に送るというものであり、実際にマウスカーソルを移動させてクリックを実行するものではありません。

強制マウス操作ツールの歴史

それでも、アプリケーションがAppleScriptに対して機能を解放していない機能を呼び出す必要があって、かつ、メニューやボタンのクリックなどで実行できないような場合には、止むを得ず指定座標のクリックをごくまれに行うことがあります(1年に1度ぐらいの頻度)。


▲強制的にマウスカーソルを移動させてクリックする支援ツールの変遷

これまで、Framework呼び出しでこれらの動作を行ってきましたが、macOS 10.14で(SIPを解除しないかぎり)スクリプトエディタ上ではサードパーティのFrameworkを呼べなくなりました(AppleScriptドロップレット上ではバンドル内のFrameworkを呼べます)。

呼び出し側から一番簡単に利用できる方法は、指定座標のクリック機能を持つアプリケーションをXcode上でAppleScriptで作成しておき、sdefを定義して、AppleScript対応アプリケーションをAppleScriptで作るものです(豆腐をすりつぶして「ひろうす」を作るようなこの迂遠さ。Google翻訳で絶対に伝わらないニュアンス。パンをすりつぶしてパンを作るような、、、)。

そのため、いままでFrameworkで運用してきたプログラムを、アプリケーション化してsdefを付加し、スクリプタブルなバックグラウンドアプリケーション(Dockに表示されない、メニューやウィンドウが表示されない)にする必要が出てきます(まんまとAppleにタダ働きさせられているような気がするので気分はよくありませんが)。

自分ではほとんど使わないマウス強制移動&クリックツールを作ってみた

そこで、sdef(AppleScript用語辞書)をつけたライブラリやアプリケーションを作る方向で調査を行っていました。実際にパラメータの受け渡しをどのように行えるのか、どのあたりでハマるのか、どのぐらいの作業量になるのか。

その1つの到達点として、この補助アプリケーション「mouseClick」を作ってみました。バックグラウンド実行専用のため、起動してもDockにアイコンは表示されません(これを知らないユーザーがバックグラウンド起動専用のアプリケーションに、Mac App Sroreでいちゃもんをつけているのを見かけて、遠い目になりました)。

–> Download mouseClick.app (To /Applications)

※ このツールは、AppleScriptからコマンドで操作する専用のものであり、画面上には何も表示されません。

簡単なAppleScriptでマウスカーソルの移動とクリックを実行できます。初回実行時はシステム環境設定の「セキュリティとプライバシー」>「プライバシー」>「アクセシビリティ」でmouseClickに「コンピュータの制御を許可」しておく必要があります(管理者権限が必要、2回目以降は操作不要)。

forceClickでは、画面の左上を原点とした座標系を使用しています。

呼び出し側と実行側をすべてAppleScriptで組めるようになったわけで、Classic MacOS時代からこの手の「指定座標の強制クリック系ソリューション」を(止むを得ず)使ってきた身からするとなかなか感慨深いものがあります。

参考文献:
objective c 入門 CocoaアプリケーションにAppleScriptサポートを追加するにはどうすればよいですか?

AppleScript名:force click sample
tell application "mouseClick"
  force click at {4, 4} –click apple menu
end tell

★Click Here to Open This Script 

(Visited 1,787 times, 10 visits today)
Posted in GUI Scripting list | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy 10.15savvy | Leave a comment

checkboxLibをアップデート(3)sdefにサンプルドキュメントを入れる

Posted on 8月 15, 2019 by Takaaki Naganoya

AppleScript Libraries(共有ライブラリ。以下ASLと略)にsdef(Script辞書)をつけて、AppleScriptや他のOSA言語との間で共通して呼び出し可能なライブラリを書くシリーズの続きです。

単なるASLにsdefを付けて、各種OSA言語からの呼び出しに対応するようにしてみました。さらに、パラメータの省略や別表記のゆらぎを許容するようにしてみました。

総仕上げで、Script用語辞書の中にドキュメントをHTMLで表記し、サンプルScriptをワンクリックでスクリプトエディタに転送されるようにしてみましょう。

最近、AppleScript用語辞書の中に表や資料が記載されているものがあります。それらは、sdef中にdocumentationタグで書かれているものです。documentationタグ内にはhtmlタグが記載されており、この中にHTMLで書かれたコンテンツが格納されています(ただ漫然と文字列で書いてあるだけですけれども)。

ここに、applescript://リンクつきのサンプルが掲載されていることもあるのですが、なぜかApple純正アプリケーションではサンプルそのものが間違っていたりして驚かされます(動作確認ぐらいしようよ)。また、見た目がスクリプトエディタのデフォルト色分けそのままで美しくありません。

そこで、本Blog掲載時に使用しているHTML書き出しプログラムを使用して、applescript://リンクつきのサンプルを掲載してみましょう。

ずいぶん見やすくなりましたし、サンプルがすぐに試せるのはいいと思います。

これによってsdefのサイズが大きくなってしまいました(2–> 10 KB)。sdefはAppleScript記述・構文確認時のテンプレートとしても、実行時のデータとしても使われるので、サイズが大きくなるとこれをparseするのに余計な時間がかかるため、あまり大きくしたくないという開発側の事情もあります。


▲InDesign CCの巨大なAppleScript用語辞書。たぶん、Adobeはまともにメンテナンスできていない

巨大な用語辞書を持つアプリケーションでは、改行コードすら削除してサイズを小さくしようとしているぐらいであり、フレンドリーなドキュメントを内包することが唯一にして無二のソリューション「ではない」ことも知っておくべきでしょう(実行速度低下というデメリットもあるので)。

ただ、sdefから改行コードを削除してサイズを小さくするというのは、CPUの実行速度が遅かった頃のノウハウであり、いまでも本当にそれが必要なのかは疑問です。実際、Keynote、Pages、Numbersなど比較的あたらしめの(それほど機能が多くない)アプリケーションでは「まっとうに読める。改行つき、インデントつき」sdefが格納されています。

(Visited 112 times, 1 visits today)
Posted in sdef | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy | Leave a comment

checkboxLibをアップデート

Posted on 8月 13, 2019 by Takaaki Naganoya

昨日作ったAppleScriptライブラリ「checkboxLib」をアップデートしてみました。

–> Download checkboxLib_v2.scptd(To ~/Library/Script Libraries)

JXAからの呼び出しに対応(1)〜data typeの記述を正しく

昨日のバージョンは問題が見つかっていました。AppleScriptから呼び出す分には問題がなかったのですが、JXAから呼び出すとエラーになっていました。

sdef(AppleScript用語辞書)をつけたライブラリは、AppleScriptで記述しつつも従来のOSAXのような運用が可能で、とりわけ他のOSA言語からも使える共有モジュールとして運用できる点が重要です。

今日明日ですぐに必要になるわけではありませんが、AppleScriptで記述したライブラリにsdefさえ添付しておけば、JXA側からも呼び出せる共有モジュールとして運用できる「ことになっています」。それがOSA(Open Scripting Architecture)上でのAppleScript Librariesの設計思想です。

そのため、JXA側からの呼び出しもテストしていたのですが、なかなかお題目どおりには行かず、ちょっとMacScripter.netのBBSで相談して、対処を行ってみました。

sdefを書くにあたっては、既存のアプリケーションの膨大なsdefのストックがあるので、それを参考にしていました(たまに記述が間違っているものがあって困ります)。

その中で、データタイプにAppleScriptでしか利用できない「list」というタイプを指定していたのが問題でした。つまり、AppleScript側からの呼び出しだけで検証していては、AppleScriptからの呼び出し時だけ正常に動く「バグ」を抱えたままの状態である可能性を否定できません。他のOSA言語からの呼び出しも検証しておかないと、潜在バグのあぶり出しが行えません。

 <parameter name="with titles" type="list" code="COLL" description="Titles of every path"/>

これをShaneのアドバイスどおりに書き換えて、

 <parameter name="with titles" code="COLL" description="Titles of every checkbox">
      <type type="text" list="yes"/>
 </parameter>

と、修正。これで、JXA側からも呼び出せるようになりました。

AppleScript名:check box sample 4_e
— Created 2019-08-12 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use checkLib : script "checkboxLib"

set tList to {"Carrot", "Burdock", "Radish", "Apple", "Cabbage", "Lettuce", "Potato", "Garlic", "Komatsuna", "Bok choy", "Shiitake mushroom", "Hen of the Woods"}

set cRes to choose checkbox main message "Select Vegetables" sub message "Select vegetables you like" with columns 2 with titles tList checkbox type standard return type data

★Click Here to Open This Script 

JavaScript名:sample_jxa_4
// Created 2019-08-12 by Takaaki Naganoya
// 2019 Piyomaru Software
var app = Application.currentApplication()
app.includeStandardAdditions =
true
var alib = Library("checkboxLib")

var array = ["Carrot", "Burdock", "Radish", "Apple", "Cabbage", "Lettuce", "Potato", "Garlic", "komatsuna", "Bok choy", " Shiitake mushroom", "Hen of the Woods"]

alib.chooseCheckbox(
{
    mainMessage:"Select Vegetables",
    subMessage:
"Select vegetables you like",
    withColumns:
2,
    withTitles:array,
    checkboxType:
"standard",
    returnType:
"item number"
  }
)

★Click Here to Open This Script 

JXAからの呼び出しに対応(2)〜enumをそのまま処理しない

とりあえず予定していた機能は実現できたわけですが、sdefにenum(定数)を定義して使ってみたくなりました。パラメータをダイレクトパラメータ(文字列、数字など)のみで指定するだけは不満が出てきそうです。

かくして、「こんな感じかな?」と手探りでenumを定義してみたのですが、例によってAppleScript側ではエラーにならないのに、JXA側ではエラーになりました。

結局、ライブラリ側のパラメータ受信部分でenumをそのまま処理せず、いったん文字列に変換して処理するようにしてみました。

いずれも、AppleScript側だけだとエラーになりませんでしたが、JXA側からの呼び出しもできるようにしておけば、他のOSA言語やObjective-C/Swiftなどの言語からの呼び出し時にも問題が出ないことでしょう。現状でJXAの存在意義はその程度です。

JXAからのライブラリ呼び出しについては、現行バージョンでもパラメータの省略時にエラーが出るのですが、「パラメータの省略はできないもの」と割り切っても問題はなさそうです。

最終的にsdefは上記(↑)のようになりました。enumの宣言部分の書き方がこなれていなかったので、その部分を修正。このsdefをスクリプトエディタでレンダリングすると、このようになります。

■参考文献リンク
Technical Note TN2106 Scripting Interface Guidelines

(Visited 149 times, 1 visits today)
Posted in JXA OSA sdef | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy | 1 Comment

アイテム番号リストをもとに、ヒットしなかった項目を返す

Posted on 7月 31, 2019 by Takaaki Naganoya

アイテム番号の入ったリスト(配列変数)をもとに、ヒットしなかった項目を返すというAppleScriptです。

これは、なにがしかのデータとなにがしかの書類上に配置されたデータの照合を行って、存在が確認されなかったデータの一覧を作成するために作成したものです。

存在確認といえば、たいていは「存在していたデータそのもの、あるいはデータのアイテム番号一覧」といったものを出力するようになっています。そこに、「存在が確認できなかったデータの一覧が欲しい」という要望が出てくることも、だいたいは普通の出来事です。

ただ、この手の「言語化すると大したことはないが、実施に精神的な抵抗感をおぼえる処理」といいいますか、「後片付け的な処理」というのは、書くのが面倒で後回しになりがちなものでもあります。

事実、実際に書いてみたら、、、既存のサブルーチンの組み合わせで作りましたが、1日たって見直してみると何が書いてあるのかよく思い出せないレベルです(既存のサブルーチンの組み合わせが過ぎて、意味がわかりにくいのかも)。

AppleScript名:アイテム番号リストをもとに、ヒットしなかった項目を返す.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/07/29
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—

property NSArray : a reference to current application’s NSArray
property NSMutableSet : a reference to current application’s NSMutableSet
property NSMutableArray : a reference to current application’s NSMutableArray

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

set strList to {"Apple", "Book", "Cheeze", "Dictionary", "Escalgo", "Find", "Gorila", "hook", "ink", "jet"}
set hitIDList to {1, 2, 3, 4, 6}

set bList to getUnpickedContents(hitIDList, strList) of me
–> {"Escalgo", "Gorila", "hook", "ink", "jet"}

on getUnpickedContents(aList, strList)
  set aMax to length of strList
  
set bList to getSequentialNumList(aMax) of me
  
set cList to excludeTwoList(bList, aList) of me
  
  
set anArray to NSMutableArray’s arrayWithArray:(cList)
  
set dList to (anArray’s sortedArrayUsingSelector:"compare:") as list
  
  
set eList to retConListFromItemNumList(dList, strList) of me
  
return eList
end getUnpickedContents

–アイテム項目番号が入っているリストをもとに、中身が入っているリストから項目を取り出す
on retConListFromItemNumList(dList, strList)
  set outList to {}
  
repeat with i in dList
    set aTmp to item (contents of i) of strList
    
set the end of outList to aTmp
  end repeat
  
return outList
end retConListFromItemNumList

on excludeTwoList(aList, bList)
  set aArray to NSArray’s arrayWithArray:(aList)
  
set bArray to NSArray’s arrayWithArray:(bList)
  
  
set aSet to NSMutableSet’s alloc()’s initWithArray:aArray
  
set bSet to NSMutableSet’s alloc()’s initWithArray:bArray
  
  
aSet’s minusSet:bSet –補集合
  
set resList to aSet’s allObjects() as list
  
  
return resList
end excludeTwoList

on getSequentialNumList(aMax)
  set outList to {}
  
repeat with i from 1 to aMax
    set the end of outList to i
  end repeat
  
return outList
end getSequentialNumList

★Click Here to Open This Script 

(Visited 51 times, 1 visits today)
Posted in list | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy 10.15savvy NSArray NSMutableArray NSMutableSet | Leave a comment

メインScript側で宣言したglobal変数値をサブ側で使用する

Posted on 7月 25, 2019 by Takaaki Naganoya

バンドル形式のAppleScriptでは、バンドル内にAppleScript Libraryを入れて、Library側の機能を呼び出すことができます。呼び出される方のサブ側のAppleScript Libraryでメイン側で宣言した変数値を参照する基礎的な内容のAppleScriptです。

–> Download mainTest.scptd

基礎は大事なので、ちょっと怪しいと思ったら必要な部分だけ組み立てて動作確認を行っています。

冒頭で(暗黙のrunハンドラの前で)global宣言を行えば、サブ側でも同じ値にアクセスできることを確認しました。一度、巨大なプログラムでやらかしたことがあって、global変数はあまり使わないように自粛していたのですが、必要とあらば仕方ありません。


▲メイン側のAppleScript。バンドル形式のAppleScriptで、この中にサブのAppleScript Libraryを入れて呼び出す


▲メイン側のAppleScriptのバンドル内に、「EverythingToTextKit.scptd」(リストやレコードなどのデータなどすべてテキスト化するライブラリ)と、「sub1.scptd」(サブ側のScript)を格納している


▲サブ側のAppleScript。ただ単にメイン側と共有しているグローバル変数「aProp」の内容をテキスト化してダイアログ表示


▲メイン側のAppleScriptを実行すると、サブ側のルーチンを呼び出して実行

(Visited 146 times, 1 visits today)
Posted in How To | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy 10.15savvy | Leave a comment

recordの値をラベルを指定して変更

Posted on 7月 23, 2019 by Takaaki Naganoya

record型変数に対して、ラベルを指定して変更するAppleScriptです。各種データ型に対応しています。

AppleScriptの属性値ラベル付きデータであるrecord型変数は、さまざまな操作のための方法が(まっとうな手段では)存在せず、使いこなすためにはまっとうでない方法がよく使われてきました(動的にrecordを生成するAppleScriptのテキストを作成してrun scriptで実行するとか。提唱者本人が書いているので間違いない)。

特定のラベルを指定してデータを取り出したり、設定したりはできますが、ラベルを動的に生成して設定するようなことはできませんし、指定のラベルが存在するかどうかを確認する機能もありません(エラートラップを仕掛けて値の取り出しを確認するぐらい?)。

macOS 10.10で全面的にCocoaの機能が利用できるようになってからは、recordを操作するにはCocoaのオブジェクト(NSDictionary, NSMutableDictionary)に変換し、Cocoaの機能を使って加工することが一般的になってきました。

CocoaのNSDictionary/NSMutableDictionaryにはAppleScriptのGUIアプリケーションのオブジェクトは格納できませんが、アプリケーションのオブジェクトを扱わない用途には問題ありません。

本Scriptは、そんな中で(巨大なAppleScriptのプログラムを書く中で)些細なサブルーチンを整備する必要があったために書いたものです。こういう細かい部品を積み重ねていくと、いろいろと巨大な概念を積み上げていくのに便利なもので。

数値に足し算しかできないの? という指摘はあるかもしれませんが、そこはマイナスの数を指定することで引き算は実現できます。

もちろん、この処理はPure AppleScriptだけで書くこともできます。

set aRec to {columnAdr:2, rowAdr:2, tableName:"table1", sheetName:"Sheet1", docName:"numbTest", cellValue:"AAA"}
set tmpVal to aRec’s rowAdr
set tmpVal to tmpVal – 1
set aRec’s rowAdr to tmpVal

return aRec
–> {columnAdr:2, rowAdr:1, tableName:"table1", sheetName:"Sheet1", docName:"numbTest", cellValue:"AAA"}

★Click Here to Open This Script 

本ルーチン(↓)では、記述性を高め、取り出したり入れたりといった記述を省略することが目的です。

# 本ルーチンを実戦投入してみたら、意外と使えなかったというオチが(^ー^;;;

AppleScript名:recordの値をラベルを指定して変更.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/07/23
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set aRec to {columnAdr:2, rowAdr:2, tableName:"table1", sheetName:"Sheet1", docName:"numbTest", cellValue:{"AAA"}}

–Number
set bRes to changeRecByKeyAndOperator(aRec, "rowAdr", 2) of me
–> {rowAdr:4, docName:"numbTest", cellValue:"AAA", tableName:"table1", sheetName:"Sheet1", columnAdr:2}

–String
set cRes to changeRecByKeyAndOperator(aRec, "docName", ".numbers") of me
–> {rowAdr:2, docName:"numbTest.numbers", cellValue:"AAA", tableName:"table1", sheetName:"Sheet1", columnAdr:2}

–List
set dRes to changeRecByKeyAndOperator(aRec, "cellValue", {".numbers"}) of me
–> {rowAdr:2, docName:"numbTest", cellValue:{"AAA", ".numbers"}, tableName:"table1", sheetName:"Sheet1", columnAdr:2}

–Date (Date value is localized in each locale (This is Japanese locale format). Change Date format in your locale format. It depends on System Preferences > International)
set bRec to {columnAdr:2, rowAdr:2, theTime:date "2019年1月1日 火曜日 0:00:00", sheetName:"Sheet1", docName:"numbTest", cellValue:{"AAA"}}
set eRes to changeRecByKeyAndOperator(bRec, "theTime", 10) of me
–> {theTime:date "2019年1月1日 火曜日 0:00:10", rowAdr:2, docName:"numbTest", cellValue:{"AAA"}, sheetName:"Sheet1", columnAdr:2}

on changeRecByKeyAndOperator(aRec as record, aKey as string, aVal as {date, list, number, string})
  set aDict to current application’s NSMutableDictionary’s dictionaryWithDictionary:aRec
  
set tmpVal to aDict’s valueForKey:aKey
  
  
–指定キーの存在チェック。存在しない場合には元の値をそのまま返す
  
set tmpKeyList to (aDict’s allKeys()) as list
  
if aKey is not in tmpKeyList then return aRec
  
  
set tmpVal to tmpVal as {date, list, number, string}
  
set tmpClass to class of tmpVal
  
  
if tmpClass = integer then
    aDict’s setValue:(tmpVal + aVal) forKey:aKey
  else if tmpClass = string then
    aDict’s setValue:(tmpVal & aVal) forKey:aKey
  else if tmpClass = list then
    aDict’s setValue:(tmpVal & aVal) forKey:aKey
  else if tmpClass = date then
    aDict’s setValue:(tmpVal + aVal) forKey:aKey
  end if
  
  
return aDict as record
end changeRecByKeyAndOperator

★Click Here to Open This Script 

(Visited 199 times, 2 visits today)
Posted in Record | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy | Leave a comment

NumbersのColumn Adr(26進数)と10進数との相互変換

Posted on 7月 22, 2019 by Takaaki Naganoya

Numbersの表のカラムを表現するアドレス文字列(26進数)と数値の間のエンコーダーおよびデコーダーのAppleScriptです。

もともとは、Excel 2004/2008で採用されたカラムアドレス形式に対処するためのScriptでした。

Excel上のセルのアドレス(場所)を指し示す方法は、「R1C1」(行とカラムを数値指定)形式、あるいはAppleScriptの行オブジェクトとセルオブジェクトで指定する形式でした。

そこへ新たに「A1」形式……画面上で表記されている行、カラムと親和性の高い形式が採用されることになりました。当初は相互変換のための関数なども用意されていなかったと記憶しています(間違っていたらご指摘ください)。そのため、Scripterが自力でこのA1形式に対応する必要が出てきました。

そんな中、Excel書類にAppleScriptを埋め込んで実行するAppleScriptを開発。本ルーチンはそのScript開発のために作成したものです。

Excel 2008でVBAの処理系が外されてMac上のVBA的なマクロ処理はAppleSctiptに一本化されるという話になっていたため(当時の話)、これを好機ととらえ、マイクロソフトのご担当にデモして、US本社で紹介していただくということになりました。

ただ、その会議上でVBAの復活プランが発表され、自分の提案したプランは廃案に(まさか当時のREALbasicのコンパイラの開発者を引き抜いてきてVBAの処理系をスクラッチで書かせるとは思いませんでしたわー)。

その後は、Excel 2011でVBAの処理系が復活。本ルーチンも割とHDDの肥やしとして絶賛在庫状態になっておりました。ごくたまーに、このExcel 2011でVBAの処理系が復活したことを知らない方がいて、「VBAで動いているマクロをAppleScriptに移植してほしい」という問い合わせがあるのですが、「Excelの最新版を購入してください。VBAがありますよ」とお返事しています。最新のExcelが動く環境を購入する費用よりも安く仕事としてお受けすることは困難なので。

そこから年月が流れ、AppleがNumbersをリリース。そのカラム表記がExcel 2004/2008と同じ形式になっているために、しまいこんでいたルーチンをふたたび引っ張り出してきた次第です。

一応、条件つきで使えるものの、作りが古い(やっつけ仕事な)点が気になります。きっと、誰かがもっといいルーチンを作って使っているに違いありません。一応、本ルーチンでは1〜1351の範囲での動作を確認しています。

もう少し改良したいところではあります。実用上は、Numbersでそこまで大きなデータは扱わない(はず)ので、問題はあまりないものと思われます。

AppleScript名:NumbersのColumn Adr(26進数)と10進数との相互変換
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/07/21
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

property NSString : a reference to current application’s NSString
property NSArray : a reference to current application’s NSArray
property NSRegularExpressionSearch : a reference to current application’s NSRegularExpressionSearch

repeat with i from 1 to 1351
  set a to numAdrToColumnEncode(i) of me
  
set b to colAddrToNumDecode(a) of me
  
set aRes to (i = b) as boolean
  
log {i, b, a, aRes}
  
if aRes = false then display dialog i as string
end repeat

–10進数数値をExcel 2004/2008的カラム表現にエンコードするサブルーチン(エンコード範囲:1〜1351)
on numAdrToColumnEncode(origNum)
  if origNum > 1351 then
    error "エラー:Numbersのカラム表現(A1形式)への変換ルーチンにおいて、想定範囲外(1351以上)のパラメータが指定されました"
  end if
  
  
set upperDigitEncTable to {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "A"}
  
set lowerDigitEncTable to {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "A"}
  
  
set oNum to origNum
  
set nTh to 26
  
set stringLength to 4
  
  
–数字が1桁の場合の対応
  
if origNum < 27 then
    set aRes to (item origNum of upperDigitEncTable) as string
    
return aRes
  end if
  
  
  
if origNum > 702 then
    –3桁になる場合
    
set upupNum to oNum div 676 –整数除算–上の上の桁
    
set oNum to oNum – (upupNum * 676)
    
set upNum to oNum div 26 –整数除算–上の桁
    
set lowNum to oNum mod 26 – 1 –余剰計算–下の桁
    
    
–log {origNum, upupNum, upNum, lowNum}
    
    
–超つじつま合わせルーチン【強引】
    
if lowNum = -1 then
      set upNum to upNum – 1
      
set lowNum to 25
    end if
    
    
set upupChar to (item upupNum of upperDigitEncTable) as string
    
set upChar to (item upNum of upperDigitEncTable) as string
    
set lowChar to (item (lowNum + 1) of lowerDigitEncTable) as string
    
set resText to upupChar & upChar & lowChar
    
  else
    –2桁の場合
    
set upNum to oNum div 26 –整数除算–上の桁
    
set lowNum to oNum mod 26 – 1 –余剰計算–下の桁
    
    
    
–超つじつま合わせルーチン【強引】
    
if lowNum = -1 then
      set upNum to upNum – 1
      
set lowNum to 25
    end if
    
    
set upChar to (item upNum of upperDigitEncTable) as string
    
set lowChar to (item (lowNum + 1) of lowerDigitEncTable) as string
    
set resText to upChar & lowChar
    
  end if
  
  
return resText
  
end numAdrToColumnEncode

–Numbersの横方向アドレス(A〜Zの26進数)文字列を10進数に変換
on colAddrToNumDecode(origStr)
  return aNthToDecimal(origStr, {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}) of me
end colAddrToNumDecode

–n進数文字列を10進数に変換する
on aNthToDecimal(origStr, nTh)
  set resNumber to 0
  
  
set sList to reverse of (characters of origStr)
  
set aLen to length of nTh
  
set digitCount to 0
  
  
repeat with i in sList
    set j to contents of i
    
set aRes to offsetInList(j, nTh) of me
    
    
set resNumber to resNumber + (aLen ^ digitCount) * aRes
    
    
set digitCount to digitCount + 1
  end repeat
  
  
return resNumber as integer
end aNthToDecimal

on offsetInList(aChar, aList)
  set anArray to NSArray’s arrayWithArray:aList
  
set aInd to (anArray’s indexOfObject:aChar)
  
if aInd = current application’s NSNotFound or (aInd as number) > 9.99999999E+8 then
    error "Invalid Character Error"
  else
    return (aInd as integer) + 1 –0 to 1 based index conversion
  end if
end offsetInList

★Click Here to Open This Script 

(Visited 236 times, 1 visits today)
Posted in list Number | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSArray NSRegularExpressionSearch NSString Numbers | Leave a comment

TeamViewerの「リモートコントロール」画面からIDとパスワードを取得(v14対応)

Posted on 7月 15, 2019 by Takaaki Naganoya

リモート操作ソフト「TeamViewer」の画面から、ユーザーIDとパスワードを取得するAppleScriptです。


▲TeamViewer v14をmacOS 10.12(左)、10.14(右)で起動したところ

GUI Scriptingの機能を使って、画面上から情報を取得し、正規表現で抽出してみました。

TeamViewerで実家のMacなど、離れた場所にあるマシンをメンテナンスする必要がある場合に、実家から電話がかかってきて、TeamViewerのパスワードとIDを口頭で教えてもらって接続する必要があるわけですが、親が高齢のためそれが心もとなくなりつつある昨今、確実に確認するために作成したものです。

その場で、(自分のために)「TeamViewerを起動してIDとパスを確認して自分あてにメールで送ってくるAppleScript」を作りかけたのですが、途中からビデオ編集の仕方を教えろなどと言われて説明する羽目に。

AppleScript名:TeamViewerの「リモートコントロール」画面からIDとパスワードを取得(v14対応)
【コメント】 ?
— Created 2019-07-15 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

property NSArray : a reference to current application’s NSArray
property NSPredicate : a reference to current application’s NSPredicate
property NSMutableArray : a reference to current application’s NSMutableArray

set aRes to getIDAndPassFromTeamViewer() of me
–> {myID:"XXX XXX XXX", myPass:"xxXxXX"}

–TeamViewerの「リモートコントロール」画面からIDとパスワードを取得(v14対応)
on getIDAndPassFromTeamViewer()
  –画面の表示状態を変更
  
selectRemoteControlRowOnTV("リモートコントロール") of me
  
  
–画面(Window)上のテキストをとりあえず全部取得
  
set sList to retEveryStaticTextInCurrentView() of me
  
  
set anArray to NSArray’s arrayWithArray:sList
  
  
–「使用中のID」を取得
  
set aPred to NSPredicate’s predicateWithFormat:"SELF MATCHES ’[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}’"
  
set bRes to (anArray’s filteredArrayUsingPredicate:aPred) as list
  
set idRes to contents of first item of bRes
  
–> "XXX XXX XXX"
  
  
set bList to removeItemFromList(sList, idRes) of me
  
set bArray to NSArray’s arrayWithArray:bList
  
set bPred to NSPredicate’s predicateWithFormat:"SELF MATCHES ’^[0-9a-zA-Z]+$’"
  
set cRes to (bArray’s filteredArrayUsingPredicate:bPred) as list
  
set psRes to contents of first item of cRes
  
–> "xxXxXX"
  
  
return {myID:idRes, myPass:psRes}
end getIDAndPassFromTeamViewer

on retEveryStaticTextInCurrentView()
  activate application "TeamViewer"
  
tell application "System Events"
    tell process "TeamViewer"
      tell window 1
        tell group 2
          set sList to value of every static text
          
–> {"接続準備完了(安全な接続)", "パートナーID", "リモートコンピュータの操作", "遠隔操作を受ける許可", "使用中のID", "999 999 999", "パスワード", "xxx999", "無人アクセス"}
          
return sList
        end tell
      end tell
    end tell
  end tell
end retEveryStaticTextInCurrentView

–TeamViewerで「リモートコントロール」行を選択
on selectRemoteControlRowOnTV(aTargStr)
  activate application "TeamViewer"
  
tell application "System Events"
    tell process "TeamViewer"
      tell table 1 of scroll area 1 of window 1
        set rCount to count every row
        
        
repeat with i from 1 to rCount
          tell row i
            tell UI element 1
              set aText to value of static text 1
            end tell
            
            
if aText = aTargStr then
              set selected to true
            end if
          end tell
        end repeat
        
      end tell
    end tell
  end tell
end selectRemoteControlRowOnTV

–1次元配列から指定の内容の要素をすべて削除して返す
on removeItemFromList(aTargList, aTargValue)
  set anArray to NSMutableArray’s arrayWithArray:aTargList
  
repeat
    set aInd to anArray’s indexOfObject:aTargValue
    
if aInd = current application’s NSNotFound or (aInd as real > 9.99999999E+8) then exit repeat
    
anArray’s removeObjectAtIndex:aInd
  end repeat
  
return anArray as list
end removeItemFromList

★Click Here to Open This Script 

(Visited 82 times, 1 visits today)
Posted in GUI Scripting regexp | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSArray NSMutableArray NSPredicate TeamViewer | Leave a comment

アラートダイアログ上にTable Viewを表示 v4

Posted on 7月 11, 2019 by Takaaki Naganoya

アラートダイアログ上にTable Viewを表示するAppleScriptです。

データを表UIで表示する部品としては、Shane Stanleyの「Myriad Tables Lib」が定番ですが、高機能なぶんライブラリ中にFrameworkが含まれていたりして、場合によっては困ることもあります。また、見た目をカスタマイズしたい場合にも、あまりいじくれなくて困ることもあります(とくにデータの文字サイズを変更できなくて困ること多し)。

そのため、AppleScriptだけで書いた表UI表示用の部品も、たまに必要になることがあります。


▲スクリプトエディタで実行@macOS 10.14.5(左:Light Mode、右:Dark Mode)


▲Script Debuggerで実行@macOS 10.14.5(左:Light Mode、右:Dark Mode)


▲AppleScriptアプレットで実行@macOS 10.14.5(左:Light Mode、右:Dark Mode)

AppleScript名:アラートダイアログ上にTable Viewを表示 v4
— Created 2019-02-21 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property NSAlert : a reference to current application’s NSAlert
property NSColor : a reference to current application’s NSColor
property NSIndexSet : a reference to current application’s NSIndexSet
property NSScrollView : a reference to current application’s NSScrollView
property NSTableView : a reference to current application’s NSTableView
property NSTableColumn : a reference to current application’s NSTableColumn
property NSMutableArray : a reference to current application’s NSMutableArray
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSModalPanelWindowLevel : a reference to current application’s NSModalPanelWindowLevel
property NSAlertSecondButtonReturn : a reference to current application’s NSAlertSecondButtonReturn

property theResult : 0
property returnCode : 0
property theDataSource : {}

on run
  set (my theResult) to 0 –initialize
  
  
set paramObj to {myMessage:"項目の選択", mySubMessage:"適切なものを以下からえらんでください", aTableList:{{field1:"MacBook Air", field2:"119,800円", field3:"1.6GHzデュアルコアIntel Core i5(Turbo Boost使用時最大3.6GHz)、4MB L3キャッシュ"}, {field1:"MacBook Pro 13", field2:"139,800円", field3:"1.4GHzクアッドコアIntel Core i5(Turbo Boost使用時最大3.9GHz)、128MB eDRAM"}, {field1:"MacBook Pro 15", field2:"258,800円", field3:"2.6GHz 6コアIntel Core i7(Turbo Boost使用時最大4.5GHz)、12MB共有L3キャッシュ"}, {field1:"Mac mini", field2:"122,800円", field3:"3.0GHz 6コアIntel Core i5 Turbo Boost使用時最大4.1GHz 9MB共有L3キャッシュ"}, {field1:"iMac 21.5", field2:"120,800円", field3:"2.3GHzデュアルコアIntel Core i5(Turbo Boost使用時最大3.6GHz)"}, {field1:"iMac 4K 21.5", field2:"142,800円", field3:"3.6GHzクアッドコアIntel Core i3"}, {field1:"iMac 5K 27", field2:"198,800円", field3:"3.0GHz 6コア Intel Core i5(Turbo Boost使用時最大4.1GHz)"}, {field1:"iMac Pro", field2:"558,800円", field3:"3.2GHz Intel Xeon W Turbo Boost使用時最大4.2GHz 19MBキャッシュ"}}, aSortOrder:{"field1", "field2", "field3"}}
  
  
–my chooseItemByTableView:paramObj–for debug
  
my performSelectorOnMainThread:"chooseItemByTableView:" withObject:paramObj waitUntilDone:true
  
return (my theResult)
end run

on chooseItemByTableView:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set aTList to (aTableList of paramObj) as list
  
set labelSortList to (aSortOrder of paramObj) as list
  
  
set aWidth to 600
  
set aHeight to 200
  
  
set aScroll to makeTableView(aTList, aWidth, aHeight, labelSortList) of me
  
  
–Detect Dark Mode
  
set dMode to retLIghtOrDark() of me
  
if dMode = true then
    set tvCol to 1
    
set tvAlpha to 0.8
    
set bCol to 0.1
    
set bAlpha to 0.8
    
set contentCol to (NSColor’s cyanColor())
  else
    set tvCol to 0
    
set tvAlpha to 0.1
    
set bCol to 1
    
set bAlpha to 0.8
    
set contentCol to (NSColor’s blackColor())
  end if
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:aScroll
    
    
set myWindow to its |window|
  end tell
  
  
myWindow’s setOpaque:(false)
  
myWindow’s setBackgroundColor:(NSColor’s colorWithCalibratedWhite:(bCol) alpha:(bAlpha))
  
myWindow’s setLevel:(NSModalPanelWindowLevel)
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
if (my returnCode) = 1001 then error number -128
  
  
set (my theResult) to (aScroll’s documentView’s selectedRow()) + 1
end chooseItemByTableView:

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

–TableView Event Handlers
on numberOfRowsInTableView:aView
  return my theDataSource’s |count|()
end numberOfRowsInTableView:

on tableView:aView objectValueForTableColumn:aColumn row:aRow
  set aRec to (my theDataSource)’s objectAtIndex:(aRow as number)
  
set aTitle to (aColumn’s headerCell()’s title()) as string
  
set aRes to (aRec’s valueForKey:aTitle)
  
return aRes
end tableView:objectValueForTableColumn:row:

on makeTableView(aDicList, aWidth, aHeight, labelSortList)
  set aOffset to 40
  
set theDataSource to current application’s NSMutableArray’s alloc()’s init()
  
theDataSource’s addObjectsFromArray:aDicList
  
  
set aScroll to current application’s NSScrollView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, aOffset, aWidth, aHeight))
  
set aView to current application’s NSTableView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, aOffset, aWidth, aHeight))
  
  
set aLen to length of labelSortList
  
  
repeat with i in labelSortList
    set j to contents of i
    
set aColumn to (current application’s NSTableColumn’s alloc()’s initWithIdentifier:j)
    (
aColumn’s setWidth:(aWidth div aLen))
    (
aColumn’s headerCell()’s setStringValue:j)
    (
aView’s addTableColumn:aColumn)
  end repeat
  
  
aView’s setDelegate:me
  
aView’s setDataSource:me
  
aView’s reloadData()
  
  
aScroll’s setDocumentView:aView
  
aView’s enclosingScrollView()’s setHasVerticalScroller:true
  
aScroll’s setVerticalLineScroll:(30.0 as real)
  
  
–1行目を選択
  
set aIndexSet to current application’s NSIndexSet’s indexSetWithIndex:0
  
aView’s selectRowIndexes:aIndexSet byExtendingSelection:false
  
  
–強制的にトップにスクロール
  
set aDBounds to aScroll’s documentView()’s |bounds|()
  
if class of aDBounds = list then
    –macOS 10.13 or later
    
set maxHeight to item 2 of item 1 of aDBounds
  else
    –macOS 10.10….10.12
    
set maxHeight to height of |size| of aDBounds
  end if
  
  
set aPT to current application’s NSMakePoint(0.0, -1 * (maxHeight as real))
  
aScroll’s documentView()’s scrollPoint:aPT
  
  
return aScroll
end makeTableView

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

–ダークモードの判定。ダークモード時:true、ライトモード時:falseが返る。System Eventsを使っていないのは、macOS 10.14以降対策(承認を取得しなくてもいいように)
on retLIghtOrDark()
  set curMode to (current application’s NSUserDefaults’s standardUserDefaults()’s stringForKey:"AppleInterfaceStyle") as string
  
return (curMode = "Dark") as boolean
end retLIghtOrDark

★Click Here to Open This Script 

(Visited 69 times, 1 visits today)
Posted in Color GUI list Record | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSAlert NSAlertSecondButtonReturn NSColor NSIndexSet NSModalPanelWindowLevel NSMutableArray NSRunningApplication NSScrollView NSTableColumn NSTableView | 1 Comment

指定画像をPNG形式(グレースケール)で保存

Posted on 7月 9, 2019 by Takaaki Naganoya

指定の画像ファイルをグレースケールのPNG画像ファイルに変換するAppleScriptです。

Appleが配布しているMNISTの手書き数字画像の認識CoreMLモデルをCocoa Framework化してみたところ、グレースケールの画像を要求されたため、画像をグレースケール化するルーチンを作ってみました。

結局、MNISTの手書き画像認識はうまく行かなかったのですが(全部「0」が返ってくる、、、)、グレースケール変換ルーチンは実用的だったので載せておくことにしました。

AppleScript名:指定画像をPNG形式(グレースケール)で保存
— 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 NSUUID : a reference to current application’s NSUUID
property NSString : a reference to current application’s NSString
property NSImage : a reference to current application’s NSImage
property NSColorSpace : a reference to current application’s NSColorSpace
property NSPNGFileType : a reference to current application’s NSPNGFileType
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 fRes to retUUIDfilePath(aFile, "png") of me
set sRes to saveNSImageAtPathAsGreyPNG(aImage, fRes) of me

–指定ファイルパスを元にUUIDのファイル名、指定拡張子をつけたファイルパスを作成して返す
on retUUIDfilePath(aPath, aEXT)
  set aUUIDstr to (NSUUID’s UUID()’s UUIDString()) as string
  
set aPath to ((NSString’s stringWithString:aPath)’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:aEXT
  
return aPath
end retUUIDfilePath

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsGreyPNG(anImage, outPath)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to NSBitmapImageRep’s imageRepWithData:imageRep
  
  
–ビットマップをグレースケール変換
  
set bRawimg to convBitMapToDeviceGrey(aRawimg) of me
  
  
set pathString to NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
  
set myNewImageData to (bRawimg’s representationUsingType:(NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –true/false
end saveNSImageAtPathAsGreyPNG

–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 

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 NSUUID : a reference to current application’s NSUUID
property NSString : a reference to current application’s NSString
property NSImage : a reference to current application’s NSImage
property NSColorSpace : a reference to current application’s NSColorSpace
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep
property NSColorRenderingIntentDefault : a reference to current application’s NSColorRenderingIntentDefault

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

set nsImageRes to convNSImageAsGrey(aImage) of me

–NSImageをグレースケールに変換する(NSImageで入出力)
on convNSImageAsGrey(anImage)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to NSBitmapImageRep’s imageRepWithData:imageRep
  
set aSpace to NSColorSpace’s deviceGrayColorSpace()
  
set bRawimg to aRawimg’s bitmapImageRepByConvertingToColorSpace:aSpace renderingIntent:(NSColorRenderingIntentDefault)
  
set outImage to NSImage’s alloc()’s initWithSize:(bRawimg’s |size|())
  
outImage’s addRepresentation:(bRawimg)
  
return outImage
end convNSImageAsGrey

★Click Here to Open This Script 

(Visited 111 times, 1 visits today)
Posted in Color file File path Image | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSBitmapImageRep NSColorRenderingIntentPerceptual NSColorSpace NSImage NSPNGFileType NSString NSUUID | Leave a comment

アラートダイアログ上にTexViewを表示_ヘルプ付き_半透明

Posted on 7月 8, 2019 by Takaaki Naganoya

アラートダイアログ上にTextViewを表示して、指定のテキストを閲覧するAppleScriptです。

# 前バージョンの「自分のソースコード」表示というのは意味不明だったので、プロセス一覧を取得してみました

ヘルプボタン(?)を付け、アラートダイアログのウィンドウ背景を半透明に設定。そのままでは配色の都合上Dark Mode/Light Modeの切り替え時に読みづらい文字なども出てきたため、モード判定を行って表示色などを変更しています。

アプレット書き出ししたときに、スクロールビューがマウスのスクロールホイールの操作に追従したスクロールを行ってくれないので、そのあたり何か追加でNSScrollViewに設定を行う必要があるのだろうかと。


▲スクリプトエディタ上で実行@macOS 10.14.5。左がLight Mode、右がDark Mode(以下同様)


▲ヘルプボタンをクリックしたところ。本当にアンカーを指定して指定のヘルプコンテンツを表示させることもできる模様。そのための基礎的な試験


▲AppleScriptアプレット書き出しして実行したところ


▲Script Debugger上で実行@macOS 10.14.5。Dark Modeに対応できていない(次バージョンで対応することでしょう)


▲Script DebuggerからAppleScript Applet (Enhanced)で書き出して実行したところ。マウスのスクロールホイールの操作を受け付けて文字がスクロールする

AppleScript名:アラートダイアログ上にTexViewを表示_ヘルプ付き_半透明
— Created 2019-07-08 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property |NSURL| : a reference to current application’s |NSURL|
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 NSTextView : a reference to current application’s NSTextView
property NSScrollView : a reference to current application’s NSScrollView
property NSRunningApplication : a reference to current application’s NSRunningApplication

property returnCode : 0

–Get Self Source Code (a kind of joke)
set asStr to do shell script "ps -ax"
set paramObj to {myMessage:"Main Message", mySubMessage:"Sub information", mes1:(asStr), mesWidth:400, mesHeight:200, fontName:"HiraginoSans-W3", fontSize:11.0}

–my dispTextViewWithAlertdialog:paramObj–for debug
my performSelectorOnMainThread:"dispTextViewWithAlertdialog:" withObject:paramObj waitUntilDone:true

on dispTextViewWithAlertdialog:paramObj
  –Receive Parameters
  
set aMainMes to (myMessage of paramObj) as string –Main Message
  
set aSubMes to (mySubMessage of paramObj) as string –Sub Message
  
set mesStr to (mes1 of paramObj) as string –Text Input field 1 Label
  
set aWidth to (mesWidth of paramObj) as integer –TextView width
  
set aHeight to (mesHeight of paramObj) as integer –TextView height
  
set aFontName to (fontName of paramObj) as string –TextView font name
  
set aFontSize to (fontSize of paramObj) as real –TextView font size
  
  
–Detect Dark Mode
  
set dMode to retLIghtOrDark() of me
  
if dMode = true then
    set tvCol to 1
    
set tvAlpha to 0.8
    
set bCol to 0.1
    
set bAlpha to 0.8
  else
    set tvCol to 1
    
set tvAlpha to 1.0
    
set bCol to 1
    
set bAlpha to 0.7
  end if
  
  
— Create a TextView with Scroll View
  
set aScroll to NSScrollView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))
  
set aView to NSTextView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))
  
aView’s setRichText:true
  
aView’s useAllLigatures:true
  
aView’s setTextColor:(NSColor’s cyanColor()) –cyanColor
  
aView’s setFont:(NSFont’s fontWithName:aFontName |size|:aFontSize)
  
set aColor to NSColor’s colorWithDeviceRed:0.0 green:0.0 blue:0.0 alpha:(tvAlpha)
  
aView’s setBackgroundColor:aColor
  
aView’s setOpaque:(false)
  
aView’s setString:mesStr
  
aScroll’s setDocumentView:aView
  
aView’s enclosingScrollView()’s setHasVerticalScroller: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:(aScroll)
    
    
–for Help Button
    
its setShowsHelp:(true)
    
its setDelegate:(me)
    
    
set myWindow to its |window|
  end tell
  
  
myWindow’s setOpaque:(false)
  
myWindow’s setBackgroundColor:(NSColor’s colorWithCalibratedWhite:(bCol) alpha:(bAlpha))
  
  
— 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
end dispTextViewWithAlertdialog:

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:

–ダークモードの判定。ダークモード時:true、ライトモード時:falseが返る
on retLIghtOrDark()
  set curMode to (current application’s NSUserDefaults’s standardUserDefaults()’s stringForKey:"AppleInterfaceStyle") as string
  
return (curMode = "Dark") as boolean
end retLIghtOrDark

★Click Here to Open This Script 

(Visited 73 times, 1 visits today)
Posted in Color dialog GUI | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSAlert NSColor NSFont NSRunningApplication NSScrollView NSTextView NSURL NSView | Leave a comment

アラートダイアログ上にTextViewを表示

Posted on 7月 8, 2019 by Takaaki Naganoya

アラートダイアログ上にTextViewを表示して、指定のテキストを閲覧するAppleScriptです。

とくにこれといって何か表示するものを思いつかなかったので、自分自身のソースコードを取得して表示しています。スクリプトエディタやScript Debugger上で実行した場合には自分自身のソースコードをテキストビュー上で表示します。

読み取り専用のスクリプトやアプレットで実行している場合にはソースコードを取得できません。何か適宜自分で表示させたいテキストを与えてみてください。

AppleScript名:アラートダイアログ上にTexViewを表示
— Created 2019-07-02 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "OSAKit"

property |NSURL| : a reference to current application’s |NSURL|
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 NSTextView : a reference to current application’s NSTextView
property NSScrollView : a reference to current application’s NSScrollView
property NSRunningApplication : a reference to current application’s NSRunningApplication
property OSAScript : a reference to current application’s OSAScript

property returnCode : 0

–Get Self Source Code (a kind of joke)
set mePath to path to me
set asStr to getASsourceFor(mePath) of me

set paramObj to {myMessage:"Main Message", mySubMessage:"Sub information", mes1:(asStr), mesWidth:400, mesHeight:200, fontName:"HiraginoSans-W3", fontSize:11.0}

–my dispTextViewWithAlertdialog:paramObj–for debug
my performSelectorOnMainThread:"dispTextViewWithAlertdialog:" withObject:paramObj waitUntilDone:true

on dispTextViewWithAlertdialog:paramObj
  –Receive Parameters
  
set aMainMes to (myMessage of paramObj) as string –Main Message
  
set aSubMes to (mySubMessage of paramObj) as string –Sub Message
  
set mesStr to (mes1 of paramObj) as string –Text Input field 1 Label
  
set aWidth to (mesWidth of paramObj) as integer –TextView width
  
set aHeight to (mesHeight of paramObj) as integer –TextView height
  
set aFontName to (fontName of paramObj) as string –TextView font name
  
set aFontSize to (fontSize of paramObj) as real –TextView font size
  
  
— Create a TextView with Scroll View
  
set aScroll to NSScrollView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))
  
set aView to NSTextView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))
  
aView’s setRichText:true
  
aView’s useAllLigatures:true
  
aView’s setTextColor:(current application’s NSColor’s cyanColor()) –cyanColor
  
aView’s setFont:(current application’s NSFont’s fontWithName:aFontName |size|:aFontSize)
  
set aColor to current application’s NSColor’s colorWithDeviceRed:0.0 green:0.0 blue:0.0 alpha:0.5
  
aView’s setBackgroundColor:aColor
  
aView’s setString:mesStr
  
aScroll’s setDocumentView:aView
  
aView’s enclosingScrollView()’s setHasVerticalScroller:true
  
  
— set up alert
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:aScroll
  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
end dispTextViewWithAlertdialog:

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

–指定AppleScriptファイルのソースコードを取得する(実行専用Scriptからは取得できない)
— Original Created 2014-02-23 Shane Stanley
on getASsourceFor(anAlias as {alias, string})
  set aURL to |NSURL|’s fileURLWithPath:(POSIX path of anAlias)
  
set theScript to OSAScript’s alloc()’s initWithContentsOfURL:aURL |error|:(missing value)
  
  
if theScript is equal to missing value then
    error "Compile Error" — handle error
  else
    set sourceText to theScript’s source()
  end if
  
  
return sourceText as string
end getASsourceFor

★Click Here to Open This Script 

(Visited 146 times, 1 visits today)
Posted in Color file File path Font GUI Text URL | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSAlert NSColor NSFont NSRunningApplication NSScrollView NSTextView NSURL OSAScript | Leave a comment

Cocoa ObjectをキーにしたDictionaryから合致するObjectを取得

Posted on 7月 7, 2019 by Takaaki Naganoya

Cocoa ObjectをキーにしたDictionaryから、Cocoa Objectでキー検索を行い、キーが合致する要素に定義されているオブジェクトを取得するAppleScriptです。

AppleScriptのrecord型変数は、本当に基本的な機能しか用意されておらず、

{keyLabel1:value1, keyLabel2:value2, keyLabel3:value3 } 

のような、キーとなるラベルには「空白文字や使用禁止文字を含まない」文字しか使えませんし、キーに何らかのオブジェクトを指定することはできません。

そんな中、macOS 10.10でCocoa Scriptingが標準搭載されたため、CocoaのNSDictionaryを調べて「へー、キーにオブジェクトが使えるのか!」などと喜んでいました(macOS 10.10が出た頃)。

{Cocoa Object 1:value1, Cocoa Object 2:value2, Cocoa Object 3:value3 } 
{Cocoa Object 1:some object 1, Cocoa Object 2:some object 2, Cocoa Object 3:some object 3 } 

ちょうどそういう(CocoaオブジェクトをキーにしたDictionaryの検索)プログラムを組もうとして、Dictionaryから「valueForKey:」でvalueを取り出そうとして(エラーに遭遇して)試行錯誤していました。

(NSDictionary) {
	NSCalibratedRGBColorSpace 0 1 0 1:"Green",
	NSCalibratedRGBColorSpace 0 0 1 1:"Blue",
	NSCalibratedRGBColorSpace 1 0 0 1:"Red"
}

実際にはこれは「objectForKey:」で取り出さないとエラーになってしまうんですね。その確認のために書いた基礎確認用のAppleScriptです。やっぱり、基礎の再確認はとても大事です。

AppleScript名:Cocoa ObjectをキーにしたDictionaryから合致するObjectを取得
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/07/06
—
–  Copyright © 2019 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 aCol to current application’s NSColor’s redColor()
set bCol to current application’s NSColor’s greenColor()
set cCol to current application’s NSColor’s blueColor()

set aDict to current application’s NSMutableDictionary’s new()
aDict’s addObject:"Red" forKey:aCol
aDict’s addObject:"Green" forKey:bCol
aDict’s addObject:"Blue" forKey:cCol

set dCol to current application’s NSColor’s blueColor()

set aRes to (aDict’s objectForKey:dCol) as string
–> "Blue"

★Click Here to Open This Script 

(Visited 32 times, 1 visits today)
Posted in Color Record | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSColor NSMutableDictionary | Leave a comment

与えられた文字列の1D Listのすべての順列組み合わせパターン文字列を返す v3

Posted on 6月 20, 2019 by Takaaki Naganoya

与えられた1次元配列のデータのすべての順列組み合わせパターンを計算し、そのとおりに配列を並べて連結した文字列を、すべての順列組み合わせパターンについて生成して返す(Permutations)AppleScriptです。

初版ではありもののサブルーチンを組み合わせて、検証を行うには十分なものでした(v2)。ただし、本来その用途に作成したものではないルーチンを寄せ集めて作ったので、組み合わせ数が増えると処理時間がかかりすぎるきらいがありました。

そこで、こうした処理(Permutations)を英語でどう呼ぶのかを調べ、AppleScriptの実装例を調べたら、灯台下暗し。MacScripter.netにありました。

ただし、そのままではいまひとつ使いにくかったので、きちんと組み合わせた文字列を1次元配列で返すように組んでみたところ、オリジナル版よりは処理時間はかかっていますが、初版からくらべると大幅に処理速度とメモリ使用効率が改善されました。

MacScripter.net掲載サンプル処理結果:{{“A”, “T”, “G”, “C”}….}
本Scriptの処理結果:{“ATGC”, “ATCG”…..}

4要素の順列組み合わせ計算:5倍速
5要素の順列組み合わせ計算:10倍速
6要素の順列組み合わせ計算:30倍速
7要素の順列組み合わせ計算:67倍速
8要素の順列組み合わせ計算:(計測不能)

というように、大規模データになればなるほど高速化の度合いが高くなります。AppleScriptにしては大規模データを扱う演算なので、Cocoaの機能を積極的に利用することで高速化を行なっています。

開発機として用いているMacBook Pro 2012 Retina(Core i7 2.6GHz)と、MacBook Pro 13 2017 (Dual Thunderbolt)で処理時間を計測してみたところ、2012のMBPのほうがわずかに高速でした。

AppleScript名:与えられた文字列の1D Listのすべての順列組み合わせパターン文字列を返す v3.scptd
— 2014-10-06 Original By Nigel Garvey@macscripter.net
— 2019-06-19 Modified By Takaaki Naganoya
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

script spdPerm
  property permutations : missing value
end script

on run
  –Test by MacBook Pro 2012 Retina Core i7 2.6GHz
  
–set theList to {"A", "T", "G", "C", "1"} –0.05 secs (5 digits) 120 items.
  
–set theList to {"A", "T", "G", "C", "1", "2"} –0.21secs (6 digits) 720 items.
  
set theList to {"A", "T", "G", "C", "1", "2", "3"} –1.44 secs (7 digits) 5,040 items.
  
–set theList to {"A", "T", "G", "C", "1", "2", "3", "4"} –11.54 secs (8 digits) 40,320 items.
  
–set theList to {"A", "T", "G", "C", "1", "2", "3", "4", "5"} –107.27 secs (9 digits) 362,880 items.
  
  
set aRes to permute(theList) of me
  
return length of aRes
end run

on permute(theList as list)
  set theArray to current application’s NSMutableArray’s arrayWithArray:theList
  
set (permutations of spdPerm) to current application’s NSMutableArray’s array()
  
prmt(theArray, 0, (count theList) – 1)
  
  
–Return AppleScript string list
  
set aFinishArray to current application’s NSMutableArray’s new()
  
set anEnum to (permutations of spdPerm)’s objectEnumerator()
  
repeat
    set aValue to anEnum’s nextObject()
    
if aValue = missing value then exit repeat
    
set aStr to aValue’s componentsJoinedByString:""
    (
aFinishArray’s addObject:aStr)
  end repeat
  
  
return aFinishArray as list
end permute

on prmt(theArray, theStart as number, theEnd as number)
  if (theStart = theEnd) then
    (permutations of spdPerm)’s addObject:theArray
  else
    repeat with x from theStart to theEnd
      set theCopy to theArray’s mutableCopy()
      
–swap
      
if (x > theStart) then (theCopy’s exchangeObjectAtIndex:theStart withObjectAtIndex:x)
      
prmt(theCopy, theStart + 1, theEnd)
    end repeat
  end if
end prmt

★Click Here to Open This Script 

(Visited 116 times, 1 visits today)
Posted in list recursive call | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSMutableArray | 2 Comments

与えられた1D Listのすべての順列組み合わせパターン文字列を返す

Posted on 6月 18, 2019 by Takaaki Naganoya

与えられた1次元配列のデータのすべての順列組み合わせパターンを計算し、そのとおりに配列を並べて連結した文字列を、すべての順列組み合わせパターンについて生成して返すAppleScriptです。

InDesignやIllustratorなどの書類上に元データをレイアウトした際に、複数のテキストフィールドに分解してレイアウトされていることがあります(見た目重視で)。

その分割されたテキストフィールドを元データと比較する際に、位置情報などをもとに「このあたりが一緒になってそうだ」とあたりをつけるわけですが、左→右、上→下という順序に基づいて配置されているという保証はありません。見た目やインパクト重視で、あえて順番を変えているケースも考えられます。

そこで、並び順について「考えられるかぎりの全ての順列組み合わせでつないでチェック」するという脳筋な(マッチョな)方法を考えてみたりもするわけです。実際、この手の計算にはコンピュータは実に向いている道具なので(やらない方がおかしい?)。

そんな計算を行うために作成したAppleScriptですが、意外や意外、すべての順列組み合わせパターンを計算するルーチンは作ってありませんでした。性格的に、このあたり作ってないと気がすまないと(自分でも)思うものの、これだけ数千本も数万本もAppleScriptを書いておいて、手付かずの処理があったというのは逆に掘り出し物というべきなんでしょう。

そのため、過去に作った一番近いルーチンを流用して、すべての組み合わせパターンを計算し、そのうえで「すべての要素が異なる組み合わせ」だけを抽出しています(すべての組み合わせを計算するのに、「AAAA」とか「AAGG」とかの要素が重複する項目は削除)。

元になっているルーチンは、製品コードなどの複数桁から構成され、それぞれの桁で数値の範囲が異なるという規則性を持つコードを、すべてのパターンについて生成するというものでした。割と、製品カタログ掲載データなどで「ありがち」な仕様です。最新のルーチンでは、各桁についてプロパティ「aRuleList」に、

{下限値, 上限値}

とコードの生成ルールを定義しておいて、そのルールにもとづいてすべてのパターンのコードを展開していました。

出来上がったプログラムにそれほど時間はかけていませんが、それなりの行数に(圧縮記述をせず、見やすく、高度な処理を書けば、行数が増えるのは当然のことなんですけれども)。

  「もう少しシンプルに書けそうなもんだけどー?」

という気持ちでいっぱいですが、まずは機能を実現することが重要です。

→ この処理自体を「Permutations」と呼ぶことを見つけ、MacScripter.netにそのものズバリの処理がずらずらと並んでいるのを見て脱力しました。そうかぁ、再帰で処理するのかぁ。あ、全然高速ですね。ただ、項目数を増やすとやっぱりメモリが足りなくなって、処理がきつくなるのは同様の模様で。

→ 結局、MacScripterに投稿された各種Scriptも、最終的にテキスト要素の1次元配列にデータ変換すると、本ルーチンと同じぐらいの処理時間がかかって驚きです 本ルーチン、そんなに遅くない模様(無駄に長いだけで)

AppleScript名:与えられた文字列の1D Listのすべての順列組み合わせパターン文字列を返す v2
— Created 2019-06-18 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

script spd
  property aList : {}
  
property tmpList : {}
  
property aRuleList : {{1, 4}, {1, 4}, {1, 4}, {1, 4}} –上書きしてしまうので、この通りとはかぎらない
  
property aRuleLen : length of aRuleList
end script

set targList to {"A", "T", "G", "C"}
set aRes to retStrListInAllCombinations(targList) of me
–> {"ATGC", "ATCG", "AGTC", "AGCT", "ACTG", "ACGT", "TAGC", "TACG", "TGAC", "TGCA", "TCAG", "TCGA", "GATC", "GACT", "GTAC", "GTCA", "GCAT", "GCTA", "CATG", "CAGT", "CTAG", "CTGA", "CGAT", "CGTA"}

–与えた文字列リストを、順列組み合わせの全パターンで組み替え直して返す
on retStrListInAllCombinations(targList as list)
  
  
set aRes to retAllPatterns(targList) of me
  
–> {1234, 1243, 1324, 1342, 1423, 1432, 2134, 2143, 2314, 2341, 2413, 2431, 3124, 3142, 3214, 3241, 3412, 3421, 4123, 4132, 4213, 4231, 4312, 4321}
  
  
–順列組み合わせデータをもとに元データをその順番に組み合わせる
  
set (tmpList of spd) to {}
  
repeat with i in aRes
    set jList to characters of (i as string)
    
    
set tmpStr to ""
    
repeat with ii in jList
      set tmpStr to tmpStr & (contents of item (ii as integer) of targList)
    end repeat
    
    
set the end of (tmpList of spd) to tmpStr
  end repeat
  
  
return (tmpList of spd)
end retStrListInAllCombinations

–与えられた要素数のリストをもとに、すべての順列組み合わせパターンを返す
on retAllPatterns(targList)
  –ルールテーブルの初期化
  
set targStrLen to length of targList
  
set (aRuleList of spd) to {}
  
repeat with i from 1 to targStrLen
    set the end of (aRuleList of spd) to {1, targStrLen}
  end repeat
  
set (aRuleLen of spd) to targStrLen –初版ではここを更新していなかったので、データの桁数を増やしても出力結果の桁数が変わらないというバグがあった
  
  
—
  
set (aList of spd) to {} –initilaize
  
set initNum to getMinNum() of me –本ルール下における最小値
  
  
copy initNum to aNum
  
  
repeat
    set aRes to incDigit(aNum, 1) of me
    
    
if aRes = false then
      exit repeat
    end if
    
    
if (chkEachDigitIsNotSameChar(aRes) of me) = true then
      if aRes is not in (aList of spd) then
        set the end of (aList of spd) to aRes
      end if
    end if
    
    
copy aRes to aNum
    
  end repeat
  
  
return (aList of spd)
end retAllPatterns

–与えられたルール下における最小値をルールリストから求める
on getMinNum()
  –桁数が合っているだけのダミー数字を、適切な桁数作成する(例:11111)
  
set tmpNumStr to ""
  
repeat (aRuleLen of spd) times
    set tmpNumStr to tmpNumStr & "1"
  end repeat
  
  
set tmpNum to tmpNumStr as integer
  
  
–ルールから各桁の最小値を取り出して、各桁に設定する
  
repeat with i from 1 to (aRuleLen of spd)
    set aDigNum to item 1 of item i of (aRuleList of spd)
    
set tmpNum to setDigit(tmpNum, i, aDigNum) of me
  end repeat
  
  
return tmpNum
end getMinNum

–繰り上がり処理(再帰呼び出しで使用)
on incDigit(aNum, aDigit)
  set {thisMin, thisMax} to item ((aRuleLen of spd) – aDigit + 1) of (aRuleList of spd)
  
  
set aTarget to getDigit(aNum, aDigit) of me
  
  
if aTarget = thisMax then
    if aDigit = (aRuleLen of spd) then
      –オーバーフロー(桁あふれ)エラーを返す
      
return false
    end if
    
    
set bNum to incDigit(aNum, aDigit + 1) of me
    
    
if bNum = false then return false
    
    
set bNum to setDigit(bNum, aDigit, thisMin) of me
  else
    set aTarget to aTarget + 1
    
set bNum to setDigit(aNum, aDigit, aTarget) of me
  end if
  
  
return bNum
end incDigit

–指定数値のうち指定桁の数字を返す
on getDigit(aNum, aDigit)
  
  
set aStr to aNum as string
  
set aLen to length of aStr
  
if aLen < aDigit then
    return false –エラー
  end if
  
  
set tStr to character (aLen – aDigit + 1) of aStr
  
return tStr as integer
  
end getDigit

–指定数値のうち指定桁の数字を返す
on setDigit(aNum, aDigit, newNum)
  
  
set aStr to aNum as string
  
set aLen to length of aStr
  
if aLen < aDigit then
    return false –エラー
  end if
  
  
set aList to characters of aStr
  
  
set item (aLen – aDigit + 1) of aList to (newNum as string)
  
set aaStr to aList as string
  
  
return aaStr as integer
  
end setDigit

–与えた文字列の各キャラクタがすべて「別のもの」であるかをチェック
on chkEachDigitIsNotSameChar(aStr as string)
  set aLen to length of aStr
  
set aList to characters of aStr
  
  
set bList to {}
  
repeat with i in aList
    set j to contents of i
    
if j is not in bList then
      set the end of bList to j
    else
      return false –Some duplicated character(s) exists
    end if
  end repeat
  
return true –All Characters are different
end chkEachDigitIsNotSameChar

★Click Here to Open This Script 

(Visited 168 times, 1 visits today)
Posted in list | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy 10.15savvy | 1 Comment

CotEditorで編集中のMarkdown書類をPDFプレビュー

Posted on 6月 15, 2019 by Takaaki Naganoya

CotEditorで編集中のMarkdown書類を、MacDownでPDF書き出しして、Skimでオープンして表示するAppleScriptです。

CotEditorにMarkdownのプレビュー機能がついたらいいと思っている人は多いようですが、MarkdownはMarkdownで、方言は多いし標準がないし、1枚もののMarkdown書類だけ編集できればいいのか、本などのプロジェクト単位で編集とか、目次が作成できないとダメとか、リンクした画像の扱いをどうするのかとか、対応しようとすると「ほぼ別のソフトを作るのと同じ」ぐらい手間がかかりそうです(メンテナー様ご本人談)。

そこで、AppleScript経由で他のソフトを連携させてPDFプレビューさせてみました。これなら、誰にも迷惑をかけずに、今日この時点からすぐにMarkdownのプレビューが行えます(当然、HTML書き出ししてSafariでプレビューするバージョンははるかかなた昔に作ってあります)。

ただし、OS側の機能制限の問題で、CotEditor上のスクリプトメニューから実行はできません(GUI Scriptingの実行が許可されない)。OS側のスクリプトメニューに登録して実行する必要があります。

GUI Scriptingを利用してメニュー操作を行なっているため、システム環境設定で許可しておく必要があります。

本来であれば、PDFの書き出し先フォルダ(この場合は書き出しダイアログで、GUI Scirptingを用いてCommand-Dで指定して一律に場所指定が行えるデスクトップフォルダ)に同名のPDFが存在しないかどうかチェックし、存在すれば削除するといった処理が必要ですが、面倒だったのであらかじめMarkdown書類をUUIDにリネームしておくことで、書き出されたPDFも同じくUUIDのファイル名になるため、論理上はファイル名の衝突を回避できるため、削除処理を省略しています。

AppleScript名:🌏レンダリングしてPDFプレビュー
— Created 2019-06-15 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property NSUUID : a reference to current application’s NSUUID
property NSWorkspace : a reference to current application’s NSWorkspace

–オープン中のMarkdown書類を取得する
tell application "CotEditor"
  tell front document
    set cStyle to coloring style
    
if cStyle is not equal to "Markdown" then
      display dialog "編集中のファイルはMarkdown書類ではないようです。" buttons {"OK"} default button 1
      
return
    end if
    
    
set aPath to path
  end tell
end tell

–一時フォルダにMarkdown書類をコピー
set sPath to (path to temporary items)
tell application "Finder"
  set sRes to (duplicate ((POSIX file aPath) as alias) to folder sPath with replacing)
end tell

–コピーしたMarkdown書類をリネーム
set s1Res to sRes as alias
set aUUID to NSUUID’s UUID()’s UUIDString() as text –UUIDを作成する
tell application "Finder"
  set name of s1Res to (aUUID & ".md")
end tell

–Markdown書類をデスクトップにPDF書き出し
set pdfRes to exportFromMacDown(POSIX path of s1Res) of me

–PDF Viewerでオープン
tell application "Skim" –Preview.appでもOK
  activate
  
open pdfRes
end tell

–一時フォルダに書き出したMarkdown書類を削除
tell application "Finder"
  delete s1Res
end tell

–指定のMacDownファイル(alias)をデスクトップ上にPDFで書き出し
on exportFromMacDown(anAlias)
  set s1Text to paragraphs of (do shell script "ls ~/Desktop/*.pdf") –pdf書き出し前のファイル一覧
  
  
tell application "MacDown"
    open {anAlias}
  end tell
  
  
macDownForceSave() of me
  
  
tell application "MacDown"
    close every document without saving
  end tell
  
  
do shell script "sync" –ねんのため
  
  
set s2Text to paragraphs of (do shell script "ls ~/Desktop/*.pdf") –pdf書き出し後のファイル一覧
  
  
set dRes to getDiffBetweenLists(s1Text, s2Text) of me –デスクトップ上のPDFファイル名一覧の差分を取得
  
set d2Res to (addItems of dRes)
  
  
if length of d2Res ≥ 1 then
    return contents of first item of d2Res
  else
    error "Error in exporting PDF to desktop folder…."
  end if
end exportFromMacDown

on getDiffBetweenLists(aArray as list, bArray as list)
  set allSet to current application’s NSMutableSet’s setWithArray:aArray
  
allSet’s addObjectsFromArray:bArray
  
  
–重複する要素のみ抜き出す
  
set duplicateSet to current application’s NSMutableSet’s setWithArray:aArray
  
duplicateSet’s intersectSet:(current application’s NSSet’s setWithArray:bArray)
  
  
–重複部分を削除する
  
allSet’s minusSet:duplicateSet
  
set resArray to (allSet’s allObjects()) as list
  
  
set aSet to current application’s NSMutableSet’s setWithArray:aArray
  
set bSet to current application’s NSMutableSet’s setWithArray:resArray
  
aSet’s intersectSet:bSet –積集合
  
set addRes to aSet’s allObjects() as list
  
  
set cSet to current application’s NSMutableSet’s setWithArray:bArray
  
cSet’s intersectSet:bSet –積集合
  
set minusRes to cSet’s allObjects() as list
  
  
return {addItems:minusRes, minusItems:addRes}
end getDiffBetweenLists

–注意!! ここでGUI Scriptingを使用。バージョンが変わったときにメニュー階層などの変更があったら書き換え
on macDownForceSave()
  activate application "MacDown"
  
tell application "System Events"
    tell process "MacDown"
      — File > Export > PDF
      
click menu item 2 of menu 1 of menu item 14 of menu 1 of menu bar item 3 of menu bar 1
      
      
–Go to Desktop Folder
      
keystroke "d" using {command down}
      
      
–Save Button on Sheet
      
click button 1 of sheet 1 of window 1
    end tell
  end tell
end macDownForceSave

–Bundle IDからアプリケーションのPathを返す
on retAppAbusolutePathFromBundleID(aBundleID)
  set appPath to NSWorkspace’s sharedWorkspace()’s absolutePathForAppBundleWithIdentifier:aBundleID
  
if appPath = missing value then return false
  
return appPath as string
end retAppAbusolutePathFromBundleID

★Click Here to Open This Script 

(Visited 728 times, 3 visits today)
Posted in file File path GUI Scripting Markdown PDF shell script | Tagged 10.11savvy 10.12savvy 10.13savvy CotEditor Finder MacDown NSUUID NSWorkspace Skim | Leave a comment

Markdown書類をメモ.appに新規エントリで登録する

Posted on 6月 11, 2019 by Takaaki Naganoya

指定のMarkdown書類をメモ.app(Notes.app)に新規エントリとして登録するAppleScriptです。


▲テストに使ったMarkdown書類

Markdown書類をUTF-8のテキストとして読み込み、それをHTMLに変換し、そのままメモ.app(Notes.app)に新規エントリとして登録します。Markdown書類のHTMLへの解釈はオープンソースのMMMarkdownを利用しています。

自分はMarkdownエディタにMacDownを用いているため、使用しているMarkdown書類もMacDownが解釈する、割と自由度の高い(HTMLコードをそのまま書いておいても許容するような)Markdownのコードを与えて処理してみましたが、これらはMMMarkdownでHTML変換する際にスルーされたせいか、装飾がかなり再現されているように感じます。

Markdownタグの互換性はエディタごとに大きく異なるため、確認はお手元のエディタ用のMarkdown書類で行なってください。

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


▲MMMarkdownを用いてMarkdown書類をHTMLに変換し、メモ.app(Notes.app)に登録した内容。表以外はけっこう反映できている

タイトルやメモ.app(Notes.app)上の登録先などは適宜変更してみてください。

何も考えずに、手元にあったMarkdown書類を処理してみたところ、http://のリンクや、applescript://のリンクなどもそのまま反映。色情報もそのまま反映されているようです。


▲macOS 10.14.5上で、Applet形式で実行。表も反映されている

macOS 10.14上では、①Script Debuggerを用いて実行 ②Frameworkを含めてApplet形式に書き出して実行 ③SIPを解除してスクリプトエディタ上で実行 のどちらか好きなものを選んでください。

Framework入りでAppletに書き出したものをダウンロードできるようにしておきました。macOS 10.14以降ではこちらもお試しください。

2019/6/15 フレームワークのリンク先が間違っていたようで、バイナリを書き出しし直しました。また、macOS 10.14環境で一部Scripterが言っているような「アプリケーション操作の認証を再度求められる」ような現象には遭遇していません。

–> MarkdownToNotes.zip

AppleScript名:Markdown書類をメモ.appに新規エントリで登録する.scptd
— Created 2019-06-11 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "MMMarkdown" –https://github.com/mdiep/MMMarkdown

property NSUUID : a reference to current application’s NSUUID

–Markdown書類の読み込み
set aFile to choose file of type {"net.daringfireball.markdown"}
tell current application
  set aStr to (read aFile as «class utf8»)
end tell

–Markdown to HTML
set htmlString to current application’s MMMarkdown’s HTMLStringWithMarkdown:aStr |error|:(missing value)

–メモ.app(Notes.app)に新規エントリを作成する
set aUUID to NSUUID’s UUID()’s UUIDString() as text –UUIDを作成する
tell application "Notes"
  make new note at folder "Notes" of account "iCloud" with properties {name:"TEST Notes_" & aUUID, body:(htmlString as string)}
end tell

★Click Here to Open This Script 

(Visited 199 times, 2 visits today)
Posted in file Markdown | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy Notes | Leave a comment

Keynote書類のテキスト色を置換

Posted on 6月 9, 2019 by Takaaki Naganoya

最前面のKeynote書類の文字色を置換するAppleScriptです。

# 初出時にはmacOS 10.13であったため、スクリプトエディタ上からも野良Framework呼び出しができましたが、macOS 10.14以降ではSIPを解除するかScript Debugger上で実行する必要があります

Keynoteは文字色の置換をする機能が実装されていないので、個別に手で色を変更するか、あるいはスタイルを編集して一括で修正するやり方になります。

そこで、AppleScriptで色置換を行う処理を書いてみました。表の背景色を置換する処理を書いたときの部品を大幅に使いまわしています。

文字色の取得や判定は、テキストアイテムの1文字目の情報で判断しています。途中で色を変更しているような場合にはうまく検出できません(処理スピードを重視したことと、自分の利用方法の範囲ではそういう文字ごとに異なる色を指定するところまではサポートしなくてよいと考えたためです。仕事ならもうちょっと真面目に作り込むかもしれませんが、、、、)。

ポップアップメニュー中の色名の動的な推定に、オープンソースの「DBColorNames」をフレームワーク化した
「dbColNamesKit.framework」を利用しています。

–> dbColNamesKit.framework (To ~/Library/Frameworks)


▲左上の時刻部分の色を置換したい


▲本Scriptを実行した直後。最前面のKeynote書類のすべてのテキストを走査して文字色を取得する


▲取得した文字色リスト。この中から置換対象を選択する。色データから色名を動的に生成し、色IDとともに名称で個別に指定したり識別したりできる


▲変更後の色をカラーピッカーで選択


▲Keynote書類上の文字色を変更してみた

AppleScript名:Keynote書類の現在のテキスト色を置換.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/06/08
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.5" — Yosemite (10.11) or later
use framework "Foundation"
use framework "AppKit"
use framework "dbColNamesKit" –https://github.com/daniel-beard/DBColorNames/
use scripting additions

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 NSImage : a reference to current application’s NSImage
property NSIndexSet : a reference to current application’s NSIndexSet
property NSTextField : a reference to current application’s NSTextField
property NSColorWell : a reference to current application’s NSColorWell
property NSMenuItem : a reference to current application’s NSMenuItem
property NSBezierPath : a reference to current application’s NSBezierPath
property NSPopUpButton : a reference to current application’s NSPopUpButton
property NSMutableArray : a reference to current application’s NSMutableArray
property NSRunningApplication : a reference to current application’s NSRunningApplication

property returnCode : 0
property pop1ind : 0

–スライド枚数をカウント
tell application "Keynote"
  tell front document
    set sCount to count every slide
  end tell
end tell

–すべてのテキストアイテム、タイトルから色情報を取得する
set cList to {}
repeat with sNum from 1 to sCount
  set cList to cList & getEveryTextColorOfSlide(sNum) of me
end repeat

–文字色のユニーク化
set dList to makeUniqueListOf(cList) of me

set paramObj to {mainDat:dList, myTitle:"テキスト色置換", mySubTitle:"Keynoteのテキストアイテム、デフォルトアイテム(タイトル)の文字色置換", myColorRangeMax:65535}
my getPopupValues:paramObj

if pop1ind = false then return –timed out
set fromCol to (contents of item pop1ind of dList)

–カラーピッカーで置換色選択
set tCol to choose color default color fromCol

–Keynote書類中のテキストの文字色を置換
repeat with sNum from 1 to sCount
  set cList to cList & repEveryTextColorOfSlide(sNum, fromCol, tCol) of me
end repeat

–カラーポップアップメニューをウィンドウ表示
on getPopupValues:paramObj
  set ap1List to (mainDat of (paramObj as record)) as list
  
set winTitle to (myTitle of (paramObj as record)) as string
  
set subTitle to (mySubTitle of (paramObj as record)) as string
  
set aColMax to (myColorRangeMax of (paramObj as record)) as list
  
  
–Viewをつくる
  
set aView to NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, 360, 80))
  
  
–Labelをつくる
  
set a1TF to NSTextField’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 40, 80, 20))
  
a1TF’s setEditable:false
  
a1TF’s setStringValue:"From Color:"
  
a1TF’s setDrawsBackground:false
  
a1TF’s setBordered:false
  
  
–Ppopup Buttonをつくる
  
set a1Button to NSPopUpButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(80, 40, 200, 20)) pullsDown:false
  
a1Button’s removeAllItems()
  
  
set a1Menu to NSMenu’s alloc()’s init()
  
set aCDB to current application’s DBColorNames’s alloc()’s init()
  
  
–Popup Menuをつくる
  
set iCount to 1
  
repeat with i in ap1List
    copy i to {r1, g1, b1}
    
    
set nsCol to makeNSColorFromRGBAval(r1, g1, b1, aColMax, aColMax) of me
    
set anImage to makeRoundedNSImageWithFilledWithColor(64, 64, nsCol, 4) of me
    
    
–色名をRGB値から動的に生成(あらかじめdbNamesが持っているカラーパレットの近似色の色名を返す)
    
set aTitle to "#" & (iCount as string) & " " & (aCDB’s nameForColor:nsCol) as string
    
    
–Menu Itemを作成する
    
set aMenuItem to (NSMenuItem’s alloc()’s initWithTitle:aTitle action:"actionHandler:" keyEquivalent:"")
    (
aMenuItem’s setImage:anImage)
    (
aMenuItem’s setEnabled:true)
    (
aMenuItem’s setTarget:me)
    (
a1Menu’s addItem:aMenuItem)
    
    
set iCount to iCount + 1
  end repeat
  
  
–Popup ButtonにPopup Menuを設定する
  
a1Button’s setMenu:a1Menu
  
  
–ViewにPopup Buttonとテキストラベルを入れる
  
aView’s addSubview:a1TF
  
aView’s addSubview:a1Button
  
aView’s setNeedsDisplay:true
  
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:winTitle
    
its setInformativeText:subTitle
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:aView
  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 s1Val to ((a1Button’s indexOfSelectedItem() as number) + 1)
  
copy s1Val to my pop1ind
end getPopupValues:

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

–Popup Action Handler
on actionHandler:sender
  set aTag to tag of sender as integer
  
set aTitle to title of sender as string
end actionHandler:

–aMaxValを最大値とする数値でNSColorを作成して返す
on makeNSColorFromRGBAval(redValue as integer, greenValue as integer, blueValue as integer, alphaValue as integer, aMaxVal as integer)
  set aRedCocoa to (redValue / aMaxVal) as real
  
set aGreenCocoa to (greenValue / aMaxVal) as real
  
set aBlueCocoa to (blueValue / aMaxVal) as real
  
set aAlphaCocoa to (alphaValue / aMaxVal) as real
  
set aColor to NSColor’s colorWithCalibratedRed:aRedCocoa green:aGreenCocoa blue:aBlueCocoa alpha:aAlphaCocoa
  
return aColor
end makeNSColorFromRGBAval

–指定サイズのNSImageを作成し、指定色で塗ってNSImageで返す
on makeNSImageWithFilledWithColor(aWidth as integer, aHeight as integer, fillColor)
  set anImage to NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight))
  
anImage’s lockFocus()
  
—
  
set theRect to {{x:0, y:0}, {height:aHeight, width:aWidth}}
  
set theNSBezierPath to NSBezierPath’s bezierPath
  
theNSBezierPath’s appendBezierPathWithRect:theRect
  
—
  
fillColor’s |set|() –色設定
  
theNSBezierPath’s fill() –ぬりつぶし
  
—
  
anImage’s unlockFocus()
  
—
  
return anImage
end makeNSImageWithFilledWithColor

–指定サイズのNSImageを作成し、指定色で塗ってNSImageで返す、anRadiusの半径の角丸で
on makeRoundedNSImageWithFilledWithColor(aWidth as integer, aHeight as integer, fillColor, anRadius as real)
  set anImage to NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight))
  
anImage’s lockFocus()
  
—
  
set theRect to {{x:0, y:0}, {height:aHeight, width:aWidth}}
  
set theNSBezierPath to NSBezierPath’s bezierPathWithRoundedRect:theRect xRadius:anRadius yRadius:anRadius
  
—
  
fillColor’s |set|() –色設定
  
theNSBezierPath’s fill() –ぬりつぶし
  
—
  
anImage’s unlockFocus()
  
  
return anImage
end makeRoundedNSImageWithFilledWithColor

–最前面のKeynote書類のすべてのスライドから、テキストアイテムとタイトルアイテムの文字色を取得
on getEveryTextColorOfSlide(sNum)
  set cList to {}
  
  
tell application "Keynote"
    tell front document
      set sMax to count every slide
      
if sMax < sNum then return false
      
      
tell slide sNum
        –すべての文字アイテムの先頭の文字の色情報を取得
        
try
          set tCount to count every text item
          
repeat with i from 1 to tCount
            set s1List to color of character 1 of object text of text item i
            
set the end of cList to s1List
          end repeat
        on error
          –set s1List to {}
        end try
        
        
–タイトルの先頭の文字の色情報を取得
        
try
          set s2List to color of character 1 of object text of default title item
          
set the end of cList to s2List
        on error
          set s2List to {}
        end try
      end tell
      
    end tell
  end tell
  
  
return cList
end getEveryTextColorOfSlide

–最前面のKeynote書類の指定番号のスライドで、テキストアイテムとタイトルアイテムの文字色を置換
on repEveryTextColorOfSlide(sNum, fromCol, toCol)
  tell application "Keynote"
    tell front document
      set sMax to count every slide
      
if sMax < sNum then return false
      
      
tell slide sNum
        –すべての文字アイテムの先頭の文字の色情報を置換
        
try
          set tCount to count every text item
          
repeat with i from 1 to tCount
            set s1List to color of character 1 of object text of text item i
            
if s1List = fromCol then
              ignoring application responses
                set color of every character of object text of text item i to toCol
              end ignoring
            end if
          end repeat
        on error
          —
        end try
        
        
–タイトルの先頭の文字の色情報を置換
        
try
          set s2List to color of character 1 of object text of default title item
          
if s2List = fromCol then
            ignoring application responses
              set color of every character of object text of default title item to toCol
            end ignoring
          end if
        on error
          set s2List to {}
        end try
      end tell
      
    end tell
  end tell
end repEveryTextColorOfSlide

–Listのユニーク化
on makeUniqueListOf(theList)
  set theSet to current application’s NSOrderedSet’s orderedSetWithArray:theList
  
return (theSet’s array()) as list
end makeUniqueListOf

★Click Here to Open This Script 

(Visited 745 times, 1 visits today)
Posted in Color dialog GUI list | Tagged 10.11savvy 10.12savvy 10.13savvy Keynote NSAlert NSBezierPath NSColor NSColorWell NSImage NSIndexSet NSMenu NSMenuItem NSMutableArray NSPopUpButton NSRunningApplication NSTextField NSView | Leave a comment

Post navigation

  • Older posts

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

Google Search

Popular posts

  • AppleScriptによるWebブラウザ自動操縦ガイド
  • ドラッグ&ドロップ機能の未来?
  • macOS 13, Ventura(継続更新)
  • Intel MacとApple Silicon Macの速度差〜画像処理
  • macOS 12.x上のAppleScriptのトラブルまとめ
  • マウスの右クリックメニューをカスタマイズするService Station
  • macOS 12.3 beta 5、ASの障害が解消される(?)
  • CotEditorで選択範囲の行頭にある数字をリナンバーする v1
  • PFiddlesoft UI Browserが製品終了に
  • SF Symbolsを名称で指定してPNG画像化
  • 不可視プロセスで表示したNSAlertを最前面に表示
  • 与えられた自然言語テキストから言語を推測して、指定の性別で、TTSキャラクタを自動選択して読み上げ
  • 新刊発売:AppleScriptによるWebブラウザ自動操縦ガイド
  • macOS 12.3 beta4、まだ直らないASまわりの障害
  • Safariで表示中のYouTubeムービーのサムネイル画像を取得
  • macOS 12のスクリプトエディタで、Context Menu機能にバグ
  • macOS 12.3上でFinder上で選択中のファイルをそのままオープンできない件
  • Pixelmator Pro v2.4.1で新機能追加+AppleScriptコマンド追加
  • SafariでブックマークされたURL一覧を取得
  • SkimのAppleScriptサポート機能にバグ

Tags

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

カテゴリー

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

アーカイブ

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