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

Excel__Numbersセルアドレスの相互変換

Posted on 12月 3, 2024 by Takaaki Naganoya

ExcelやNumbersで使われているセルのアドレス表記方法「A1形式」と数値の相互変換を行うAppleScriptです。

一応、自分でも昔に書いたルーチンを使い回していますが、26進数と10進数との間の変換で桁が増えたときの処理に難があって、上限値を設けてその間であれば変換できる、という感じになっていました。

もともと、このルーチンはExcel 2008でVBAの処理系を搭載しないことになったのを好機ととらえ、AppleScriptをエンコードしてExcelの隠しワークシート上に格納しておいて外部から実行する「ExcelAS」プロジェクトのために作成したものです。

実際に調布のMicrosoftでデモを行なって、US Microsoftに掛け合ってもらったものの、次バージョンでVBAの処理系を復活させることになって、(Visual BASIC互換の)「REALbasic」のエンジンを書いていたエンジニアをMSがヘッドハント。常識的に考えればVBAの廃止自体がおかしな決定だったので、その隙を狙えるかも? と企画して作ったものの、残念な結果になってしまいました。ただ、現在に至るもMac上のVBAの処理系、とくにエディタは作りが残念(Retina解像度に合ってないとか、日本語入力できないとか、フォームが使えないとか)なので、もうちょっとなんとかならないものかと思ってしまいます。

話をアドレス変換ルーチンに戻しましょう。実際に、そんなに大きな値の相互変換はしていないので問題視していませんでしたが、変換ルーチンに上限値のしばりがあるのはうっとおしいとは思っていました。ただ、ExcelASプロジェクトの頓挫により、アドレス変換処理を書き換えるほどのインセンティブがなかったので、ながらく放置状態に。

そこで、定期的に行なっているChatGPTによるAppleScript記述実用性チェックの「お題」としてこのセルアドレスの相互変換を行わせてみました。

ちゃんと動いているように見えます。こういうデータ変換系のプログラムは、割とChatGPTで書かせるのは「アリ」だと思います。本ルーチンの注意点は、Excelアドレス(カラム名指定)はアルファベット大文字で記述する必要があるということです。小文字のアルファベットで記述すると本バージョンではエラーになります。

ただ、アプリケーションの詳細なコントロールを行わせると、首をひねってしまうような書き方を返してきます。

AppleScript名:Excel__Numbersセルアドレスの相互変換.scpt
— 数値 → A1形式
set result1 to numberToCell(2024, 5) — "BYV5"
display dialog "Number to Cell: " & result1

— A1形式 → 数値
set result2 to cellToNumber("BYV5") — {2024, 5}
display dialog "Cell to Number: Column: " & item 1 of result2 & ", Row: " & item 2 of result2

— 数値からセルアドレス(A1形式)への変換
on numberToCell(columnNumber, rowNumber)
  set columnAddress to ""
  
set tempNumber to columnNumber
  
  
— 列番号をA-Z形式に変換
  
repeat while tempNumber > 0
    set remainder to (tempNumber – 1) mod 26
    
set columnAddress to (character (remainder + 1) of "ABCDEFGHIJKLMNOPQRSTUVWXYZ") & columnAddress
    
set tempNumber to (tempNumber – 1) div 26
  end repeat
  
  
— A1形式のアドレスを返す
  
return columnAddress & rowNumber
end numberToCell

— セルアドレス(A1形式)から数値への変換
on cellToNumber(cellAddress)
  set columnPart to ""
  
set rowPart to ""
  
  
— 列部分と行部分を分離
  
repeat with char in cellAddress
    if char is in "0123456789" then
      set rowPart to rowPart & char
    else
      set columnPart to columnPart & char
    end if
  end repeat
  
  
— 列部分を数値に変換
  
set columnNumber to 0
  
repeat with i from 1 to length of columnPart
    set char to character i of columnPart
    
set columnNumber to columnNumber * 26 + (offset of char in "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
  end repeat
  
  
— 数値を返す
  
return {columnNumber, (rowPart as integer)}
end cellToNumber

★Click Here to Open This Script 

Posted in Number Text | Tagged 10.10savvy 10.11savvy 10.12savvy 10.13savvy 10.14savvy 10.15savvy 11.0savvy 12.0savvy 13.0savvy 14.0savvy 15.0savvy Excel Numbers | Leave a comment

有害ではなくなっていたSpaces

Posted on 9月 30, 2024 by Takaaki Naganoya

Spacesは、macOS標準搭載の仮想デスクトップ機能であり、最大16個の仮想デスクトップを作れるようになっているほか、F3キーを押すと縮小表示を行うようになっているなど、ハード/ソフトともによく統合された機能です。

ただし、AppleScriptユーザー側からすると

「他の仮想デスクトップにアプリのウィンドウを置くとAppleScriptからアクセスできないカス機能」
「開発チームが他の機能のことを考慮していないクズ機能」

といった感想になります。

このため、さまざまな書籍で「AppleScriptとの互換性のない機能」のひとつとしてリストアップされ、AppleScript系の開発/運用現場では「安全のためにSpacesを使わないように」と注意するのが真っ先に行う恒例行事になっていました。

内蔵HDD/SSDの暗号化機能なみに、登場時にAppleScriptとの互換性検証が不十分なものについては「信用できない」として、以来、安全のために暗号化機能は極力使わないようにしてきました。

# HDDの暗号化機能が登場したときに、暗号化したHDDにAppleScriptからアクセスできないというバカみたいな不具合が発生。その後も、有効にするとeGPUが使えなくなるなど、この機能を作っている担当者だかチームのことが信じられません。

そして話はSpacesに戻ります。執筆中の電子書籍「Pages+AppleScriptで本をつくろう!」の注意点でSpacesについて言及し、確認のために「やっぱり今でも動かないのか?」と、試してみたら……他の仮想デスクトップ上に配置したPagesの書類の情報を取得できます。

「…………。」

何度試してみても、他の仮想デスクトップに配置したPages書類の情報を取得できます。

macOS 13.7.1と、macOS 10.13.7で試してみたところ、両方で動作しました。

このぐらいの範囲のmacOSで動くのであれば、さまざまな本でSpacesに関する「危険なので使用を推奨しない」という評価は取り下げる必要があることでしょう。

ただ、Pagesについては表示中のページから+6ページぐらいを超えるとオブジェクトのposition属性を取得できないといった不具合があり、これはmacOS 15で再テストしても発生が確認されています。

Posted in Bug news | Tagged 10.13savvy 15.0savvy Spaces | Leave a comment

相対パスを計算で求める

Posted on 6月 14, 2022 by Takaaki Naganoya

指定のPOSIX pathを元に相対パスを計算するAppleScriptです。

Unix shellであれば、相対パスについては「../../../」などと表現できるわけですが、シェルを介さずに計算する方法が見つからなかったので、必要に迫られて作っておきました。

AppleScript名:上位パスを相対的に求める.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/06/14
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—

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

set aFile to "/Users/me/Documents/1/2/3"

set aNum to 1
set bFile to getUpperDir(aFile, aNum) of me

–> "/Users/me/Documents/1/2"

set aNum to 2
set cFile to getUpperDir(aFile, aNum) of me
–>"/Users/me/Documents/1"

set aNum to 3
set dFile to getUpperDir(aFile, aNum) of me
–> "/Users/me/Documents"

–与えられたパスから指定階層「上」のパスを求める
on getUpperDir(aPOSIXpath as string, aNum as integer)
  if aNum < 1 then return aPOSIXpath
  
set pathString to current application’s NSString’s stringWithString:aPOSIXpath
  
repeat aNum times
    set pathString to pathString’s stringByDeletingLastPathComponent()
  end repeat
  
return pathString as string
end getUpperDir

★Click Here to Open This Script 

AppleScript名:下位パスを配列で追加して求める.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/06/14
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—

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

set aPOSIXpath to "/Users/me/Documents/" –AppleScriptのPOSIX path表現(フォルダを表現するさい、末尾に「/」)
set catDirList to {"1", "2", "3"}
set bPath to getChildPathByAppendingDirsByArray(aPOSIXpath, catDirList) of me
–> /Users/me/Documents/1/2/3

set aPOSIXpath to "/Users/me/Documents" –CocoaのPOSIX path表現(フォルダを表現する場合でも、末尾に「/」入らず)
set catDirList to {"3", "2", "1"}
set cPath to getChildPathByAppendingDirsByArray(aPOSIXpath, catDirList) of me
–> "/Users/me/Documents/3/2/1"

on getChildPathByAppendingDirsByArray(aPOSIXpath, catDirList)
  set pathString to current application’s NSString’s stringWithString:aPOSIXpath
  
set aList to (pathString’s pathComponents()) as list
  
set aList to aList & catDirList
  
  
set bPath to current application’s NSString’s pathWithComponents:aList
  
return bPath as string
end getChildPathByAppendingDirsByArray

★Click Here to Open This Script 

Posted in File path list Text | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy 12.0savvy | Leave a comment

人類史上初、魔導書の観点から書かれたAppleScript入門書「7つの宝珠」シリーズ開始?!

Posted on 5月 30, 2022 by Takaaki Naganoya

いつものようにコードレス糸電話(FaceTime Audio)で企画会議を行なっていたら、「プログラミングを魔導書の形式で書くことが可能なのではないか?」というアイデアが登場。その場でアイデアスケッチを行い、あれよあれよという間に、実物ができてしまいました。

→ 販売ページ

ノリと勢いだけで作ってしまった1冊ですが、ビジュアル要素多めでまとめられました。ただ、宗教的なアレとかナニとかを完全に無視して作ったものなので、日本国内でしか流通させないほうがよいでしょう。

本書は、プログラミングという魔法について、「魔導書」の観点から記した人類最初の書物である。

難解なプログラミングを、なじみ深い魔導書の観点から説明すると親しみやすくなるのだろうか、という1つの魔術モルモット実験でもある。

本書で扱う内容はごくごく簡単で基礎的な内容だが、このぐらいにしぼって解説すれば難しく見えないという7テーマ、七宝珠である。

「習うより慣れろ」ということわざがあるように、難解な魔術であっても苦手意識を持たずに「慣れる」ことは重要である。 本書をもってしても、真の魔道士を育成することは難しい。だが、「だいたいこんなかんじ」という感覚をつかむためには、このぐらいの分量に抑えることが肝要だろう。

PDF 31ページ

目次

■魔導書「7つの宝珠」

神(Computer)との対話を行う人の子の書
失われし魔法の7つの宝珠を求めて
変数と代入文という最初の宝珠
if文〜条件分岐という宝珠
繰り返しループ 体力を削らせない宝珠
配列変数 詠唱呪文の機能を高める宝珠
コメント文 失われた知恵の宝珠
ログ表示 簡単に変数の中身を確認する宝珠
終了 そこで呪文実行を止める宝珠

■第1の宝珠 変数と代入文

神の言葉から人の子の言葉への移行
巻物で満ち溢れる人の子の世
牛飼いを羊飼いに変える変数
変数に牛や羊を入れるのが「代入」
変数の中に何がある?

■最短詠唱呪文集

魔術入門〜最短詠唱呪文
警告音を鳴らす魔術「beep」
現在の日付を知る魔法「current date」
クリップボードの内容を調べる魔法
時間待ちを行う魔法「delay」
ゆうしゃ(=あなた)のステータス

Posted in Books news | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy 12.0savvy | Leave a comment

1D Listに入っているテキストから丸つき数字を抽出して数値化し、最小のものを求める

Posted on 11月 26, 2021 by Takaaki Naganoya

1D List(1D Array)に入っているテキスト要素から、丸つき数字を抽出して数値化し、得られた数値のうち最小のものを求めるAppleScriptです。

こんな、丸つき数字のテキストが入った「表」をKeynote上に作成したときに、

項目を追加したり順番を入れ替えたりすると、セルの中に入れている丸つき数字も変更する必要があります。これが手作業でたいへんめんどくさいので、Scriptで処理できるようにサブルーチンを整備してみました。

やりたいことは割とシンプルなはずなのに、割といろいろ書かないと実現しない処理でもあります。

そして、本Scriptは置換対象のデータから丸つき数字部分を取り出して、最小のものを判別し、リナンバー時の開始値を既存のデータから推測するという処理のために作ったものです。

AppleScript名:1D Listに入っているテキストから丸つき数字を抽出して数値化し、最小のものを求める.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2021/11/26
—
–  Copyright © 2021 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set aList to {"❹Script Editor", "②Xcode", "③ショートカット", "④Script Debugger④", "⑤SD Notary", "⑥UI Browser", "⑦Accessibility Inspector"}
set aSmallestNum to getMinimumNumFromNumberWithSign(aList) of me
–> 2

–1D Listに入っているテキストから丸つき数字を抽出して数値化し、最小のものを求める
on getMinimumNumFromNumberWithSign(aList)
  set nList to {}
  
  
repeat with i in aList
    set j to contents of i
    
–与えられたテキストのうち、丸つき数字(白)の
    
set j2 to holdNumberWithSignOnly(j) of me
    
set n2List to characters of j2 –複数の丸つき数字が入っている場合に対処
    
    
repeat with ii in n2List
      set jj to contents of ii
      
set tmpNum to decodeNumFromNumWithSign(jj) of me
      
set the end of nList to tmpNum
    end repeat
    
  end repeat
  
  
set anArray to current application’s NSArray’s arrayWithArray:nList
  
set cRes to (anArray’s valueForKeyPath:"@min.self") as integer
  
return cRes
end getMinimumNumFromNumberWithSign

–指定文字列から丸つき数字のみ抽出する
on holdNumberWithSignOnly(aStr as text)
  set aNSString to current application’s NSString’s stringWithString:aStr
  
return (aNSString’s stringByReplacingOccurrencesOfString:"[^\\U000024EA-\\U000024EA\\U00002460-\\U00002473\\U00003251-\\U000032BF\\U000024FF-\\U000024FF\\U00002776-\\U0000277F\\U000024EB-\\U000024F4\\U00002780-\\U00002789\\U0000278A-\\U00002793\\U000024F5-\\U000024FE]" withString:"" options:(current application’s NSRegularExpressionSearch) range:{0, aNSString’s |length|()}) as text
end holdNumberWithSignOnly

–丸つき数字を数値にデコードする v2
on decodeNumFromNumWithSign(aStr as string)
  set numStr1 to "①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚㉛㉜㉝㉞㉟㊱㊲㊳㊴㊵㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿"
  
set numStr2 to "❶❷❸❹❺❻❼❽❾❿⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴"
  
set numStr3 to "➀➁➂➃➄➅➆➇➈➉"
  
set numStr4 to "➊➋➌➍➎➏➐➑➒➓"
  
set numStr5 to "⓵⓶⓷⓸⓹⓺⓻⓼⓽⓾"
  
–set numStr6 to "⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇"
  
–set numStr7 to "1︎⃣2︎⃣3︎⃣4︎⃣5︎⃣8︎⃣9︎⃣"
  
–set numStr8 to "⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛"
  
  
set nList to {numStr1, numStr2, numStr3, numStr4, numStr5}
  
  
repeat with i in nList
    set numTemp to contents of i
    
if numTemp contains aStr then
      using terms from scripting additions
        set bNum to offset of aStr in numTemp
      end using terms from
      
return bNum
    end if
  end repeat
  
return false
end decodeNumFromNumWithSign

★Click Here to Open This Script 

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

文字列から丸つき数字のみ抽出する

Posted on 11月 26, 2021 by Takaaki Naganoya

指定の文字列から丸つき数字の部分だけを抽出するAppleScriptです。

丸つき数字の文字を数値に変換するサブルーチンのために作成したものです。

AppleScript名:文字列から丸つき数字のみ抽出する.scpt
–  Original by: Shane Stanley
–  Created on: 2019/11/04
–  Modified by: Takaaki Naganoya
–  Modified on: 2021/11/26

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

set aRes to holdNumberWithSignOnly("⑦Accessibility Inspector") of me
–> "⑦"

on holdNumberWithSignOnly(aStr as text)
  set aNSString to current application’s NSString’s stringWithString:aStr
  
  
return (aNSString’s stringByReplacingOccurrencesOfString:"[^\\U000024EA-\\U000024EA\\U00002460-\\U00002473\\U00003251-\\U000032BF\\U000024FF-\\U000024FF\\U00002776-\\U0000277F\\U000024EB-\\U000024F4\\U00002780-\\U00002789\\U0000278A-\\U00002793\\U000024F5-\\U000024FE]" withString:"" options:(current application’s NSRegularExpressionSearch) range:{0, aNSString’s |length|()}) as text
end holdNumberWithSignOnly

★Click Here to Open This Script 

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

丸つき数字を数値にデコードする v2

Posted on 11月 26, 2021 by Takaaki Naganoya

丸つき数字を数値にデコードするAppleScriptです。よくよく考えるとこれまでに作っていなかったので、作っておきました。

AppleScript名:丸つき数字を数値にデコードする v2.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2021/11/26
—
–  Copyright © 2021 Piyomaru Software, All Rights Reserved
—

set dRes to decodeNumFromNumWithSign("⑮") of me
–> 15

–丸つき数字を数値にデコードする v2
on decodeNumFromNumWithSign(aStr as string)
  set numStr1 to "①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚㉛㉜㉝㉞㉟㊱㊲㊳㊴㊵㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿"
  
set numStr2 to "❶❷❸❹❺❻❼❽❾❿⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴"
  
set numStr3 to "➀➁➂➃➄➅➆➇➈➉"
  
set numStr4 to "➊➋➌➍➎➏➐➑➒➓"
  
set numStr5 to "⓵⓶⓷⓸⓹⓺⓻⓼⓽⓾"
  
–set numStr6 to "⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇"
  
–set numStr7 to "1︎⃣2︎⃣3︎⃣4︎⃣5︎⃣8︎⃣9︎⃣"
  
–set numStr8 to "⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛"
  
  
set nList to {numStr1, numStr2, numStr3, numStr4, numStr5}
  
  
repeat with i in nList
    set numTemp to contents of i
    
if numTemp contains aStr then
      using terms from scripting additions
        set bNum to offset of aStr in numTemp
      end using terms from
      
return bNum
    end if
  end repeat
  
return false
end decodeNumFromNumWithSign

★Click Here to Open This Script 

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

丸つき数字の除去と数値からの変換

Posted on 11月 26, 2021 by Takaaki Naganoya

丸つき数字を指定文字列から削除するAppleScriptと、1〜50の範囲の数値を丸つき数字に変換するAppleScriptです。

Keynoteの表に入っている丸つき数字のリナンバーを行うために、必要な処理を書いてみたものです。日本語環境でしかこういう文字は使わないことでしょう。

丸つき数字が文字コード上でところどころ切れているため、単純に調べるのに手間がかかりました。

AppleScript名:数字を丸つき数字に変換.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2021/11/26
—
–  Copyright © 2021 Piyomaru Software, All Rights Reserved
—

repeat with i from -10 to 100 by 1
  set aStr to convNumToNumWithSign(i) of me
  
log {i, aStr}
end repeat

on convNumToNumWithSign(aNum as number)
  if (aNum ≤ 0) or (aNum > 50) then return ""
  
set aStr to "①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚㉛㉜㉝㉞㉟㊱㊲㊳㊴㊵㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿"
  
set bChar to character aNum of aStr
  
return bChar
end convNumToNumWithSign

★Click Here to Open This Script 

AppleScript名:丸つき数字を検出・削除
–  Original by: Shane Stanley
–  Created on: 2019/11/04
–  Modified by: Takaaki Naganoya
–  Modified on: 2021/11/26

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

set aRes to removeNumberWithSign("⓪①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚㉛㉜㉝㉞㉟㊱㊲㊳㊴㊵㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿⓿❶❷❸❹❺❻❼❽❾❿⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓") of me
–> "‍‍‍‍‍‍"

on removeNumberWithSign(aStr as text)
  set aNSString to current application’s NSString’s stringWithString:aStr
  
  
return (aNSString’s stringByReplacingOccurrencesOfString:"[\\U000024EA-\\U000024EA\\U00002460-\\U00002473\\U00003251-\\U000032BF\\U000024FF-\\U000024FF\\U00002776-\\U0000277F\\U000024EB-\\U000024F4\\U00002780-\\U00002789\\U0000278A-\\U00002793\\U000024F5-\\U000024FE]" withString:"" options:(current application’s NSRegularExpressionSearch) range:{0, aNSString’s |length|()}) as text
end removeNumberWithSign

★Click Here to Open This Script 

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

Macの製品名を求める(M1以降対応)v1a

Posted on 7月 29, 2021 by Takaaki Naganoya

実行中のMacの製品名を求めるAppleScriptです。もともと、AppleScriptで作成して使用しているアイデアプロセッサ「Kamenoko」で行っている処理なのですが、

M1上で実行すると、製品名は間違えるわ、仕様は合っていないわで散々でした。あ、マシンのアイコンは取ってきていますね。その他のデータはマシン移行をしたときにそのまま前のマシンのデータが残っていたためでしょう。

調べてみると、M1 Macでは従来どおりの製品名データを持っていないようで、Intel Macでは取得できていた製品の名前をわかりやすく記述するデータがありません。各国語にローカライズされていて便利だったのですが。

そこで、M1 MacかどうかのCPUタイプ検出を行い、そのうえで処理を分けることにしました。動作原理上、購入してセットアップしたてのマシンでこのファイルが存在しているかどうか、検証が必要だと思います。

AppleScript名:Macの製品名を求める(M1以降対応)v1a.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2021/07/28
—
–  Copyright © 2021 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.7" — macOS 10.13 or later
use framework "Foundation"
use scripting additions

set hRes to retModelName() of me
–> "Mac mini (M1, 2020)"–macOS 11.5
–> "Mac mini Intelデュアルコアプロセッサおよび統合型グラフィックス搭載、2014年後期に投入。"–macOS 12beta
–> "15インチMacBook Pro, Retinaディスプレイ, Intel Core i7 (Mid 2012)"–macOS 10.14.6

on retModelName()
  set cRes to CPU type of (system info)
  
  
if cRes begins with "ARM" then
    –Apple Silicon Mac
    
set sText to "defaults read ~/Library/Preferences/com.apple.SystemProfiler.plist" & " ’CPU Names’ | cut -sd ’\"’ -f 4"
    
set hRes to do shell script sText
    
return hRes
  else if cRes begins with "Intel" then
    –Intel Mac
    
set hRes to retModelInfo() of me
    
return hRes
  end if
end retModelName

on retModelInfo()
  tell application "System Events"
    set osVersion to system version of (system info)
  end tell
  
— macOS 10.15.3 –> 15
  
  
considering numeric strings
    if osVersion ≥ "10.15" then
      –macOS 11.0以降
      
set pListPath to "/System/Library/PrivateFrameworks/ServerInformation.framework/" & "Versions/A/Resources/ja.lproj/SIMachineAttributes.plist"
    else if osVersion > "10.14" then
      –macOS 10.14まで
      
set pListPath to "/System/Library/PrivateFrameworks/ServerInformation.framework/" & "Versions/A/Resources/Japanese.lproj/SIMachineAttributes.plist"
    end if
  end considering
  
  
set aRec to retDictFromPlist(pListPath) of me
  
set hwName to (do shell script "sysctl -n hw.model")
  
set aMachineRec to retRecordByLabel(aRec, hwName) of me
  
set aMachineRec2 to first item of aMachineRec
  
return |description| of _LOCALIZABLE_ of aMachineRec2
end retModelInfo

on retDictFromPlist(aPath)
  set thePath to current application’s NSString’s stringWithString:aPath
  
set thePath to thePath’s stringByExpandingTildeInPath()
  
set theDict to current application’s NSDictionary’s dictionaryWithContentsOfFile:thePath
  
return theDict as record
end retDictFromPlist

on retRecordByLabel(aRec as record, aKey as string)
  set aDic to current application’s NSDictionary’s dictionaryWithDictionary:aRec
  
set aVal to aDic’s valueForKey:aKey
  
return aVal as list
end retRecordByLabel

on retRecordByKeyPath(aRec as record, aKey as string)
  set aDic to current application’s NSDictionary’s dictionaryWithDictionary:aRec
  
set aVal to aDic’s valueForKeyPath:aKey
  
return aVal
end retRecordByKeyPath

–1D Listを文字列長でソート v2
on sort1DListByStringLength(aList as list, sortOrder as boolean)
  set aArray to current application’s NSArray’s arrayWithArray:aList
  
set desc1 to current application’s NSSortDescriptor’s sortDescriptorWithKey:"length" ascending:sortOrder
  
set desc2 to current application’s NSSortDescriptor’s sortDescriptorWithKey:"self" ascending:true selector:"localizedCaseInsensitiveCompare:"
  
set bArray to aArray’s sortedArrayUsingDescriptors:{desc1, desc2}
  
return bArray as anything
end sort1DListByStringLength

★Click Here to Open This Script 

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

新旧エミュレータでAppleScript実行速度対決

Posted on 6月 6, 2021 by Takaaki Naganoya

JavaScriptで書かれた68k Macエミュレータの新規軸「macitosh.js」が登場してきたので、SheepShaverと対決させてみました。

macintosh.js–Classic Mac OS 8 on Mac mini 2014 2.6GHz Intel Core i5 macOS 11.5
SheepShaver–Classic Mac OS 9.2 on MacBook Air mid 2011 1.6GHz Intel Core i5 macOS 10.13.6

それぞれ、Mactracker上に記載のあるGeekbenchのベンチマーク値は以下のとおりです。

ベンチマーク対決内容はAppleScriptで1,000万回単純ループを行うものです。

結果:macintosh.js 191秒

結果:sheepshaver 10秒

古いSheepShaverのほうが新しく作られたmacintosh.jsよりも20倍ぐらい高速、という結果が出ました。だからダメということはなく、JavaScriptなどという処理系でここまでネイティブコードに肉薄したということに驚きます。

シングルコア性能でMac mini 2014のほうが倍ぐらい速いのですが、さすがにネイティブコードでエミュレータを動かしているだけあって、MacBook Airのほうが10倍ぐらい高速です。同一マシンでベンチマークしたらsheepshaverのほうが20倍ぐらい高速でしょう。

macintosh.jsにはM1対応版(っていうのか?)もあり、M1 Mac miniで動作させればMac mini 2014の3倍ぐらい高速ですが、それでもMacBook Air上で動かしたsheepshaverのほうが3倍高速ということになります(多分)。

ちなみに、現代のIntel Mac(およびARM Mac)で1,000万回程度の単純ループを普通にAppleScriptで実行させると、速すぎて1秒以下になってしまい計測不能。1億回ぐらい回さないと1秒以下です(10億回ぐらい回さないとダメかも)。PowerPCの時代には1,000万回単純ループが計測の(個人的な)指標になっていました。


▲M1 Mac mini+Macintosh.jsで実行したら68秒。だいたい予想どおり


▲M1 Mac mini+SheepShaver(Universal Binary)で実行したら10秒。MacBook Air 2011+SheepShaverと同じ結果に

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

Keynoteで全スライドのタイトルアイテムの高さを統一

Posted on 3月 1, 2021 by Takaaki Naganoya

Keynoteの最前面の書類で、選択したマスタースライドに該当するスライドのタイトルのテキストフレームの高さ(height)を統一するAppleScriptです。

Cocoa Scripting本の監修者のedama2さんからタイトルの大きさが不揃いで見にくいという指摘があり、その対処のために組んでみました(泣)。


▲マスタースライド名でどのスライドを処理するか指定


▲スライドタイトルの高さを統一

AppleScript名:全スライドのデフォルトタイトルアイテムの高さを統一.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2021/03/01
—
–  Copyright © 2021 Piyomaru Software, All Rights Reserved
—

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

set targetHeight to 97

–最前面の書類のベーススライド(マスタースライド)名称一覧を取得してユニーク化
tell application "Keynote"
  set baseNames to (name of base slide of every slide of front document)
end tell
set aRes to uniquify1DList(baseNames) of me

–処理対象のマスタースライドを選択
set tSlide to (choose from list aRes with prompt "処理対象のベーススライド名を選択") as string

–最前面の書類の全スライドのうち、指定のマスタースライドを指定してあるもののタイトルの高さを統一
tell application "Keynote"
  tell front document
    –全スライドを取得してループ
    
set sList to every slide
    
repeat with i in sList
      set j to contents of i
      
tell j
        –スライドのマスタースライド名が指定のものに該当する場合にのみ処理
        
set bSlide to (name of base slide) as string
        
if bSlide is equal to tSlide then
          try
            ignoring application responses
              set height of default title item to targetHeight
            end ignoring
          end try
        end if
      end tell
    end repeat
  end tell
end tell

on uniquify1DList(theList as list)
  set theSet to current application’s NSOrderedSet’s orderedSetWithArray:theList
  
return (theSet’s array()) as list
end uniquify1DList

★Click Here to Open This Script 

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

指定文字のシフトJIS内文字かのチェック

Posted on 2月 28, 2021 by Takaaki Naganoya

指定の文字がシフトJISのコードの範囲に存在しているかどうかをチェックするAppleScriptです。

絵文字とか、日本国内で使われていない(CJK統合漢字のうち日本で使われていない)漢字を除外するために作ってみたものです。もともと、半角文字と全角文字の判定を行うためにNSASCIIStringEncodingに変換できるかどうかを調べるサンプルがあったので、「JIS第1/第2水準文字だけ調べるのに同様の処理で済むのでは?」と考えて試してみたものです。


▲実際のプログラムリスト。プログラムリスト下部のURL Linkをクリックすると、文字列が欠落していないすべての内容がスクリプトエディタ上に転送されます

AppleScript名:指定文字のシフトJIS内文字かのチェック.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2021/02/28
—
–  Copyright © 2021 Piyomaru Software, All Rights Reserved
—

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

set a1Res to chkSJISChar("微") of me
–> true

set a2Res to chkSJISChar("") of me
–> false

set a3Res to chkSJISChar("熙") of me
–> true

set a4Res to chkSJISChar("") of me
–> false

return {a1Res, a2Res, a3Res, a4Res}
–> {true, false, true, false}

on chkSJISChar(aChar as string)
  set aStr to current application’s NSString’s stringWithString:aChar
  
set tmpStr1 to (aStr’s canBeConvertedToEncoding:(current application’s NSShiftJISStringEncoding))
  
return tmpStr1 as boolean
end chkSJISChar

★Click Here to Open This Script 

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

構成要素を指定して漢字検索 v3

Posted on 2月 22, 2021 by Takaaki Naganoya

旧称「部首で漢字検索」のバージョンアップ版です。部首ではなく構成部品の文字を指定して漢字を検索するAppleScriptです。

便利な道具ではありますが、あくまでも子供の学習用以外の用途にお使いください。

–> Download kanjiSearchFromPartsV3.zip (AppleScript Bundle with library and JSON files in its bundle)

前バージョンでは常用漢字の範囲を超えるデータが出力されるという問題点があったため、常用漢字の一覧データを作成し、これに合致するものだけを出力するようにしました。

常用漢字との照合処理に時間がかかっており、v2ではAppleScriptのネイティブ機能でループして除外チェックを行なっておりました。これをv3ではCocoaの機能を用いて一括で重複部分の抽出を行うことで、v2の半分の時間で完了できることに。v2で0.6秒程度かかっていたものが、v3では0.3秒を下回る時間で処理できるようになりました(MacBook Pro Core i7 2.66GHz)。

そもそも論でいえば、元のJSONデータから常用漢字+人名漢字を超える文字の情報を削除すればいいだけの話なので、JSONデータから常用漢字+人名漢字を超える文字を削除するプログラムを書いて実行するのがよいのでしょう。

AppleScript名:構成要素を指定して漢字検索 v3.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2021/02/21
—
–  Copyright © 2021 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.7"
use framework "Foundation"
use scripting additions
use jkLib : script "jyoyoKanjiLib" –常用漢字一覧を返してくるAppleScriptライブラリ

script jsonStr
  property aJsonDict : missing value –JSONから読み取ったNSDictionary
  
property jKanji : missing value –常用漢字データ(NSArray)
end script

property NSString : a reference to current application’s NSString
property NSCountedSet : a reference to current application’s NSCountedSet
property NSJSONSerialization : a reference to current application’s NSJSONSerialization
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding

–図形としての構成要素を指定して漢字検索(部首ではない)
–set aRes to searchKanjiFromElementJ("木") of me –きへん? のぎへんや他のものも返ってくるよ
–> {"椅", "植", "椎", "検", "頼", "漆", "鉢", …}

–set bRes to searchKanjiFromElementJ("氵") of me –さんずい
–> {"滴", "漁", "漂", "漆", "漏", "演", "漠",…}

set dRes to searchKanjiFromElementJ("⻖") of me
–>{"堕", "墜", "阪", "防", "阻", "附", "降"…}

–検索に使える部首のキー文字の一覧を返す
–set qList to listupQueryKeysForKanji() of me
–> {"工", "棘", "左", "位", "婁", "攴", …}

on searchKanjiFromElementJ(aQueryStr)
  if (aJsonDict of jsonStr) = missing value then my init()
  
if (jKanji of jsonStr) = missing value then my initJ()
  
set aRes to (aJsonDict of jsonStr)’s valueForKey:aQueryStr
  
if aRes = missing value then return missing value
  
  
set cArray to aRes’s arrayByAddingObjectsFromArray:(jKanji of jsonStr)
  
set cRes to returnDuplicatesOnly(cArray) of me
  
return cRes
end searchKanjiFromElementJ

on searchKanjiFromElement(aQueryStr)
  if (aJsonDict of jsonStr) = missing value then my init()
  
set aRes to (aJsonDict of jsonStr)’s valueForKey:aQueryStr
  
if aRes = missing value then return missing value
  
return aRes as list
end searchKanjiFromElement

on listupQueryKeysForKanji()
  if (aJsonDict of jsonStr) = missing value then my init()
  
set aRes to (aJsonDict of jsonStr)’s allKeys()
  
return aRes as list
end listupQueryKeysForKanji

on initJ()
  set (jKanji of jsonStr) to current application’s NSArray’s arrayWithArray:(retJyouyouKanji() of jkLib)
end initJ

on init()
  –https://github.com/yagays/kanjivg-radical
  
set aPath to (POSIX path of (path to me)) & "Contents/Resources/element2kanji.json"
  
set jsonString to NSString’s alloc()’s initWithContentsOfFile:(aPath) encoding:(NSUTF8StringEncoding) |error|:(missing value)
  
set jsonData to jsonString’s dataUsingEncoding:(NSUTF8StringEncoding)
  
set (aJsonDict of jsonStr) to NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
end init

on returnDuplicatesOnly(anArray)
  set aSet to NSCountedSet’s alloc()’s initWithArray:anArray
  
set bList to (aSet’s allObjects()) as list
  
  
set dupList to {}
  
repeat with i in bList
    set aRes to (aSet’s countForObject:i)
    
if aRes > 1 then
      set the end of dupList to (contents of i)
    end if
  end repeat
  
  
return dupList
end returnDuplicatesOnly

★Click Here to Open This Script 

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

部首で漢字検索

Posted on 2月 21, 2021 by Takaaki Naganoya

漢字の部首を指定して、漢字を検索するAppleScriptです。厳密にいえば「部首」の文字ではなく、それっぽい文字で探せます。用途や利用者を想定できれば(子供が勉強用に使わないのであれば)十分に有用だと思います(理由は後述)。

Unicodeのデータから検索できるのではないかと考え、Unicodeの規格を調べていたのですが、漢字のSVGデータから構成文字情報を抽出したとされる「kanjivg-radical」を偶然みつけ、これを利用することで、割と手軽に実現できました。

–> kanjiSearch.zip(Download Script Bundle included JSON in its bundle)

開発環境のMac(Intel Core i7 2.66GHz)で、キャッシュがヒットしていれば(JSONから変換したデータがpropertyに読み込まれていれば)0.02秒程度で検索できています。この手の処理はデータのローディング(読み込み)が命なので、SSD使用必須です。

同データはJSON形式なので、AppleScriptバンドル中にJSONのまま突っ込んで、Cocoaの機能を用いてNSDictionaryに読み込んで検索しています。

ほかにも、Mac OS Xへの移行時に散々紹介されたMac OS Xのビックリドッキリ機能「関連文字に変換」をAppleScriptで実現した「関連文字を検索」も作ってみました。

このあたりをまとめてAppleScriptライブラリにしておけば便利そうですが、まだ使い勝手をテストしている段階です。義務教育で習う漢字の構成要素(へん、つくり etc)の呼び名とkanjivg-radicalで利用できる構成パーツの間に不整合(kanjivg-radicalの方が柔軟)があるので、そのあたりを埋めないと使いにくそう(下手に子供が使うと間違った国語知識を持ってしまう)な危険があるので、そのあたりを補う必要性を感じます。

たとえば、「禾」(のぎへん)を持つ漢字を「木」で検索できてしまうところです。大人は「実用的で使いやすい!」と喜ぶところですが、義務教育課程では両者は厳密に区別されています。自分は使いやすいので喜んで使っていますが、用途によっては使わないほうがよいかもしれません。

追記:

へんやつくりを元に検索できるデータとして、同梱の「radical2kanji_left_right.json」や「radical2kanji_top_bottom.json」が存在していることに気づいたので、そちらをAppleScriptのバンドル中に入れて、同様に検索してみました。

ただ、こちらのデータは随分と粗が多く、「⻖」(こざとへん)で自分の名前に使われている「隆」を「radical2kanji_left_right.json」から検索したところヒットしません。

{"阨", "陵", "隈", "険", "陣", "院", "陲", "陦", "陽", "陳", "陬", "隧", "險", "除", "隍", "陜", "陀", "陏", "隗", "階", "障", "隕", "降", "陂", "隴", "隔", "際", "隅", "附", "限", "陸", "陟", "陌", "阮", "阡", "阯", "阻", "阿", "阪", "防"}

国語辞書や文字コード表との照合といいますか、きちんとした検証作業は行われておらず、機械的に処理しただけのデータという印象を受けます。

一方で、「element2kanji.json」を用いて「⻖」(こざとへん)で検索したところ、

{"嶐", "阨", "蔭", "橢", "薩", "隣", "婀", "陵", "隈", "窿", "険", "隠", "陷", "陣", "痾", "院", "陶", "隙", "陲", "陦", "陽", "陪", "陳", "隘", "陥", "陬", "墜", "隧", "陰", "險", "除", "隍", "陜", "陀", "陛", "陏", "隗", "階", "障", "隕", "降", "陂", "隨", "隴", "隔", "随", "際", "隋", "陞", "隰", "墮", "隱", "陝", "隅", "隊", "附", "限", "陋", "陸", "陟", "隲", "陌", "隆", "阮", "阡", "阯", "阻", "阿", "阪", "堕", "防"}

と、結果が返ってきており……どうも複数のJSONデータを用いて、へんやつくりを考慮したJSONデータで検索して、ヒットしなかったら「element2kanji.json」を用いて物量でダメ押しするように設計されているようです。つまり、「radical2kanji_left_right.json」や「radical2kanji_top_bottom.json」が粗いのを複数のデータで補うように使うものである、と。

無限の量とバリエーションを持つデータに対するアプローチとしては間違っていないと思いますが、文字コードという有限のデータに対しての処理としては少し疑問が残る実装です。本当に使い物になるデータにするには、実際に人間の手による検証と校正が必要な内容でしょう。そのことは明記されるべきです。

「element2kanji.json」は現状のままで有用だと思いますが、「radical2kanji_left_right.json」や「radical2kanji_top_bottom.json」については、実際に国語辞典と照合してデータを補わないと実用レベルにはならないと感じました。盲目的に信用しないで、手元で実際に評価・検証することが重要です。

データ自体、CJK(中国語、日本語、韓国語)の統合漢字をサポートする範囲で作成されているようで、日本語で日常的に利用する常用漢字よりも幅広い文字がデータ化されています。常用漢字の範囲内に含まれているかをチェックするデータを併用するのが妥当でしょう。

AppleScript名:部首で漢字検索.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2021/02/21
—
–  Copyright © 2021 Piyomaru Software, All Rights Reserved
—

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

script jsonStr
  property aJsonDict : missing value
end script

property NSString : a reference to current application’s NSString
property NSJSONSerialization : a reference to current application’s NSJSONSerialization
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding

–部首を指定して漢字検索
set aRes to searchKanjiFromElement("木") of me –きへん
–> {"稾", "欅", "謀", "酥", "悚", "椁", "検"….}

–set bRes to searchKanjiFromElement("氵") of me–さんずい
–> {"溯", "湮", "漁", "漕", "濶", "懣", "添", "淨",…..}

–set cRes to searchKanjiFromElement("之") of me
–> {"芝", "泛", "貶", "乏"}

–set dRes to searchKanjiFromElement("⻖") of me
–> {"嶐", "阨", "蔭", "橢", "薩", "隣", "婀"…}

–検索に使える部首のキー文字の一覧を返す
–set qList to listupQueryKeysForKanji() of me
–> {"工", "棘", "左", "位", "婁", "攴", "巨", "攵"…}

on searchKanjiFromElement(aQueryStr)
  if (aJsonDict of jsonStr) = missing value then my init()
  
set aRes to (aJsonDict of jsonStr)’s valueForKey:aQueryStr
  
if aRes = missing value then return missing value
  
return aRes as list
end searchKanjiFromElement

on listupQueryKeysForKanji()
  if (aJsonDict of jsonStr) = missing value then my init()
  
set aRes to (aJsonDict of jsonStr)’s allKeys()
  
return aRes as list
end listupQueryKeysForKanji

on init()
  –https://github.com/yagays/kanjivg-radical
  
set aPath to (POSIX path of (path to me)) & "Contents/Resources/element2kanji.json"
  
set jsonString to NSString’s alloc()’s initWithContentsOfFile:(aPath) encoding:(NSUTF8StringEncoding) |error|:(missing value)
  
set jsonData to jsonString’s dataUsingEncoding:(NSUTF8StringEncoding)
  
set (aJsonDict of jsonStr) to NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
end init

★Click Here to Open This Script 

Posted in File path JSON Record | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSJSONSerialization NSString NSUTF8StringEncoding | Leave a comment

ページ範囲処理 v2

Posted on 2月 14, 2021 by Takaaki Naganoya

処理対象ページをユーザーに文字入力させた場合に、

X1,X2,X3,Y-Z

のようなフォーマットを解釈して、処理対象ページ番号をすべて展開するAppleScriptです。

もともと16年前に作成したScriptを書き換えたものです。オリジナルもとくに現行環境で問題なく動いているのですが、ソートルーチンを高速なものに差し替えています。ただし、処理データの量がたいして多くないことを前提としているため(数万ページ指定しないとCocoaのソートルーチンを利用するメリットがない)、Cocoaのソートルーチンは使っていません。

AppleScript名:ページ範囲処理 v2
—
–  Created by: Takaaki Naganoya
–  Created on: 2005/11/04
–  Modified on: 2021/02/14
—
–  Copyright © 2021 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set parsedList to parsePageRangeString("1-10, 35, 37, 39, 100-110") of me
–> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 35, 37, 39, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110}

–ページ範囲指定のテキスト(多分)を展開して実際のページ数の一覧リストに
on parsePageRangeString(pageText as string)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to ("," as string)
  
set aList to text items of pageText
  
set AppleScript’s text item delimiters to curDelim
  
  
set eList to {}
  
repeat with i in aList
    set j to contents of i
    
if ("-" as string) is in j then
      set eList to eList & parseByHyphen(j) of me
    else
      set the end of eList to j as number
    end if
  end repeat
  
  
set eList to removeDuplicates(eList) of me
  
set eList to shellSortAscending(eList) of me
  
  
return eList
end parsePageRangeString

–重複部分を削除
on removeDuplicates(aList)
  set newList to {}
  
repeat with i from 1 to (length of aList)
    set anItem to item 1 of aList
    
set aList to rest of aList
    
if {anItem} is not in aList then set end of newList to anItem
  end repeat
  
return newList
end removeDuplicates

–ハイフンを実際の数値に変換
on parseByHyphen(aText)
  set aText to aText as string
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to ("-" as string)
  
set aList to text items of aText
  
set AppleScript’s text item delimiters to curDelim
  
  
set sList to {}
  
repeat with i from ((item 1 of aList) as number) to ((item 2 of aList) as number)
    set the end of sList to i
  end repeat
  
return sList
end parseByHyphen

–入れ子ではないリストの昇順ソート
on shellSortAscending(aSortList)
  script oBj
    property list : aSortList
  end script
  
  
set len to count oBj’s list’s items
  
set gap to 1
  
  
repeat while (gap ≤ len)
    set gap to ((gap * 3) + 1)
  end repeat
  
  
repeat while (gap > 0)
    set gap to (gap div 3)
    
if (gap < len) then
      repeat with i from gap to (len – 1)
        set temp to oBj’s list’s item (i + 1)
        
set j to i
        
repeat while ((j ≥ gap) and (oBj’s list’s item (j – gap + 1) > temp))
          set oBj’s list’s item (j + 1) to oBj’s list’s item (j – gap + 1)
          
set j to j – gap
        end repeat
        
set oBj’s list’s item (j + 1) to temp
      end repeat
    end if
  end repeat
  
  
return oBj’s list
end shellSortAscending

★Click Here to Open This Script 

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

日本語簡易パーサーeasyJParse v5

Posted on 12月 31, 2020 by Takaaki Naganoya

簡易日本語パーサー「easyJParse」のバージョンアップ版です。AppleScriptライブラリ「BridgePlus」を利用しないように改めました。

簡易日本語パーサーというのは、日本語の文を単語に分解するプログラムですが、品詞情報や係り受けの情報が得られるわけではなく、単に単語に分解するだけのもので、用途を日本語コマンド解釈などに限定した簡易版の形態素解析器もどきソフトウェアです。特定の人名など区切られて困る単語についてはカギ括弧などで括ることで(例:「ぴよまるソフトウェア」)まとまった単語として出力する機能を持たせています。

→ easyJParse v3
→ easyJParse v4

前バージョンまではBridgePlus Script Libraryを利用していましたが、同ライブラリがFrameworkを含んでいるために、確実に動かせるように設定するには技量(理解と慣れ)が必要です。自分の手元では動かせていますが、ユーザーによってはBridgePlusをmacOS 10.15以降のMacで利用できないケースも見られ(たぶん、操作間違い)、BridgePlusへの依存がマイナスポイントになりつつあるように感じられます。

本ScriptでBridgePlusから利用しているメソッドは2つ。どちらも既存のAppleScriptのルーチンの組み合わせで再現できる程度の簡単なもの。これらをすべて既存のルーチンの組み合わせで置き換えました。BridgePlus内蔵の機能を書き換える際に、扱うデータサイズはあまり大きくないものであることを前提に最適化しました。あまり巨大なデータを扱うのには向いていませんが、小さなデータを高速に処理できるようにしてあります。

MacBookPro10,1,  macOS Version 10.14.6 (Build 18G8005),  100 iterations
         First Run   Total Time    Average     Median    Maximum    Minimum   Std.Dev.
First       0.6685       0.6236     0.0062     0.0059     0.0083     0.0054     0.0008

正直なところ、この程度の極小データサイズだとCocoaの機能を利用するメリットがあまりないので、Cocoaを使わないように書き換えると高速化できます。高速化は必要に応じて行う程度でしょう。

外部ライブラリに依存しなくなったため、たとえばCotEditorのメニューから呼び出すScriptや、FileMaker Pro Scriptの中にまるごと日本語パーサーを突っ込むといった真似ができます。

AppleScript名:easyJParse v5.scptd
— Created 2018-09-26 by Takaaki Naganoya
— Modified 2020-12-31 by Takaaki Naganoya
— 2020 Piyomaru Software
use AppleScript version "2.5" — El Capitan (10.11) or later
use framework "Foundation"
use scripting additions

property NSArray : a reference to current application’s NSArray
property NSSortDescriptor : a reference to current application’s NSSortDescriptor

set aTargName to "Finderで選択中のAI書類上の「製品名」レイヤーから抜き出したコードをもとにスペック情報をGoogle Spreadsheet「製品コード表」から展開して保存。"
set aList to parseJ(aTargName, true) of me
–> {"Finder", "で", "選択", "中", "の", "AI", "書類", "上", "の", "「", "製品名", "」", "レイヤー", "から", "抜き出し", "た", "コード", "を", "もと", "に", "スペック", "情報", "を", "Google", " ", "Spreadsheet", "「", "製品コード表", "」", "から", "展開", "し", "て", "保存", "。"}–v4
–> {"Finder", "で", "選択", "中", "の", "AI", "書類", "上", "の", "「", "製品名", "」", "レイヤー", "から", "抜き出し", "た", "コード", "を", "もと", "に", "スペック", "情報", "を", "Google", " ", "Spreadsheet", "「", "製品コード表", "」", "から", "展開", "し", "て", "保存", "。"}–v5

return aList

set aTargName to "私の名前は「長野谷」です。"
set aList to parseJ(aTargName, true) of me
–> {"私", "の", "名前", "は", "「", "長野谷", "」", "です", "。"}–v4
–> {"私", "の", "名前", "は", "「", "長野谷", "」", "です", "。"}–v5

–カッコのネスティングとクロス(エラー)については、処理せずにそのまま出力
on parseJ(aTargStr as string, pickupPhraseByBracketPair as boolean)
  copy aTargStr to tStr
  
  
set cList to characters of tStr
  
set wList to words of tStr
  
  
set cLen to length of cList
  
  
set w2List to {}
  
set w3List to {}
  
set aCount to 0
  
  
set lastPos to 0
  
  
repeat with i in wList
    set j to contents of i
    
    
using terms from scripting additions
      set anOffset to offset of j in tStr
    end using terms from
    
    
if anOffset is not equal to 1 then
      set aChar to character (lastPos + 1) of aTargStr
      
      
set the end of w3List to {wordList:aChar, characterList:{aChar}, startPos:(lastPos + 1), endPos:(lastPos + 1)}
    end if
    
    
set aLen to length of j
    
    
set w2List to w2List & (characters of j)
    
set startPointer to (anOffset + aCount)
    
set endPointer to (anOffset + aCount + aLen – 1)
    
    
set the end of w3List to {wordList:j, characterList:(characters of j), startPos:startPointer, endPos:endPointer}
    
    
set trimStart to (anOffset + aLen)
    
    
if trimStart > (length of tStr) then
      set trimStart to 1
    end if
    
    
set tStr to text trimStart thru -1 of tStr
    
    
set aCount to aCount + anOffset + aLen – 1
    
copy endPointer to lastPos
  end repeat
  
  
–句読点など。文末の処理
  
if endPointer is not equal to cLen then
    set the end of w3List to {wordList:tStr, characterList:(characters of tStr), startPos:(lastPos + aCount), endPos:aLen}
  end if
  
  
set bArray to sortRecListByLabel((w3List), "startPos", true) of me
  
set cArray to (bArray’s valueForKeyPath:"wordList") as list
  
  
–カッコでくくった範囲を1つの塊として連結する
  
set bracketList to {"「", "」", "『", "』", "【", "】", "《", "》", "〈", "〉", "(", ")"}
  
set bList to jointItemsBetweenBrackets(cArray, bracketList) of me
  
  
return bList
end parseJ

–リストに入れたレコードを、指定の属性ラベルの値でソート
on sortRecListByLabel(aRecList as list, aLabelStr as string, ascendF as boolean)
  set aArray to NSArray’s arrayWithArray:aRecList
  
set sortDesc to NSSortDescriptor’s alloc()’s initWithKey:aLabelStr ascending:ascendF
  
set sortDescArray to NSArray’s arrayWithObject:sortDesc
  
set sortedArray to aArray’s sortedArrayUsingDescriptors:sortDescArray
  
return sortedArray
end sortRecListByLabel

on offset of bArg in anArg
  set aClass to class of anArg
  
set bClass to class of bArg
  
  
if {aClass, bClass} = {text, text} then –case 1
    return getOffset(anArg, bArg) of me
  else if {aClass, bClass} = {list, list} then –case 2 (The target case)
    return execOffsetList(bArg, anArg) of me
  else if {aClass, bClass} = {text, list} then –case 3 (Illegular case)
    return execOffsetList(bArg, {anArg}) of me
  else if {aClass, bClass} = {list, text} then –case 4 (Illegular case)
    return execOffsetList({bArg}, anArg) of me
  end if
end offset

–1D List同士のoffset演算を行うルーチンの本体
on execOffsetList(aList as list, bList as list)
  set resList to {}
  
repeat with i in aList
    set j to contents of i
    
set aCount to 1
    
    
repeat with ii in bList
      set jj to contents of ii
      
if jj = j then
        set the end of resList to aCount
        
exit repeat
      end if
      
set aCount to aCount + 1
    end repeat
  end repeat
  
  
–見つかったItem No.が連続値かどうかチェック
  
set sRes to chkSequential(resList) of me
  
if sRes = true then
    return contents of first item of resList
  else
    return false
  end if
end execOffsetList

–与えられた1D Listが連続値かどうかをチェックする
on chkSequential(aList)
  if length of aList = 1 then return true
  
if aList = {} then return false
  
  
set aFirst to first item of aList
  
set aList to rest of aList
  
  
repeat with i in aList
    set j to contents of i
    
if j is not equal to (aFirst + 1) then
      return false
    end if
    
copy j to aFirst
  end repeat
  
  
return true
end chkSequential

–テキスト同士のoffset ofを(2.5x fasterで)実行する
on getOffset(str, searchStr)
  set d to divideBy(str, searchStr)
  
if (count d) is less than 2 then return 0
  
return (length of item 1 of d) + 1
end getOffset

on divideBy(str, separator)
  set delSave to AppleScript’s text item delimiters
  
set the AppleScript’s text item delimiters to separator
  
set strItems to every text item of str
  
set the AppleScript’s text item delimiters to delSave
  
return strItems
end divideBy

–カッコでくくった範囲を1つの塊として連結する
on jointItemsBetweenBrackets(aList as list, bracketList as list)
  
  
  
–リスト内のブラケット位置の検出
  
set aRes to (my indexesOfItems:bracketList inArray:aList base:0) as list
  
–> {9, 12, 15, 18, 22, 25, 27, 29}–0 based
  
  
if aRes = {} then return aList
  
  
–位置情報リストを開始位置, 終了位置のペアの2D Listに変換する
  
set cList to my subarraysFrom:(aRes) groupedBy:2
  
–> {{9, 12}, {15, 18}, {22, 25}, {27, 29}}–0 based
  
  
–カッコの位置がクロスしていないかチェック(入れ子状態はエラーになる)
  
set dRes to checkCrossRange(cList) of me
  
if dRes = false then return aList
  
  
set ccList to reverse of cList –順次、ブラケットに囲まれた要素を連結していくので、アイテム数が随時変化する。アイテム番号が狂わないよう後方から処理する必要がある。そのために、リストの要素を逆順に組み替える
  
–> {{27, 29}, {22, 25}, {15, 18}, {9, 12}}–0 based
  
  
—
  
copy aList to aaList
  
  
repeat with i in ccList
    copy i to {s2Dat, e2Dat}
    
    
set s2Dat to s2Dat + 1 –Array index conversion from 0 to 1 based
    
set e2Dat to e2Dat + 1 –Array index conversion from 0 to 1 based
    
    
set tmp1 to items 1 thru s2Dat of aaList
    
set tmp2 to (items (s2Dat + 1) thru (e2Dat – 1) of aaList) as string
    
set tmp3 to items e2Dat thru -1 of aaList
    
    
set aaList to tmp1 & tmp2 & tmp3
  end repeat
  
  
return aaList
end jointItemsBetweenBrackets

–{始点, 終点}のペアの2D Listが違いにクロスしていないかチェック
on checkCrossRange(aList as list)
  set rList to {}
  
repeat with i in aList
    copy i to {sRange, eRange}
    
set tmpRange to current application’s NSMakeRange(sRange, eRange – sRange + 1)
    
set the end of rList to tmpRange
  end repeat
  
  
repeat with ii in rList
    set jj to contents of ii
    
repeat with i in rList
      set j to contents of i
      
      
if jj is not equal to j then
        set aRes to current application’s NSIntersectionRange(jj, j)
        
        
if aRes is not equal to {location:0, |length|:0} then
          return false
        end if
      end if
      
    end repeat
  end repeat
  
  
return true
end checkCrossRange

–BridgePlus内の命令を展開
on indexesOfItems:(iList as list) inArray:(aList as list) base:(baseNum as integer)
  return retIndexesOfNumInArray(iList, aList, baseNum) of me
end indexesOfItems:inArray:base:

–1Dリスト中のシーケンシャルサーチ(複数)
on retIndexesOfNumInArray(aTargetList, aList, baseNum)
  script obj
    property list : aList
    
property resList : {}
  end script
  
  
if baseNum is not in {0, 1} then return false
  
  
–set obj’s list to aList
  
set (resList of obj) to {}
  
set aCount to baseNum
  
set hitF to false
  
  
repeat with i in obj’s list
    set j to contents of i
    
if j is in aTargetList then
      set the end of (resList of obj) to aCount
    end if
    
    
set aCount to aCount + 1
  end repeat
  
  
return (resList of obj)
end retIndexesOfNumInArray

on subarraysFrom:(aList as list) groupedBy:(gNum as integer)
  script spdObj
    property list : aList
    
property bList : {}
  end script
  
  
  
–Group Num check
  
if gNum = 0 then return false
  
if length of aList < gNum then return false
  
  
if (length of aList) mod gNum is not equal to 0 then return
  
  
set (bList of spdObj) to {}
  
  
set tmpList to {}
  
set aCount to 1
  
  
repeat with i in aList
    set j to contents of i
    
set the end of tmpList to j
    
set aCount to aCount + 1
    
    
if aCount > gNum then
      set the end of (bList of spdObj) to tmpList
      
set tmpList to {}
      
set aCount to 1
    end if
  end repeat
  
  
return (bList of spdObj)
end subarraysFrom:groupedBy:

★Click Here to Open This Script 

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

Pixelmator ProのSVG to PNG変換

Posted on 12月 28, 2020 by Takaaki Naganoya

Pixelmator ProでSVGのファイルをPNG形式で書き出すAppleScriptです。

この、ダイアログでファイルを選択して書き出しファイル名を入力させるタイプのAppleScriptをたくさん掲載していますが、もともとAppleScriptの一括処理的なプログラムで、いちいちダイアログを出して1つ1つのファイルを保存させるようなことはやりません。あくまで、サンプルScriptの動作を完結させるための仕様です。

実際には、指定フォルダ以下にあるSVGファイルをSpotlightで抽出して、まとめて書き出し先のフォルダにPNG形式で書き出すといった処理になるでしょう。

SVG方面では1024jpさんのGapplinがあり、こちらもAppleScript対応しており各種操作が行えるようになっているのですが、Sandbox対応度に問題があるためかファイル書き出し操作がAppleScriptから行えていないので、現状では大量のSVG書類の変換にはPhotoshopかPixelmator Proということになりそうです。

SVGを読み込んで他の画像形式に書き出すためのCocoa Frameworkを利用できるとよさそうですが、いまひとつうまく動くものを知りません。


▲SVG対応のアプリケーション。SVGを読めるもの、書けるもの、書き出せるもの、と対応度はさまざま

AppleScript名:PixelmatorのSVG to PNG変換
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/12/01
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.7" — Yosemite (10.13) or later
use framework "Foundation"
use scripting additions

set aFile to choose file of type {"public.svg-image"}
set outPath to choose file name with prompt "select output file name"

tell application "Pixelmator Pro"
  open aFile
  
  
tell front document
    export to outPath as PNG
    
close without saving
  end tell
end tell

★Click Here to Open This Script 

AppleScript名:GaplinのSVG to PNG変換
set aFile to choose file of type {"public.svg-image"}
set outPath to choose file name with prompt "select output file name"

tell application "Gapplin"
  open aFile
  
  
tell front document
    export to outPath as PNG with options {class:export options, scale:1.0}
    
close without saving
  end tell
end tell

★Click Here to Open This Script 

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

Numbersで選択範囲に背景色を塗られているセル数をカウント

Posted on 12月 14, 2020 by Takaaki Naganoya

Numbersでオープン中の最前面の書類の現在のシート上の選択状態にある表の選択範囲から、背景色(background color)が塗られているセルを数えるAppleScriptです。

用途は、WebGL + three.jsで作られた3Dの回転選択メニューのデータ確認のためです。Numbers上で表示範囲の表を作って、その上で背景色を塗ることで「どの位置にデータを表示するか」を指定します。そのさいに、並べるセル数が表示用のJavaScriptと合っていないと面倒なので、本Scriptで色つきセルをかぞえています。

Numbers上で背景色(background color)が塗られているセルは16ビットで色の値が返ってきますし、塗られていないセルはmissing valueが返ってきます。

AppleScript名:Numbersで選択範囲に背景色を塗られているセル数をカウント
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/12/06
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

tell application "Numbers"
  tell front document
    –現在表示中のシートを対象にする
    
tell active sheet
      –Tableを特定する
      
try
        set theTable to first table whose class of selection range is range
      on error
        display notification "Numbers: There is no selection"
        
return {}
      end try
      
      
tell theTable
        –選択範囲のデータを1D Listで取得する
        
set aRes to background color of cells of selection range
      end tell
      
      
      
–Count Background
      
set aCount to 0
      
repeat with i in aRes
        set j to contents of i
        
        
if j is not equal to missing value then
          set aCount to aCount + 1
        end if
      end repeat
      
      
return aCount
    end tell
  end tell
end tell

★Click Here to Open This Script 

同様に、着色セルの座標値(x座標, y座標)を返すものも作って使用しています。

AppleScript名:Numbersで選択中のセルのうち背景色を塗られているもののx,y座標を2D Listで返す
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/12/06
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

tell application "Numbers"
  tell front document
    –現在表示中のシートを対象にする
    
tell active sheet
      –Tableを特定する
      
try
        set theTable to first table whose class of selection range is range
      on error
        display notification "Numbers: There is no selection"
        
return {}
      end try
      
      
tell theTable
        tell selection range
          set cellRes to background color of cells
          
set aWidth to count every column
          
set aHeight to count every row
        end tell
      end tell
      
      
–Check selected cell’s background color
      
set cellL to {}
      
set adrCount to 1
      
repeat with y from 1 to aHeight
        repeat with x from 1 to aWidth
          set aTmp to contents of (item adrCount of cellRes)
          
          
if aTmp is not equal to missing value then
            set the end of cellL to {x, y}
          end if
          
          
set adrCount to adrCount + 1
        end repeat
      end repeat
      
      
return cellL
      
–> {{1, 1}, {2, 1}, {3, 1}, {6, 1}, {8, 1}, {12, 1}, {15, 1}, {16, 1}, {20, 1}, {21, 1}, {24, 1}, {27, 1}, {28, 1}, {29, 1}, {1, 2}, {4, 2}, {6, 2}, {9, 2}, {11, 2}, {14, 2}, {17, 2}, {19, 2}, {23, 2}, {25, 2}, {27, 2}, {1, 3}, {2, 3}, {3, 3}, {6, 3}, {10, 3}, {14, 3}, {17, 3}, {19, 3}, {20, 3}, {23, 3}, {25, 3}, {27, 3}, {28, 3}, {29, 3}, {1, 4}, {6, 4}, {10, 4}, {14, 4}, {17, 4}, {21, 4}, {23, 4}, {25, 4}, {27, 4}, {1, 5}, {6, 5}, {10, 5}, {15, 5}, {16, 5}, {19, 5}, {20, 5}, {21, 5}, {24, 5}, {27, 5}, {1, 7}, {5, 7}, {8, 7}, {11, 7}, {12, 7}, {15, 7}, {17, 7}, {19, 7}, {20, 7}, {21, 7}, {23, 7}, {27, 7}, {1, 8}, {2, 8}, {4, 8}, {5, 8}, {7, 8}, {9, 8}, {11, 8}, {13, 8}, {15, 8}, {17, 8}, {20, 8}, {23, 8}, {27, 8}, {1, 9}, {3, 9}, {5, 9}, {7, 9}, {8, 9}, {9, 9}, {11, 9}, {12, 9}, {15, 9}, {17, 9}, {20, 9}, {23, 9}, {25, 9}, {27, 9}, {1, 10}, {5, 10}, {7, 10}, {9, 10}, {11, 10}, {13, 10}, {15, 10}, {17, 10}, {20, 10}, {23, 10}, {24, 10}, {26, 10}, {27, 10}, {1, 11}, {5, 11}, {7, 11}, {9, 11}, {11, 11}, {13, 11}, {16, 11}, {20, 11}, {23, 11}, {27, 11}}
    end tell
  end tell
end tell

★Click Here to Open This Script 

Posted in Color list | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy Numbers | Leave a comment

HTMLカラー値から明度を取得

Posted on 12月 8, 2020 by Takaaki Naganoya

HTMLカラー値からNSColorを作成し、Gray Scaleに変換したのちに明度情報を取得するAppleScriptです。

RGB値をHSV(HSB)に変換して明度情報を取得するバージョンも試してみたのですが、個人的にはこちらの処理の方がしっくりくる感じでした。

# コメント部分のWhiteとBlackの記述が逆だったので修正しておきました

AppleScript名:HTMLカラー値から明度を取得 v1.1.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/12/07
—
–  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

property NSColor : a reference to current application’s NSColor
property NSString : a reference to current application’s NSString
property NSAttributedString : a reference to current application’s NSAttributedString
property NSUTF16StringEncoding : a reference to current application’s NSUTF16StringEncoding
property NSDeviceWhiteColorSpace : a reference to current application’s NSDeviceWhiteColorSpace

set aCol to "#412a23"
set wCol to calcBrightnessFromHTMLColorCodeStr(aCol) of me
–> 0.245871186256

set aCol to "#000000" –Black
set wCol to calcBrightnessFromHTMLColorCodeStr(aCol) of me
–> 0.0

set aCol to "#FFFFFF" –White
set wCol to calcBrightnessFromHTMLColorCodeStr(aCol) of me
–> 1.0

set aCol to "#EEA096"
set wCol to calcBrightnessFromHTMLColorCodeStr(aCol) of me
–> 0.759391903877

on calcBrightnessFromHTMLColorCodeStr(aStr as string)
  set {rVal, gVal, bVal} to rgbHex2nunList(aStr) of me
  
–NSColorを作成
  
set aCol to makeNSColorFromRGBAval(rVal, gVal, bVal, 255, 255) of me
  
— グレースケール化
  
set gCol to aCol’s colorUsingColorSpaceName:(NSDeviceWhiteColorSpace)
  
set wComp to gCol’s whiteComponent() –whiteComponentを取得することで擬似的に明度情報を取得  
  
return wComp
end calcBrightnessFromHTMLColorCodeStr

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

on decodeCharacterReference(aStr)
  set anNSString to NSString’s stringWithString:aStr
  
set theData to anNSString’s dataUsingEncoding:(NSUTF16StringEncoding)
  
set styledString to NSAttributedString’s alloc()’s initWithHTML:theData documentAttributes:(missing value)
  
set plainText to (styledString’s |string|()) as string
  
return plainText
end decodeCharacterReference

–HTMLコードのRGB 16進数コードを数値リストに変換
on rgbHex2nunList(aHexStr)
  –エラーチェック
  
if aHexStr does not start with "#" then return false
  
if length of aHexStr is not equal to 7 then return false
  
set bHex to text 2 thru -1 of aHexStr
  
  
set {rStr, gStr, bStr} to {text 1 thru 2 of bHex, text 3 thru 4 of bHex, text 5 thru 6 of bHex}
  
  
set bList to {}
  
repeat with i in {rStr, gStr, bStr}
    set j to contents of i
    
set the end of bList to aHexStrToNum(j) of me
  end repeat
  
  
return bList
end rgbHex2nunList

–16進数文字列を10進数数値に変換する
on aHexStrToNum(hexStr)
  set hStr to "0123456789ABCDEF"
  
  
set aNum to 0
  
set aLen to length of hexStr
  
  
repeat with i from aLen to 1 by -1
    
    
set aCon to contents of character i of hexStr
    
using terms from scripting additions
      set aVal to (offset of aCon in hStr) – 1
    end using terms from
    
set aNum to aNum + aVal * (16 ^ (aLen – i))
    
  end repeat
  
  
return aNum as integer
end aHexStrToNum

★Click Here to Open This Script 

Posted in Color | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSAttributedString NSColor NSDeviceWhiteColorSpace NSString NSUTF16StringEncoding | Leave a comment

Pixelmator Pro v2.0.1でAppleScript用語辞書に命令語追加

Posted on 12月 2, 2020 by Takaaki Naganoya

Pixelmator Proはバージョン1.8でAppleScriptに対応しましたが、その後のアップデートでも用語辞書に変更が加えられています。

v2.0では以前に作ったアイコンの各解像度画像の書き出しScriptがうまく動作していませんでしたが、v2.0.1ではうまく(エラーを出さずに)動作していることを確認しています。バグレポートしてから反映されるまでの時間が短くて、フットワークの軽さに感心しました。こういうところ、Piyomaru Softwareとは比べ物になりません。

■v1.8→v2.0


「elipse shape layer」(楕円レイヤー)に同義語(synonym)が追加定義されました。「circle shape layer」「oval shape layer」と入力して構文確認すると「elipse shape layer」として解釈されます。

■v2.0→v2.0.1


「select color range」コマンドが追加定義されました。写真のようなデータを相手に色域を指定して選択できるようです。このrangeで指定する値が、色差(ΔE)なのか、何か他の指標の数値なのかがいまひとつわかりません。

自分が作った色域指定のAppleScriptでは、文字色の選択のために作ったものなので、もう少し仕様が違います。

select color range v : Select all areas of a specified color. This command can be executed on the document (in which case every layer is sampled) or on a layer, in which case the selection is created based on the layer's content.
select color range document
color list of integer : The color of the areas that should be selected.
[range integer] : The range of the colors that should be selected. With a range of 1, only areas that are exactly of the specified color will be selected. As the range is increased, increasingly more similarly-colored areas will be selected.
[smooth edges boolean] : Whether the edges of the selection should be smoothed.

rangeはrangeとしか書かれていないですね。100を指定するとキャンバス全体が選択されてしまうので、数値範囲は事実上1〜99ということになると思います(AppleScript用語辞書に有効範囲ぐらいは書いておいてほしいなー)。

rangeの値をどう指定するかで、どのぐらいの範囲の「色」を選択できるかが変わってくるので、自分もテストデータの選択色範囲を見ながら値を調整したので、いま指定しているrangeの値が正しいという保証はありません。

もともと、対話的に値を模索するような値なので、画像で使われている色数の分布などの情報をあらかじめ取得して分析しておき、その中でどの程度の色をピックアップするのか知っておく必要があるでしょう。そこまで徹底的に分析してからでないと、このselect color rangeコマンドをバッチ処理的な世界観の中で有効利用することは難しいと思います。

このコマンドを実装するぐらいなら、画像をOCR処理してテキストを取り出して、指定のキーワードが入っているエリアをぼかし処理するといった「OCRフィルタリング」の機能の方がいいかも。画面キャプチャ画像で特定の文字が入っている部分をぼかし処理するパターンがとても多いので、これは自分でも組んでおきたい処理ではあります(OCR次第。OS標準搭載機能だけでなんとかできるとよさそう)。

AppleScript名:選択中のレイヤーから赤っぽい色を選択.scpt
tell application "Pixelmator Pro"
  tell front document
    tell current layer
      select color range color {65535, 0, 0} range 90
    end tell
  end tell
end tell

★Click Here to Open This Script 

AppleScript名:選択中のレイヤーから緑色っぽい色を選択.scpt
tell application "Pixelmator Pro"
  tell front document
    tell current layer
      select color range color {0, 65535, 0} range 90
    end tell
  end tell
end tell

★Click Here to Open This Script 

AppleScript名:選択中のレイヤーから青っぽい色を選択.scpt
tell application "Pixelmator Pro"
  tell front document
    tell current layer
      select color range color {0, 0, 65535} range 80
    end tell
  end tell
end tell

★Click Here to Open This Script 

Posted in Color | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy Pixelmator Pro | Leave a comment

Post navigation

  • Older posts

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

Google Search

Popular posts

  • 開発機としてM2 Mac miniが来たのでガチレビュー
  • macOS 15, Sequoia
  • 指定のWordファイルをPDFに書き出す
  • Pages本執筆中に、2つの書類モード切り替えに気がついた
  • Numbersで選択範囲のセルの前後の空白を削除
  • メキシカンハットの描画
  • Pixelmator Pro v3.6.4でAppleScriptからの操作時の挙動に違和感が
  • AdobeがInDesign v19.4からPOSIX pathを採用
  • AppleScriptによる並列処理
  • Safariで「プロファイル」機能を使うとAppleScriptの処理に影響
  • Cocoa Scripting Course 続刊計画
  • macOS 14.xでScript Menuの実行速度が大幅に下がるバグ
  • AppleScript入門③AppleScriptを使った「自動化」とは?
  • Keynote/Pagesで選択中の表カラムの幅を均等割
  • デフォルトインストールされたフォント名を取得するAppleScript
  • macOS 15 リモートApple Eventsにバグ?
  • Keynote、Pages、Numbers Ver.14.0が登場
  • macOS 15でも変化したText to Speech環境
  • AppleScript入門① AppleScriptってなんだろう?
  • Numbersで最前面の書類のすべてのシート上の表の行数を合計

Tags

10.11savvy (1101) 10.12savvy (1242) 10.13savvy (1391) 10.14savvy (587) 10.15savvy (438) 11.0savvy (283) 12.0savvy (212) 13.0savvy (194) 14.0savvy (147) 15.0savvy (132) CotEditor (66) Finder (51) iTunes (19) Keynote (117) NSAlert (61) NSArray (51) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (53) NSDictionary (28) NSFileManager (23) NSFont (21) NSImage (41) NSJSONSerialization (21) NSMutableArray (63) NSMutableDictionary (22) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (119) NSURL (98) NSURLRequest (23) NSUTF8StringEncoding (30) NSView (33) NSWorkspace (20) Numbers (76) Pages (55) Safari (44) Script Editor (27) WKUserContentController (21) WKUserScript (20) WKWebView (23) WKWebViewConfiguration (22)

カテゴリー

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

アーカイブ

  • 2025年5月
  • 2025年4月
  • 2025年3月
  • 2025年2月
  • 2025年1月
  • 2024年12月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年6月
  • 2024年5月
  • 2024年4月
  • 2024年3月
  • 2024年2月
  • 2024年1月
  • 2023年12月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年6月
  • 2023年5月
  • 2023年4月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年12月
  • 2019年11月
  • 2019年10月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年5月
  • 2018年4月
  • 2018年3月
  • 2018年2月

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

メタ情報

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

Forum Posts

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

メタ情報

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