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

タグ: 12.0savvy

書籍フォルダの階層をさかのぼって、ツメに掲載する最大チャプターを推測 v2

Posted on 3月 4, 2022 by Takaaki Naganoya

電子書籍を作るのにPagesやKeynoteを使っており、「AppleScriptによるWebブラウザ自動操縦ガイド」(以下、Webブラウザガイド)も全ページPagesで作っています。

PagesやKeynoteでは書籍作成用としては機能が素朴すぎて、足りない点はAppleScriptでツールを作って、作業の手間を減らしています。それらの補助Scriptは、各種パラメータをその本に合わせて固定して使用しています。

Webブラウザガイドは全14章で構成されているため、ページの左右につけている「ツメ」(Index)は1から14までの数字が入っています。

今後もツメチェックAppleScript(座標、塗りつぶし色と非選択色の自動判別、ファイル名からの該当章の自動ピックアップ)を他の書籍用にも運用していくつもりですが、この「全14章」という仕様は固定なので、章構成が異なる他の本のプロジェクトでは、自動で章の数をかぞえてくれるとよさそうだと考えました。

だいたい電子書籍のファイルについては、フォルダ分けして2階層ぐらいで管理しているので、その階層数については決め打ちでDoc rootフォルダを計算(parent of parent of….)するようにしました。そして、全フォルダのフォルダ名称を取得。

ダイアログで最終章を選択させると、そこから章番号を自動抽出して(「XX章」と書かれていることが前提)、その番号を返します。

こういう用途を考えると、階層構造をそのまま選択できるNSOutlineViewを選択用の部品に使えると便利で……これまでにもedama2さんと意見交換しつつNSOutlineViewをNSAlertダイアログ上に表示するといった試作も何回か検討してきたのですが、スクリプトエディタ/Script Debugger上で記述するAppleScriptObjCではこの部品を扱うのがとても難しいんですね。

ならば、Xcode上で記述するAppleScriptObjCにAppleScript用語辞書を持たせて、階層ファイル構造を選択させる専用の補助アプリケーションを作ってもいいのかも? ただ、Xcode 13.x系が壊れて使えないままの環境であるため、いまXcodeでビルドするわけにもいかないのでした。

choose fileコマンドやchoose folderコマンドに「icon view」「list view」「column view」といった初期表示状態を指定できる機能があれば、それで済むような気もしますが、どうせAppleに要望出してもこういうのは通らないので、自分で作ったほうが確実で早いですわー。

にしても、この通常ウィンドウと見分けがつかないファイル選択ダイアログ、macOS 11で最初に見たときには「正気か?!」と、腰を抜かしました。あいかわらず、この決定を下した責任者は●●だと思いますが、せめてもう少し視覚的に見分けがつくようにできなかったもんでしょうか。

AppleScript名:書籍フォルダの階層をさかのぼって、ツメに掲載する最大チャプターを推測 v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/02/26
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—

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

tell application "Pages"
  tell front document
    set filePath to (file of it) as alias
  end tell
end tell

tell application "Finder"
  set parentFol to (parent of parent of filePath)
  
tell parentFol
    set fNames to name of every folder
  end tell
end tell

set folName to contents of (choose from list fNames with prompt "書籍のツメに載せる最終章のフォルダを選択")
set cNum to retChapter(folName as string) of me
–> 14

–ファイル名から「章」情報を抽出
on retChapter(aStr)
  set wList to words of aStr
  
set aCount to 1
  
repeat with ii in wList
    set jj to contents of ii
    
if jj = "章" then
      return contents of item (aCount – 1) of wList
    end if
    
set aCount to aCount + 1
  end repeat
  
return 0 –Illeagal file name
end retChapter

★Click Here to Open This Script 

Posted in Books file File path Text | Tagged 12.0savvy Finder Pages | 1 Comment

Skimで現在表示中のページ(見開き2ページ、書籍モード)をJPEG画像で書き出す

Posted on 3月 2, 2022 by Takaaki Naganoya

SkimでPDFを、見開き2ページ、書籍モードで表示させた状態で、見開きごと2ページ分の画像をJPEG画像で書き出すAppleScriptです。

macOS 12.3 beta 5、Skim v1.6.8で動作を確認してあります。macOS 12に合わせてPDFKitを直接useコマンドで使用指定しています。


▲SkimでPDFをオープンした状態で実行。見開き2ページ、書籍モードを設定している状態


▲macOS標準搭載のスクリプトメニューから呼び出すことを前提に作ってあります


▲見開き2ページのうち、右ページを選択しているか、左ページを選択しているかの状態を検出して処理


▲出力結果。表示中のPDFと同じフォルダ内に作成される

AppleScript名:Skimで現在表示中のページ(見開き2ページ、書籍モード)をJPEG画像で書き出す
— Created 2022-03-02 by Takaaki Naganoya
— 2022 Piyomaru Software
use AppleScript version "2.7"
use scripting additions
use framework "Foundation"
use framework "Quartz"
use framework "PDFKit"
use framework "AppKit"

property |NSURL| : a reference to current application’s |NSURL|
property NSString : a reference to current application’s NSString
property NSImage : a reference to current application’s NSImage
property NSScreen : a reference to current application’s NSScreen
property NSNumber : a reference to current application’s NSNumber
property NSZeroPoint : a reference to current application’s NSZeroPoint
property PDFDocument : a reference to current application’s PDFDocument
property NSJPEGFileType : a reference to current application’s NSJPEGFileType
property NSCompositeCopy : a reference to current application’s NSCompositeCopy
property NSGraphicsContext : a reference to current application’s NSGraphicsContext
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep
property NSNumberFormatter : a reference to current application’s NSNumberFormatter
property NSImageInterpolationHigh : a reference to current application’s NSImageInterpolationHigh

tell application "Skim"
  set docCount to count every document
  
if docCount = 0 then return
  
  
tell front document
    set curViewSets to view settings
    
set curMode to display mode of curViewSets
    
    
if curMode is not in {two up, two up continuous} then
      display dialog "2ページ見開きモードでないため、処理を終了します。" with title "error" with icon 0
      
return
    end if
    
    
set bMode to displays as book of curViewSets
    
if bMode = false then
      display dialog "「書籍モード」でないため、処理を終了します。" with title "error" with icon 0
      
return
    end if
    
    
set curInd to index of current page
    
set docFile to file of it
  end tell
end tell

–PDFのファイルパスから実際のPDFを求める
set aPOSIX to POSIX path of docFile
set aURL to (|NSURL|’s fileURLWithPath:aPOSIX)
set aPDFdoc to PDFDocument’s alloc()’s initWithURL:aURL

–PDFのページ数を求める
set pCount to aPDFdoc’s pageCount() –ページ数

if curInd = pCount then
  display dialog "このページはPDFの最終ページなので、見開き表示になっていない可能性があります。" with title "エラー"
  
return
end if

if curInd = 1 then
  display dialog "このページはPDFの最初のページなので、見開き表示になっていない可能性があります。" with title "エラー"
  
return
end if

–見開き中の選択ページが奇数(右ページ)だった場合の対処
if chkOddNum(curInd) = true then set curInd to curInd – 1

–Detect Retina Environment
set compFactor to 1.0 –1.0 — 0.0 = max jpeg compression, 1.0 = none

set retinaF to NSScreen’s mainScreen()’s backingScaleFactor()
if retinaF = 1.0 then
  set aScale to 2.0 –Non Retina Env
else
  set aScale to 1.0 –Retina Env
end if

–Pick Up a PDF page as an image (Left Side Page)
set thisPageL to (aPDFdoc’s pageAtIndex:(curInd – 1))
set imgL to (NSImage’s alloc()’s initWithData:(thisPageL’s dataRepresentation()))
set pageL to renderPDFPageToNSImage(imgL, (curInd – 1), aScale) of me

–Pick Up a PDF page as an image (Right Side Page)
set thisPageR to (aPDFdoc’s pageAtIndex:(curInd – 0))
set imgR to (NSImage’s alloc()’s initWithData:(thisPageR’s dataRepresentation()))
set pageR to renderPDFPageToNSImage(imgR, (curInd – 0), aScale) of me

–Calc 2 pages’ width and others
set origWidth to (pageR’s |size|()’s width)
set newWidth to origWidth * 2
set newHeight to pageR’s |size|()’s height

–Make 2 pages’ blank image
set aSize to current application’s NSMakeSize(newWidth, newHeight)
set newImage to NSImage’s alloc()’s initWithSize:aSize

–Compositte each Left and Right page image
overlayNSImageByLeftTopOrigin(newImage, pageL, {0, 0}) of me
overlayNSImageByLeftTopOrigin(newImage, pageR, {origWidth, 0}) of me

–Save Image as JPEG
set theData to newImage’s TIFFRepresentation()
set newRep to (NSBitmapImageRep’s imageRepWithData:theData)
set targData to (newRep’s representationUsingType:(NSJPEGFileType) |properties|:{NSImageCompressionFactor:compFactor, NSImageProgressive:false})
set zText to retZeroPaddingText((curInd + 1), 4) of me
set outPath to addString_beforeExtensionIn_addingExtension_("_" & zText, aPOSIX, "jpg")
(
targData’s writeToFile:outPath atomically:true) –書き出し

on renderPDFPageToNSImage(anImage, aPageNum, aScale)
  set pointSize to anImage’s |size|()
  
  
set newSize to current application’s NSMakeSize((pointSize’s width) * aScale, (pointSize’s height) * aScale)
  
set newImage to (NSImage’s alloc()’s initWithSize:newSize)
  
  
newImage’s lockFocus()
  (
anImage’s setSize:newSize)
  (
NSGraphicsContext’s currentContext()’s setImageInterpolation:(NSImageInterpolationHigh))
  (
anImage’s drawAtPoint:(NSZeroPoint) fromRect:(current application’s CGRectMake(0, 0, newSize’s width, newSize’s height)) operation:(NSCompositeCopy) fraction:2.0)
  
newImage’s unlockFocus()
  
return newImage
end renderPDFPageToNSImage

–ファイルパス(POSIX path)に対して、文字列(枝番)を追加。任意の拡張子を追加
on addString:extraString beforeExtensionIn:aPath addingExtension:aExt
  set pathString to NSString’s stringWithString:aPath
  
set theExtension to pathString’s pathExtension()
  
set thePathNoExt to pathString’s stringByDeletingPathExtension()
  
  
set newPath to (thePathNoExt’s stringByAppendingString:extraString)’s stringByAppendingPathExtension:aExt
  
return newPath as string
end addString:beforeExtensionIn:addingExtension:

on retZeroPaddingText(aNum, aLen)
  set tText to ("0000000000" & aNum as text)
  
set tCount to length of tText
  
set resText to text (tCount – aLen + 1) thru tCount of tText
  
return resText
end retZeroPaddingText

–2つのNSImageを重ね合わせ合成してNSImageで返す(x,yで配置座標を指定) –newImageを参照渡し
on overlayNSImageByLeftTopOrigin(newImage, composeImage, aTargPos as list)
  set backSize to newImage’s |size|()
  
set bHeight to (height of backSize)
  
  
set overlaySize to composeImage’s |size|()
  
copy aTargPos to {x1, tempy1}
  
set x2 to (width of overlaySize)
  
set y2 to (height of overlaySize)
  
set y1 to bHeight – y2 + tempy1
  
  
newImage’s lockFocus()
  
  
set bRect to {{x1, y1}, {x2, y2}} –macOS 10.13 or later
  
set newImageRect to {{0, 0}, (newImage’s |size|)}
  
newImage’s drawInRect:newImageRect
  
composeImage’s drawInRect:bRect
  
  
newImage’s unlockFocus()
end overlayNSImageByLeftTopOrigin

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 saveNSImageAtPathAsPNG(anImage, outPath)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to NSBitmapImageRep’s imageRepWithData:imageRep
  
set pathString to NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
set myNewImageData to (aRawimg’s representationUsingType:(NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –true/false
end saveNSImageAtPathAsPNG

–奇数かどうかチェック
on chkOddNum(aNum)
  set a to aNum mod 2
  
if a = 1 then
    return true
  else
    return false
  end if
end chkOddNum

–偶数かどうかチェック
on chkEvenNum(aNum)
  set a to aNum mod 2
  
if a = 0 then
    return true
  else
    return false
  end if
end chkEvenNum

★Click Here to Open This Script 

Posted in PDF | Tagged 12.0savvy | Leave a comment

macOS 12.3 beta 5、ASの障害が解消される(?)

Posted on 3月 2, 2022 by Takaaki Naganoya

macOS 12.3 beta 3/beta 4で発生していたAppleScriptの処理系全般にわたって発生していた障害が、beta 5で解消されたように見えます。

本Blogへのプログラムリスト掲載時に使っている「AS Publisher v1.8」(AppleScriptでAppleScriptを処理して掲載用のHTMLを生成するプログラム)自体が動作せず、Blogに投稿できない(横にある別Ver.OSのマシンでやればいいんですが)状況が続いていました。

本日配信されていたmacOS 12.3 beta 5で解消されたように見えます。手元にあるScriptが膨大すぎて、全数チェックするわけにもいきませんが、オープンできずにいたAppleScript書類はオープン/実行できています。

昨日リリースした書籍に掲載予定だったリストに動かないものがあって、掲載を見送る処理&使用しているプログラムの作者にお詫びのメールを送っていたのですが、なんのことはない、このbeta 3/4のバグのせいでした(beta 5にアップデートしたら何事もなかったように動いた)。

AppleScript書類をオープンできないとか実行できないといった「最悪レベルの問題」を起こさないことは確認できていますが、やっぱり「内部の表があふれる」的なエラーを出すScriptはまだあるようです。

macOS 11や10.15でそのようなエラーを起こす例を見なかったScriptなので、やはりmacOS 12環境に固有の問題が何かまだ残されているということなんでしょう。

macOS 12.3 beta 5、古めのMac OS X 10.2ぐらいの時期に書かれたAppleScript書類で、現在すでにOSにインストールされていない各種補助アプリケーションを呼び出しているものを、アプリケーション選択ダイアログを出さずに、いきなり「オープンできない」とダイアログを出して切り捨てる動作を行なっています。Script Debugger経由ではオープンできるため、依然として注意が必要です。

Posted in Bug news | Tagged 12.0savvy | 8 Comments

macOS 12.3 beta4、まだ直らないASまわりの障害

Posted on 2月 23, 2022 by Takaaki Naganoya

macOS 12.3 beta 3で発生した目が覚めるような不具合。本日、beta 4が出てきたものの、AppleScript書類をオープンできない(ものがある)とか、実行できない(ものもある)というなかなかハードな状況です。正直、macOS 12.2に戻したいデス(^ー^;;

ちょっと前にSkimで遭遇した「内部の表があふれました」エラーの問題がどうやら(Skim以外にも)存在していて、その解決を図ろうとして他の問題を引き起こしてしまったのではないかと推測しています。

どこか別のチームが引き起こした修正が影響を及ぼしているのかと思いきや……そうでもない雰囲気が(汗)

macOS 12.3がどの程度までbetaを出すのかわかりませんが、通例ではbeta 5ぐらいでReleaseするんじゃないでしょうか。ラスト1take?

少なくとも、常識的に考えれば3月にリリースするとか噂で言われている新ハードウェアの発売に合わせて(未発表なので詳細は知りませんが)、これらのハードウェア向けにmacOS 12.3をリリースするとかいう話なんじゃないでしょうか。

# macOS 12.2.2とかいった細かいバージョンアップで例外的に対応することも不可能ではないと思われますが、外野からではリリース番号のポリシーなどはよくわかりません

自分なら、当初取り掛かっていた問題解決をいったん引っ込めて、12.2と同等の状況に戻してリリースすることでしょう。一部の問題解決を目指して、より広範囲に問題を引き起こすのは得策ではありません。

正直、AppleScriptの処理系の安定性がここまで「揺らいだ」のは初めての出来事なので(Mac OS X 10.3.xで、自分が多用している「is in」演算子が動かないことに気づいた時には目の前が真っ暗になりました…「Newt Onジャマー」とか呼んで、いいかげんにしてくれよと思ってました)、正直困惑しています。

Posted in Bug news | Tagged 12.0savvy | Leave a comment

CotEditor v4.1.2でAppleScript系の機能を追加

Posted on 2月 22, 2022 by Takaaki Naganoya

オープンソース開発されているフリーのテキストエディタ「CotEditor」v4.1.2において、AppleScript系の機能が追加されています。

・DocumentオブジェクトのhasBOM属性

has BOM (boolean, r/o) : Is the file encoding of the document has BOM (byte order mark)?

・convertコマンドのBOMオプション

convert v : Convert the document text to new encoding.
convert document : The document to convert encoding.
[lossy boolean] : Allows lossy conversion?
[BOM boolean] : Has the new encoding a BOM (byte order mark)?
to text : The new encoding, either in localized encoding name or an IANA charset name.
→ boolean : Did the convertion succeed?

・新設のjumpコマンド

jump v : Move the caret to the specified location. At least, either one of a parameter is required.
jump document : The document to move.
to line integer : The number of the line to go. If a negative value is provided, the line is counted from the end of the document.
[column integer] : The location in the line to jump. If a negative value is provided, the column is counted from the end of the line.

こんなサンプル書類があったとして、

AppleScriptのdocumentオブジェクトの文字データを取得してダンプしてみても、

--No BOM
{"E3", "81", "B4", "E3", "82", "88", "E3", "81", "BE", "E3", "82", "8B", "E3", "82", "BD", "E3", "83", "95", "E3", "83", "88", "E3", "82", "A6", "E3", "82", "A7", "E3", "82", "A2", "0A", "61", "62", "63", "64", "E9", "AB", "98", "E5", "B3", "B6", "E5", "B1", "8B", "65", "66", "67", "68", "69", "0A", "0A"}

--with BOM
{"E3", "81", "B4", "E3", "82", "88", "E3", "81", "BE", "E3", "82", "8B", "E3", "82", "BD", "E3", "83", "95", "E3", "83", "88", "E3", "82", "A6", "E3", "82", "A7", "E3", "82", "A2", "0A", "61", "62", "63", "64", "E9", "AB", "98", "E5", "B3", "B6", "E5", "B1", "8B", "65", "66", "67", "68", "69", "0A", "0A"}

この状態ではhasBOM属性値で差があっても、内部データでは差が出ません。これをファイルに書き込んで、ファイル内容についてチェックを行うと、

--No BOM
0000000 81e3 e3b4 8882 81e3 e3be 8b82 82e3 e3bd
0000010 9583 83e3 e388 a682 82e3 e3a7 a282 610a
0000020 6362 e964 98ab b3e5 e5b6 8bb1 6665 6867
0000030 0a69 000a                              
0000033

--With BOM
0000000 bbef e3bf b481 82e3 e388 be81 82e3 e38b
0000010 bd82 83e3 e395 8883 82e3 e3a6 a782 82e3
0000020 0aa2 6261 6463 abe9 e598 b6b3 b1e5 658b
0000030 6766 6968 0a0a                         
0000036

のように、差を検出できます。

Posted in news Object control Text | Tagged 10.15savvy 11.0savvy 12.0savvy CotEditor | Leave a comment

[超危険]macOS 12.3 beta3、errOSAInternalTableOverflow多発

Posted on 2月 16, 2022 by Takaaki Naganoya

今朝方来ていたmacOS 12.3 beta3アップデートをインストールしたら、(Script Debuggerで)AppleScript書類のでかいのをオープンしただけで「errOSAInternalTableOverflow」が表示されるようになりました。

スクリプトエディタでは、AppleScript書類のオープンすら(小さいものでないと)できない状況です。

過去最悪レベルの問題リリースです>macOS 12.3beta 3


▲今日の深夜に問題なく実行できていたScriptがいきなりオープンできなかったり実行できなくなったりする問題が発生


▲昨日までオープンできていたAppleScript書類をスクリプトエディタでオープンできなくなる事態が発生!!!

こういうアップデートは困ります、、、、Betaプログラムに参加されている方は、Beta 3のアップデートをインストールすることはやめておいたほうがいいと思います。

日常的に、Pagesの連続PDF出力+連結など大規模なScriptを動かしていたのが、急に今日になって動かなくなってしまいました。

こういうのは困るんですが?(ーー;;;

大きなScriptを動かすときには、部品ごとに分割して、別ファイルに分割して対処を行なってみていますが、、、過去にこのようなトラブルに遭遇したことはなかったので、純粋に腹が立つバグですわー

# どうしても動かないと困るAppleScriptについては、書き換えてScriptの機能をライブラリに分割して、バンドル内にライブラリを同梱する方向で対処しました

バグレポートはしましたが、「ざけんなコラ!!!!」と日本語で書きそうになりましたわー。

# さすがに直したらしい(謎情報)ですが、macOS 12.3 Beta 4自体がいつ出るのか不明。ものすごくScript周りがバギーで一刻も早く出てほしい。Appleの会議体制から考えると1週間以内に出ることはない

# macOS 12.3 beta 5で直りました(多分)

Posted in Bug | Tagged 12.0savvy | 1 Comment

Pages書類内の表の指定ラベルの行を削除

Posted on 2月 14, 2022 by Takaaki Naganoya

Pagesの書類上にある表に対して、指定のラベルを持つ行を削除するAppleScriptです。macOS 12.3beta2+Pages 11.2で動作確認しています。

現在作成中のWebブラウザのScripting本で、各種AppleScript実行環境の一覧表を掲載しているのですが、

それぞれの差別化ポイントとして掲載していたデータのうちの1つが、執筆後に一律で解決できることになり(NSAlertダイアログの最前面表示)、そのデータ行については削除することになりました。

そこで、複数のPages書類に記載した表を一括で削除することになり、AppleScriptを組んで削除することにしました。

必要はありませんでしたが、ヘッダー列が1列だけでなく、複数の列になった場合と、ヘッダーの複数セルが1つにまとめられていた場合への対処も行っておきました。ただし、気休め程度であって、本気で対処したものではありません。

AppleScript名:Pages書類内の表の指定ラベルの行を削除.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/02/14
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

set targRowLabel to "NSAlert ダイアログの最前面表示"

tell application "Pages"
  tell front document
    set tList to every table whose column count = 2
  end tell
end tell

delRowInEveryTable(tList, targRowLabel) of me

on delRowInEveryTable(tList as list, targRowLabel as string)
  tell application "Pages"
    repeat with i in tList
      set j to contents of i
      
      
tell j
        set hCCount to header column count
        
set hRCount to header column count
        
        
–ヘッダーカラムが複数存在している場合に対処?
        
repeat with hc from 1 to hCCount
          tell column hc
            set aList to value of every cell
          end tell
          
          
if targRowLabel is in aList then
            set aRes to search1DList(aList, targRowLabel) of me
            
            
–ヘッダー列に削除対象ラベルが存在しつつ、削除対象ラベルがヘッダー行の範囲ではない場所に出現した場合に削除
            
if (aRes is not equal to false) and (aRes ≥ hRCount) then
              try –ねんのため
                delete row aRes
              end try
            end if
          end if
          
        end repeat
      end tell
    end repeat
    
  end tell
end delRowInEveryTable

on search1DList(aList, aTarg)
  set anArray to current application’s NSMutableArray’s arrayWithArray:aList
  
set anIndex to anArray’s indexOfObject:aTarg
  
if (anIndex = current application’s NSNotFound) or (anIndex > 9.99999999E+8) then
    return false
  end if
  
return (anIndex as integer) + 1 –convert index base (0 based to 1 based)
end search1DList

★Click Here to Open This Script 

Posted in list | Tagged 10.15savvy 11.0savvy 12.0savvy Pages | Leave a comment

リストに入れたテキストで、冒頭に入ったマルつき数字をリナンバーする

Posted on 2月 12, 2022 by Takaaki Naganoya

日本語環境限定かもしれませんが、マルつき数字(①②③④⑤⑥⑦⑧⑨….)をさまざまな場所でよく使います。

データにマルつき数字を入れると、順番がわかりやすくてよいのですが、データそのものを入れ替えたときに番号をふり直すという手間がかかってしまいます。これがけっこうな手間になっています(地味に大変)。

そこで、

 {"③AAAAAA", "②BBBBB", "①CCCCC", "⑬DDDDDD", "⑫EEEE", "④FFFF", "⑤GGGG", "⑥HHHH", "⑲IIIII", "⑧JJJJ"}

というデータを本Scriptによって、

{"①AAAAAA", "②BBBBB", "③CCCCC", "④DDDDDD", "⑤EEEE", "⑥FFFF", "⑦GGGG", "⑧HHHH", "⑨IIIII", "⑩JJJJ"}

と、リナンバー処理します。

本処理は、絵文字の削除Scriptの副産物として生まれたもので、マル文字を削除したのちに番号をふり直して付加したところ、たいへん有用性を感じられました。

Keynote、Numbers、Pages…と、同じことができるようにScriptを整備し、CotEditor用にあったほうが便利だろうと考えて、CotEditor用にかきかえた際に、

–> Watch Demo Movie

「ほかのアプリケーションでも使えたほうが便利なので、再利用しやすいように部品化しておこう」

と、Script文でラッピングしてみたものがこれです。

AppleScript名:リストに入れたテキストで、冒頭に入ったマルつき数字をリナンバーする.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/02/12
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—

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

set aOffset to 0

set aSelList to {"③AAAAAA", "②BBBBB", "①CCCCC", "⑬DDDDDD", "⑫EEEE", "④FFFF", "⑤GGGG", "⑥HHHH", "⑲IIIII", "⑧JJJJ"}

—データ中に丸つき数字が存在した場合には、最小のものを取得
set aOffset to (getMinimumNumFromNumberWithSign(aSelList) of maruNumKit)

–ユーザーに対して「本当に初期値がこれでいいのか?」をダイアログなどで確認したほうがいい

–Keynoteの表のセルから取得したデータから丸つき数字を除去する
set cList to removeNumberWithSignFromList(aSelList) of maruNumKit

–list中の各アイテムの冒頭に順次丸つき数字を追加する
set dList to {}
set aCount to 0

repeat with i in cList
  set j to convNumToNumWithSign(aCount + aOffset) of maruNumKit
  
set jj to contents of i
  
  
set the end of dList to (j & jj)
  
  
set aCount to aCount + 1
end repeat

return dList
–> {"①AAAAAA", "②BBBBB", "③CCCCC", "④DDDDDD", "⑤EEEE", "⑥FFFF", "⑦GGGG", "⑧HHHH", "⑨IIIII", "⑩JJJJ"}

–1D Arrayを改行コードをデリミタに指定しつつテキスト化
–set outStr to retDelimedText(dList, return) of maruNumKit

–丸つき数字を扱うキット
script maruNumKit
  
  
use AppleScript
  
use framework "Foundation"
  
use scripting additions
  
property parent : AppleScript
  
  
–1~50の範囲の数値を丸つき数字に変換して返す
  
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
  
  
  
–1D List上で指定データを検索してヒットしたアイテム番号を返す
  
on search1DList(aList, aTarg)
    set anArray to current application’s NSMutableArray’s arrayWithArray:aList
    
set anIndex to anArray’s indexOfObject:aTarg
    
if (anIndex = current application’s NSNotFound) or (anIndex > 9.99999999E+8) then
      return false
    end if
    
return (anIndex as integer) + 1 –convert index base (0 based to 1 based)
  end search1DList
  
  
  
–1D listのクリーニング
  
on cleanUp1DList(aList as list, cleanUpItems as list)
    set bList to {}
    
repeat with i in aList
      set j to contents of i
      
if j is not in cleanUpItems then
        set the end of bList to j
      else
        set the end of bList to ""
      end if
    end repeat
    
return bList
  end cleanUp1DList
  
  
  
–text in listから丸つき数字を除去する
  
on removeNumberWithSignFromList(aList as list)
    set bList to {}
    
repeat with i in aList
      set j to contents of i
      
set j2 to removeNumberWithSign(j) of me
      
set the end of bList to j2
    end repeat
    
return bList
  end removeNumberWithSignFromList
  
  
  
–文字列から丸つき数字を除去する
  
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
  
  
  
–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 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
  
  
–1D Listを指定デリミタをはさみつつテキストに
  
on retDelimedText(aList as list, aDelim as string)
    set aText to ""
    
set curDelim to AppleScript’s text item delimiters
    
set AppleScript’s text item delimiters to aDelim
    
set aText to aList as text
    
set AppleScript’s text item delimiters to curDelim
    
return aText
  end retDelimedText
end script

★Click Here to Open This Script 

Posted in list Text | Tagged 10.15savvy 11.0savvy 12.0savvy | 1 Comment

PDFViewでcustom URL protocolのリンクを含むPDFのリンクが途切れるバグが修正される

Posted on 2月 9, 2022 by Takaaki Naganoya

PDFView上で、カスタムURLプロトコルのURLリンクを含むPDFのリンクをクリックした場合に、展開されたリンクデータが途中で途切れるバグ(だか仕様だか)がmacOS 12.3beta 1で修正された…ように見えます。

なんの話だか、詳細が説明されなければわからないことでしょう。以下に詳細を示します。

macOS標準装備の「プレビュー.app」では、カスタムURLプロトコル入りのPDFでリンクをクリックしても反応しません。macOS標準装備のPDFビューワでこうしたPDFのリンクを拾わない、というAppleのセキュリティ上のポリシーを通すことについては、それはご勝手にすればいいでしょう。

ただ、だからといってPDFViewというOSの部品レベルでそれを阻害するような機能を実装するというのは、「やりすぎ」であり、「起動しないコンピュータ、動作しないコンピュータを作れば100%セキュリティを守れます!」というどこかの責任者のバカみたいな主張をバカな現場がそのまま実装したというだけの話です。

プレビュー.appなんて「よくわからない人」が使うPDFビューワーであり、文化的な最低限のレベルを満たしている人類は普通にSkimを使います。このバグによってSkimにまで影響が出て、基本的人権ともいえるPDFブラウジングが阻害されたため、「直してくれ」と要求した次第です。

2019/11/29 macOS 10.15でPDFView経由のURLイベントが正しくデコードされないバグ

macOS 10.15でこのバグ(だか仕様変更だか)が発生してAppleにバグレポート。macOS 10.15はそういう勘違いで独善的な仕様変更のオンパレード。macOS 10.15は本当に腹のたつアップデートでした。

そして、待てど暮らせど直る気配もなく、急にレポートがきて「いまごろ、何の話だ?」と、驚いてしまったほどです。

本バグ(と、自分は位置付けている)レポートは、「applescript://」URLリンクを埋め込んだPDFが、macOS上でリンククリックすると、Script Editorにその内容がすべて転送されず、途中で途切れるようになったという現象についての抗議です。

勝手に仕様変更だかバグだかを作ったのはAppleであり、その修正までに2年かかったというバカみたいな話です。

  macOS 10.15:PDFViewのバグ発生を検出、Appleにサンプルコードつきでバグレポートとして報告する
  macOS 11:バグ継続
  macOS 12:Beta 3でバグが修正されたことが通告される

勝手に仕様変更だかバグを作ったのはAppleなのに、利用者がその不利益を被って、多大なる労力を要求されるってなんなんでしょう、、、

PDFViewでPDFを表示する程度のシンプルでおかわいらしい内容のテストプログラムを作ってあったので、Xcodeでビルドして実行してテストしてみました。まだ、すべてのPDFでチェックしたわけではありませんが、いまのところ「いい感じ」に見えます。

この、Apple純正のバグをApple様に直していただいて、そのことをApple様に感謝しなければいけないのでしょうか? なんというマッチポンプ。もしかして、組織のどこかの人たちが善意で直してくれたのかもしれませんが、自分には知る由もありません。

ちなみに、SkimについてはmacOS 12でカスタムURLプロトコルリンクのPDFを問題なく処理できることを確認しています。

この調子で、PDFViewのcurrentPageがAppleScriptにまともにブリッジされていない件についても修正してくださるとありがたいのですが、どんなもんなんでしょうか。

Posted in Bug news | Tagged 12.0savvy PDFView | Leave a comment

与えられた自然言語テキストから言語を推測して、指定の性別で、TTSキャラクタを自動選択して読み上げ

Posted on 2月 5, 2022 by Takaaki Naganoya

自然言語テキストを与えると、記述言語を推測して、その言語コード(jaとか)、性別、Premium(高音質)音声かどうか(true/false)をもとにText to Speechの読み上げ音声キャラクタをしぼりこんで、sayコマンドで音声読み上げするAppleScriptです。

# ScriptのリストについているURL Linkを書き換えました

自然言語から推測される言語コードと、TTS音声キャラクタに振られている言語コードの間に仕様的な食い違いがあるので、中国語の自動判定を行うためには、(若干の)処理を追加する必要があります。

自然言語テキストから取得できるのは「簡体字」「繁体字」のコードである一方で、TTS読み上げキャラクタが持っているのは、China、HongKong、Taiwanと国コードなので、対照表でもつけるか、いっそ全部「zh」でくくってランダム選択するか、、、はたまた、実行マシンの緯度・経度情報から判定するか、テーブルを編集可能なようにしておいて、テーブルのルールを決め打ちで反映するとか、、、、


▲システム環境設定>アクセシビリティ>読み上げコンテンツ>システムの声 のポップアップメニューで、一番下に「カスタマイズ」の項目があり、Text To Speech読み上げキャラクタの追加が行える


▲追加したTTSキャラクタの音声データは自動でダウンロードが行われる。TTS用にSiri音声は指定できないが、「ショートカット」の音声読み上げでは指定できる。このあたり、外部のTTS音声データ提供会社との契約によるものなのか、あるいは管理プログラムが異なるのか?

AppleScript名:与えられた自然言語テキストから言語を推測して、指定の性別で、TTSキャラクタを自動選択して読み上げ v1(簡体字、繁体字 未サポート).scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/02/05
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property NSSpeechSynthesizer : a reference to current application’s NSSpeechSynthesizer

set str1 to "こんにちは"

–指定文字列が何語かを推測して、言語コード(Short)を取得
set a1Res to guessLanguageCodeOf(str1) of me

–指定の言語コード(Short)をキーにしてTTS属性情報を取得
set vList to retAvailableTTSbyShortLangCodeAndSexAndPremium(a1Res, "Female", true) of me
if vList = {} then return

–取得したTTS情報リストから、てきとーに項目を取得
set fV to contents of first item of vList

set vName to VoiceName of fV
say str1 using vName

—
on retAvailableTTSbyShortLangCodeAndSexAndPremium(aLangShortCode as string, aSex as string, premiumFlag as boolean)
  set outList to {}
  
  
if aSex is not in {"Male", "Female"} then error "Sex code is wrong"
  
  
set aList to NSSpeechSynthesizer’s availableVoices()
  
set bList to aList as list
  
  
repeat with i in bList
    set j to contents of i
    
set aInfo to (NSSpeechSynthesizer’s attributesForVoice:j)
    
set aInfoRec to aInfo as record
    
    
–読み上げ対象文字データは多すぎるので削除しておく
    
set VoiceIndividuallySpokenCharacters of aInfoRec to {}
    
set VoiceSupportedCharacters of aInfoRec to {}
    
    
set aName to VoiceName of aInfoRec
    
set aLangCode to VoiceLocaleIdentifier of aInfoRec
    
    
set aGender to VoiceGender of aInfoRec
    
set aVID to VoiceIdentifier of aInfoRec
    
    
if (aLangCode starts with aLangShortCode) and (aGender = "VoiceGender" & aSex) then
      if premiumFlag = true then
        if aVID ends with "premium" then
          set the end of outList to aInfoRec
        end if
      else
        set the end of outList to aInfoRec
      end if
    end if
  end repeat
  
  
return outList
end retAvailableTTSbyShortLangCodeAndSexAndPremium

–文字列から言語を推測して言語名を返す
on guessLanguageOf(theString)
  set theTagger to current application’s NSLinguisticTagger’s alloc()’s initWithTagSchemes:{current application’s NSLinguisticTagSchemeLanguage} options:0
  
theTagger’s setString:theString
  
set languageID to theTagger’s tagAtIndex:0 |scheme|:(current application’s NSLinguisticTagSchemeLanguage) tokenRange:(missing value) sentenceRange:(missing value)
  
return ((current application’s NSLocale’s localeWithLocaleIdentifier:"en")’s localizedStringForLanguageCode:languageID) as text
end guessLanguageOf

–文字列から言語を推測して言語コードを返す
on guessLanguageCodeOf(theString)
  set theTagger to current application’s NSLinguisticTagger’s alloc()’s initWithTagSchemes:{current application’s NSLinguisticTagSchemeLanguage} options:0
  
theTagger’s setString:theString
  
set languageID to theTagger’s tagAtIndex:0 |scheme|:(current application’s NSLinguisticTagSchemeLanguage) tokenRange:(missing value) sentenceRange:(missing value)
  
return languageID as text
end guessLanguageCodeOf

★Click Here to Open This Script 

Posted in Language Text Text to Speech | Tagged 10.15savvy 11.0savvy 12.0savvy NSLinguisticTagger NSLocale NSSpeechSynthesizer | Leave a comment

指定アプリケーションの各言語のローカライズ名称を取得して、言語名をローカライズしてNumbersに出力

Posted on 2月 4, 2022 by Takaaki Naganoya

指定アプリケーションが対応している各ローカライズ言語におけるアプリケーション名称を取得して、言語名をcurrent localeに合わせて変換しつつCSV出力してNumbersでオープンするAppleScriptです。

アプリケーションバンドルを調査して、ローカライズ対応している言語の一覧を取得するプログラムは組んでありました。そのローカライズを順次調べて、InfoPlist.stringsファイルを読み込み、CFBundleNameのエントリを調べています。

これで、その言語向けにローカライズされた「名称」を調べられます。あとは、言語コードを名称に変換する処理(これも、ありもの)を組み合わせて、2次元配列(2D list)にまとめあげ、CSV書き出しして(ありもの)、Numbersでオープンしただけのものです。

言語名称については、currentLocaleを利用しているため、日本語環境で実行すれば日本語表現で出力されますし、英語環境で実行すれば英語表現で出力されます。

実際に、書籍に掲載する資料用のデータを作成するときに使ってみました。

言語 Code 「地図」アプリのローカライズ名称
ドイツ語 de Karten
ヘブライ語 he מפות
英語(オーストラリア) en_AU Maps
アラビア語 ar الخرائط
ギリシャ語 el Χάρτες
日本語 ja マップ
英語 en Maps
ウクライナ語 uk Карти
スペイン語(ラテンアメリカ) es_419 Mapas
中国語(中国本土) zh_CN 地图
スペイン語 es Mapas
デンマーク語 da Kort
イタリア語 it Mappe
スロバキア語 sk Mapy
ポルトガル語(ポルトガル) pt_PT Mapas
マレー語 ms Peta
スウェーデン語 sv Kartor
チェコ語 cs Mapy
韓国語 ko 지도
広東語(中国本土) yue_CN 地图
ノルウェー語 no Kart
ハンガリー語 hu Térképek
中国語(香港) zh_HK 地圖
トルコ語 tr Harita
ポーランド語 pl Mapy
中国語(台湾) zh_TW 地圖
英語(イギリス) en_GB Maps
ベトナム語 vi Bản đồ
ロシア語 ru Карты
フランス語(カナダ) fr_CA Plans
フランス語 fr Plans
フィンランド語 fi Kartat
インドネシア語 id Peta
オランダ語 nl Kaarten
タイ語 th แผนที่
ポルトガル語 pt Mapas
ルーマニア語 ro Hărți
クロアチア語 hr Karte
ヒンディー語 hi नक़्शा
カタロニア語 ca Mapes
AppleScript名:指定アプリケーションの各言語のローカライズ名称を取得して、言語名をローカライズしてNumbersに出力.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/02/04
—
–  Copyright © 2022 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 targFile to "InfoPlist.strings"
set targKey to "CFBundleName"

set aLocale to (current application’s NSLocale’s currentLocale())

set aLoc to path to applications folder
set anApp to POSIX path of (choose file of type {"com.apple.application-bundle"} default location aLoc)

set aBundle to getBundleFromPath(anApp) of me
set aName to aBundle’s objectForInfoDictionaryKey:(current application’s kCFBundleNameKey)

set aLocList to getSpecifiedAppFilesLocalizationListWithDuplication(aBundle) of me

set hitList to {}

repeat with i in aLocList
  set j to contents of i
  
  
if j is not equal to "Base" then
    set allPath to anApp & "/Contents/Resources/" & j & ".lproj/" & targFile
    
set aDict to (current application’s NSDictionary’s alloc()’s initWithContentsOfFile:allPath)
    
    
if aDict is not equal to missing value then
      set aVal to (aDict’s valueForKeyPath:(targKey))
      
if aVal is not equal to missing value then
        set aLang to getLangNameWithLocale(j, aLocale) of me
        
set the end of hitList to {aLang, j, aVal as string}
      end if
    else
      log {"Error in ", j}
    end if
  end if
end repeat

–一時ファイルをCSV形式でデスクトップに書き出し
set aPath to (path to desktop as string) & (do shell script "uuidgen") & ".csv"
saveAsCSV(hitList, aPath) of me

–書き出したCSVファイルをNumbersでオープン
tell application "Numbers"
  open (aPath as alias)
end tell

–Application path –> Bundle
on getBundleFromPath(aPOSIXpath)
  set aURL to current application’s |NSURL|’s fileURLWithPath:aPOSIXpath
  
set aWorkspace to current application’s NSWorkspace’s sharedWorkspace()
  
set appURL to aWorkspace’s URLForApplicationToOpenURL:aURL
  
set aBundle to current application’s NSBundle’s bundleWithURL:appURL
  
return aBundle
end getBundleFromPath

–指定Bundleのローカライズ言語リストを求める。重複を許容
on getSpecifiedAppFilesLocalizationListWithDuplication(aBundle)
  set locList to aBundle’s localizations()
  
return locList as list
end getSpecifiedAppFilesLocalizationListWithDuplication

on getLangNameWithLocale(langCode, aLocale)
  set aLangName to (aLocale’s displayNameForKey:(current application’s NSLocaleIdentifier) value:langCode) as string
  
return aLangName
end getLangNameWithLocale

–2D List to CSV file
on saveAsCSV(aList, aPath)
  –set crlfChar to (ASCII character 13) & (ASCII character 10)
  
set crlfChar to (string id 13) & (string id 10)
  
set LF to (string id 10)
  
set wholeText to ""
  
  
repeat with i in aList
    set newLine to {}
    
    
–Sanitize (Double Quote)
    
repeat with ii in i
      set jj to ii as text
      
set kk to repChar(jj, string id 34, (string id 34) & (string id 34)) of me –Escape Double Quote
      
set the end of newLine to kk
    end repeat
    
    
–Change Delimiter
    
set aLineText to ""
    
set curDelim to AppleScript’s text item delimiters
    
set AppleScript’s text item delimiters to "\",\""
    
set aLineList to newLine as text
    
set AppleScript’s text item delimiters to curDelim
    
    
set aLineText to repChar(aLineList, return, "") of me –delete return
    
set aLineText to repChar(aLineText, LF, "") of me –delete lf
    
    
set wholeText to wholeText & "\"" & aLineText & "\"" & crlfChar –line terminator: CR+LF
  end repeat
  
  
if (aPath as string) does not end with ".csv" then
    set bPath to aPath & ".csv" as Unicode text
  else
    set bPath to aPath as Unicode text
  end if
  
  
writeToFileAsUTF8(wholeText, bPath, false) of me
  
end saveAsCSV

on writeToFileAsUTF8(this_data, target_file, append_data)
  tell current application
    try
      set the target_file to the target_file as text
      
set the open_target_file to open for access file target_file with write permission
      
if append_data is false then set eof of the open_target_file to 0
      
write this_data as «class utf8» to the open_target_file starting at eof
      
close access the open_target_file
      
return true
    on error error_message
      try
        close access file target_file
      end try
      
return error_message
    end try
  end tell
end writeToFileAsUTF8

on repChar(origText as text, targChar as text, repChar as text)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to targChar
  
set tmpList to text items of origText
  
set AppleScript’s text item delimiters to repChar
  
set retText to tmpList as string
  
set AppleScript’s text item delimiters to curDelim
  
return retText
end repChar

★Click Here to Open This Script 

Posted in Language Locale Record | Tagged 10.15savvy 11.0savvy 12.0savvy NSBundle NSDictionary NSLocale NSURL NSWorkspace Numbers | Leave a comment

Numbersの表でセル連結箇所が存在していたらすべて連結解除

Posted on 1月 31, 2022 by Takaaki Naganoya

指定のNumbers書類中の指定の表で、セルの連結が行われた箇所が存在していたらすべて連結解除するAppleScriptです。

Numbersの表でセルの連結が存在していると、フィルタ処理などが行えないために、セル連結箇所がないかを調べる手段がないと困ります。でも、そういう便利なコマンドがNumbersのAppleScript用語辞書には存在していないので作りました。

連結箇所が分かれば、個別に連結解除するだけです。ループですべてunmergeします。

動作確認は、M1 Mac mini+macOS 12.3beta+Numbersバージョン11.2で行なっています。


▲処理前 セルが連結されている箇所が複数存在している


▲処理後 すべてのセル結合されている箇所が連結解除された

AppleScript名:指定の表で連結セルがあればすべて分離.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/01/31
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

property NSCountedSet : a reference to current application’s NSCountedSet

tell application "Numbers"
  tell front document
    tell active sheet
      tell table 1
        set nList to name of every cell
        
set aRes1 to returnDuplicatesOnly(nList) of me –重複するセルの名称のみピックアップ
        
        
–重複セルを個別に分離
        
repeat with i in aRes1
          set j to contents of i
          
unmerge cell j
        end repeat
      end tell
    end tell
  end tell
end tell

on returnDuplicatesOnly(aList as list)
  set aSet to NSCountedSet’s alloc()’s initWithArray:aList
  
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 list Object control | Tagged 10.15savvy 11.0savvy 12.0savvy NSCountedSet Numbers | Leave a comment

Numbersの表でセル連結箇所が存在しているかどうかチェック

Posted on 1月 31, 2022 by Takaaki Naganoya

指定のNumbers書類中の指定の表で、セルの連結が行われた箇所が存在しているかどうかチェックするAppleScriptです。

Numbersの表でセルの連結が存在していると、フィルタ処理などが行えないために、セル連結箇所がないかを調べる手段がないと困ります。でも、そういう便利なコマンドはNumbersのAppleScript用語辞書には存在していません。

動作確認は、M1 Mac mini+macOS 12.3beta+Numbersバージョン11.2で行なっています。

セルが連結されている箇所は、セルのnameが重複していることが判明。すべてのセルの「name」を取得して、重複しているものをチェックするとセル連結の有無がわかります。

B3セルのproperties

{vertical alignment:top, row:row “row2” of table 1 of sheet 1 of document id “6ED4F3E1-57BD-4A1E-8E0E-9C781DE3840E” of application “Numbers”, class:cell, font name:”HiraKakuProN-W3″, formatted value:”2 21″, background color:missing value, formula:missing value, name:”B3″, text wrap:true, text color:{0, 0, 0}, alignment:auto align, column:column “field1” of table 1 of sheet 1 of document id “6ED4F3E1-57BD-4A1E-8E0E-9C781DE3840E” of application “Numbers”, format:automatic, font size:10.0, value:”2 21″}

C3セルのproperties

{vertical alignment:top, row:row “row2” of table 1 of sheet 1 of document id “6ED4F3E1-57BD-4A1E-8E0E-9C781DE3840E” of application “Numbers”, class:cell, font name:”HiraKakuProN-W3″, formatted value:”2 21″, background color:missing value, formula:missing value, name:”B3″, text wrap:true, text color:{0, 0, 0}, alignment:auto align, column:column “field2” of table 1 of sheet 1 of document id “6ED4F3E1-57BD-4A1E-8E0E-9C781DE3840E” of application “Numbers”, format:automatic, font size:10.0, value:”2 21″}

AppleScript名:指定の表でセル連結がないかチェック.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/01/31
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

property NSCountedSet : a reference to current application’s NSCountedSet

tell application "Numbers"
  tell front document
    tell active sheet
      tell table 1
        set nList to name of every cell
        
set aRes1 to returnDuplicatesOnly(nList) of me
        
return aRes1
        
–> {"B3"}
      end tell
    end tell
  end tell
end tell

on returnDuplicatesOnly(aList as list)
  set aSet to NSCountedSet’s alloc()’s initWithArray:aList
  
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 list Object control | Tagged 10.15savvy 11.0savvy 12.0savvy NSCountedSet Numbers | 1 Comment

macOS 12.3 Beta(21E5196i)、電話番号ピックアップできないバグが直る?

Posted on 1月 28, 2022 by Takaaki Naganoya

macOS 12.3 Beta(21E5196i)が配信され、M1 Mac mini上で実験してみたところ、macOS 12でバグが出ていた「自然言語テキストからNSDataDetectorで電話番号を抽出しようとすると何も出てこない」件(日本語環境限定)が修正されているように見えます。

Thanks Shane!

AppleScript名:与えられたテキストから電話番号を抽出 v2
— Created 2015-08-21 by Shane Stanley
— Modified 2015-08-21 by Takaaki Naganoya
— Modified 2015-08-22 by Shane Stanley
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set theString to "長野谷隆昌
(Takaaki Naganoya)
maro@piyocast.com
http://piyocast.com/as
2015年8月21日〜23日
080-1111-2222
030-1234-5678
東京都練馬区中村橋1-2-3
"

set theDates to (extractPhoneNumberFromNaturalText(theString))
–>  {​​​​​"080-1111-2222"​​​}–macOS 10.12 or other version
–> {"080-1111-2222", "030-1234-5678"}–macOS 13.6 with Intel MacBook Air
–> {"080-1111-2222", "030-1234-5678"}–macOS 14.6 with Intel MacBook Pro
–> {"080-1111-2222", "030-1234-5678"}–macOS 15.7 with Intel MacBook Pro
–> {} –macOS 12 beta 6 with M1 Mac mini
–> {"080-1111-2222", "030-1234-5678"}–macOS 12.3beta1 with M1 Mac mini

on extractPhoneNumberFromNaturalText(aString)
  set anNSString to current application’s NSString’s stringWithString:aString
  
  
set {theDetector, theError} to current application’s NSDataDetector’s dataDetectorWithTypes:(current application’s NSTextCheckingTypePhoneNumber) |error|:(reference)
  
set theMatches to theDetector’s matchesInString:anNSString options:0 range:{0, anNSString’s |length|()}
  
set theResults to theMatches’s valueForKey:"phoneNumber"
  
  
return theResults as list
end extractPhoneNumberFromNaturalText

★Click Here to Open This Script 

Posted in Bug | Tagged 12.0savvy NSDataDetector NSString | Leave a comment

不可視プロセスで表示したNSAlertを最前面に表示

Posted on 1月 28, 2022 by Takaaki Naganoya

コンテクストメニューからAppleScriptを実行するツール「Service Station」を連日こづき回していろいろ試しています。

その中で、Service StationではScript実行をGUIなしの補助プログラムからosascriptコマンドを経由してAppleScriptを実行しているために、AppleScript中でNSAlertによるダイアログ表示をおこなった際に、ダイアログが最前面に表示されないという問題が生じていました。

これを見たedama2さんから、強制的にNSAlertダイアログを最前面に表示させるコードを提供していただいたので、実際にテストに用いたAppleScriptに入れたものをご紹介します。


▲そのまま普通にNSAlertダイアログを表示させたところ。Service Stationによるコンテクストメニューから実行すると、最前面に表示されないという問題があった


▲edama2さんからもたらされたコードを追加したNSAlertダイアログ。Service Stationから実行しても、問題なく最前面に表示される

コードは2行、効き目はばっちり!

--Move to frontmost (By edama2)
current application's NSApplication's sharedApplication()'s setActivationPolicy:(current application's NSApplicationActivationPolicyRegular)
current application's NSApp's activateIgnoringOtherApps:(true)

副作用として、Dockにターミナルのアイコンが表示され、最前面のアプリケーションが「osascript」になってしまいますが、気にならないところでしょう。

Program Name Name of runtime Support AppleScript document format AS Format NSAlert dialog is displayed in frontmost Can use GUI Scripting functions Can call AppleScript Libraries? Can call AS Library including Frameworks? Can call Generic Cocoa Functions? Can use Cocoa system notification functions?
Service Station osascript Script/Text Script/Applet Script/Text Script No-> Yes Yes Yes No Yes No
Script Menu osascript Script/Scriptd/Applet Script/Scriptd Yes Yes Yes No Yes Yes
Shortcuts Events MacHelper File Embedded Script Text Yes Yes Yes No Yes No
Switch Control Assistive Control File Embedded Script Script (archived) Yes Yes No No Yes No
FastScript 3 FastScripts Script Runner Script/Scriptd/Applet Script/Scriptd Yes Yes Yes No Yes

あれ? edama2さんのおかげで、Service Stationの弱点が1つなくなりましたよ。Service Stationについては、

(1)「Kind–> Script」「AppleScript」でテキストで書いた「.applescript」しかピックアップできないとかいう気の狂ったようなRulesの仕様は要・修正

(2)実行Scriptにフラットな.scptとテキストの.applescriptしか実行できないのはダメ。バンドル形式の.scptdの実行サポートは必須

(3)大量のAppleScriptをコンテクストメニューに入れると使い勝手が落ちるので、Rulesでもう少しこまかく条件付けできるとよさそう。ただし必須ではない

といったところでしょうか。

AppleScript名:Webダイアログ表示(強制最前面).scpt
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

my serviceStationDidSelect("", "", "")

on serviceStationDidSelect(targetedURL, selectedItemURLs, menuKind)
  set aList to {{label:"TEST1", value:403}, {label:"TEST2", value:301}, {label:"TEST3", value:101}, {label:"TEST4", value:65}}
  
set bList to sortRecListByLabel(aList, {"value"}, {false}) of me –降順ソート
  
  
–https://www.amcharts.com/demos/pie-chart/
  
set myStr to retHTML() of me
  
set jsonStr to array2DToJSONArray(bList) of me as string
  
set aString to current application’s NSString’s stringWithFormat_(myStr, jsonStr) as string
  
set paramObj to {myMessage:"Simple Pie Chart", mySubMessage:"This is a AMCharts test", htmlStr:aString, viewSize:{1000, 550}}
  
  
my webD’s displayWebDialog(paramObj)
end serviceStationDidSelect

on array2DToJSONArray(aList)
  set anArray to current application’s NSMutableArray’s arrayWithArray:aList
  
set jsonData to current application’s NSJSONSerialization’s dataWithJSONObject:anArray options:(0 as integer) |error|:(missing value)
  
set resString to current application’s NSString’s alloc()’s initWithData:jsonData encoding:(current application’s NSUTF8StringEncoding)
  
return resString
end array2DToJSONArray

–リストに入れたレコードを、指定の属性ラベルの値でソート
on sortRecListByLabel(aRecList as list, aLabelStr as list, ascendF as list)
  set aArray to current application’s NSArray’s arrayWithArray:aRecList
  
  
set aCount to length of aLabelStr
  
set sortDescArray to current application’s NSMutableArray’s new()
  
repeat with i from 1 to aCount
    set aLabel to (item i of aLabelStr)
    
set aKey to (item i of ascendF)
    
set sortDesc to (current application’s NSSortDescriptor’s alloc()’s initWithKey:aLabel ascending:aKey)
    (
sortDescArray’s addObject:sortDesc)
  end repeat
  
  
return (aArray’s sortedArrayUsingDescriptors:sortDescArray) as list
end sortRecListByLabel

script webD
  —
  
–  Created by: Takaaki Naganoya
  
–  Created on: 2020/06/20
  
—
  
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
  
—
  
use AppleScript
  
use framework "Foundation"
  
use framework "AppKit"
  
use framework "WebKit"
  
use scripting additions
  
property parent : AppleScript
  
  
property |NSURL| : a reference to current application’s |NSURL|
  
property NSAlert : a reference to current application’s NSAlert
  
property NSString : a reference to current application’s NSString
  
property NSButton : a reference to current application’s NSButton
  
property WKWebView : a reference to current application’s WKWebView
  
property WKUserScript : a reference to current application’s WKUserScript
  
property NSURLRequest : a reference to current application’s NSURLRequest
  
property NSRunningApplication : a reference to current application’s NSRunningApplication
  
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding
  
property WKUserContentController : a reference to current application’s WKUserContentController
  
property WKWebViewConfiguration : a reference to current application’s WKWebViewConfiguration
  
property WKUserScriptInjectionTimeAtDocumentEnd : a reference to current application’s WKUserScriptInjectionTimeAtDocumentEnd
  
  
property returnCode : 0
  
  
  
on displayWebDialog(paramObj)
    my performSelectorOnMainThread:"browseStrWebContents:" withObject:(paramObj) waitUntilDone:true
  end displayWebDialog
  
  
on browseStrWebContents:paramObj
    set aMainMes to myMessage of paramObj as string
    
set aSubMes to mySubMessage of paramObj as string
    
set htmlString to (htmlStr of paramObj) as string
    
–set jsDelimList to (jsDelimiters of paramObj) as list
    
set webSize to (viewSize of paramObj) as list
    
    
copy webSize to {aWidth, aHeight}
    
    
–WebViewをつくる
    
set aConf to WKWebViewConfiguration’s alloc()’s init()
    
    
set aWebView to WKWebView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight)) configuration:aConf
    
aWebView’s setNavigationDelegate:me
    
aWebView’s setUIDelegate:me
    
aWebView’s setTranslatesAutoresizingMaskIntoConstraints:true
    
using terms from scripting additions
      set bURL to |NSURL|’s fileURLWithPath:(POSIX path of (path to me))
    end using terms from
    
aWebView’s loadHTMLString:htmlString baseURL:(bURL)
    
    
–Move to frontmost (By edama2)
    
current application’s NSApplication’s sharedApplication()’s setActivationPolicy:(current application’s NSApplicationActivationPolicyRegular)
    
current application’s NSApp’s activateIgnoringOtherApps:(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:aWebView
      
      
set myWindow to its |window|
    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
    
    
##後始末
    
aWebView’s stopLoading()
    
set js to "window.open(’about:blank’,’_self’).close();"
    
aWebView’s evaluateJavaScript:js completionHandler:(missing value)
    
set aWebView to missing value
    
  end browseStrWebContents:
  
  
  
on doModal:aParam
    set (my returnCode) to (aParam’s runModal()) as number
  end doModal:
  
  
  
on viewDidLoad:aNotification
    return true
  end viewDidLoad:
  
  
  
on fetchJSSourceString(aURL)
    set jsURL to |NSURL|’s URLWithString:aURL
    
set jsSourceString to NSString’s stringWithContentsOfURL:jsURL encoding:(NSUTF8StringEncoding) |error|:(missing value)
    
return jsSourceString
  end fetchJSSourceString
  
  
  
on pickUpFromToStr(aStr as string, s1Str as string, s2Str as string)
    using terms from scripting additions
      set a1Offset to offset of s1Str in aStr
      
if a1Offset = 0 then return false
      
set bStr to text (a1Offset + (length of s1Str)) thru -1 of aStr
      
set a2Offset to offset of s2Str in bStr
      
if a2Offset = 0 then return false
      
set cStr to text 1 thru (a2Offset – (length of s2Str)) of bStr
      
return cStr as string
    end using terms from
  end pickUpFromToStr
  
  
  
–リストを任意のデリミタ付きでテキストに
  
on retArrowText(aList, aDelim)
    using terms from scripting additions
      set aText to ""
      
set curDelim to AppleScript’s text item delimiters
      
set AppleScript’s text item delimiters to aDelim
      
set aText to aList as text
      
set AppleScript’s text item delimiters to curDelim
      
return aText
    end using terms from
  end retArrowText
  
  
on array2DToJSONArray(aList)
    set anArray to current application’s NSMutableArray’s arrayWithArray:aList
    
set jsonData to current application’s NSJSONSerialization’s dataWithJSONObject:anArray options:(0 as integer) |error|:(missing value) –0 is
    
set resString to current application’s NSString’s alloc()’s initWithData:jsonData encoding:(current application’s NSUTF8StringEncoding)
    
return resString
  end array2DToJSONArray
  
  
  
on parseByDelim(aData, aDelim)
    using terms from scripting additions
      set curDelim to AppleScript’s text item delimiters
      
set AppleScript’s text item delimiters to aDelim
      
set dList to text items of aData
      
set AppleScript’s text item delimiters to curDelim
      
return dList
    end using terms from
  end parseByDelim
  
end script

on retHTML()
  return "<!doctype html>
<head>
<meta charset=\"utf-8\">
<!– Styles –>
<style>
body { background-color: #000000; color: #ffffff; }
#chartdiv {
width: 100%;
height: 500px;
}

</style>
</head>
<body>

<!– Resources –>
<script src=\"https://www.amcharts.com/lib/4/core.js\"></script>
<script src=\"https://www.amcharts.com/lib/4/charts.js\"></script>
<script src=\"https://www.amcharts.com/lib/4/themes/dark.js\"></script>
<script src=\"https://www.amcharts.com/lib/4/themes/animated.js\"></script>

<!– Chart code –>
<script>
am4core.ready(function() {

// Themes begin
am4core.useTheme(am4themes_dark);
am4core.useTheme(am4themes_animated);
// Themes end

// Create chart instance
var chart = am4core.create(\"chartdiv\", am4charts.PieChart);

// Add data
chart.data = %@;

// Add and configure Series
var pieSeries = chart.series.push(new am4charts.PieSeries());
pieSeries.dataFields.value = \"value\";
pieSeries.dataFields.category = \"label\";
pieSeries.slices.template.stroke = am4core.color(\"#fff\");
pieSeries.slices.template.strokeOpacity = 1;

// This creates initial animation
pieSeries.hiddenState.properties.opacity = 1;
pieSeries.hiddenState.properties.endAngle = -90;
pieSeries.hiddenState.properties.startAngle = -90;

chart.hiddenState.properties.radius = am4core.percent(0);

}); // end am4core.ready()
</script>

<!– HTML –>
<div id=\"chartdiv\"></div>
</body>
</html>"

end retHTML

★Click Here to Open This Script 

Posted in JSON Review | Tagged 12.0savvy NSAlert NSButton NSRunningApplication NSString NSURL NSURLRequest Service Station WKUserContentController WKUserScript WKUserScriptInjectionTimeAtDocumentEnd WKWebView WKWebViewConfiguration | Leave a comment

Service Stationと他のメニュー系AppleScript実行環境との比較

Posted on 1月 28, 2022 by Takaaki Naganoya

AppleScriptの実行環境のうち、メニューから実行するタイプのものと「Service Station」の比較を行なってみました。

■Service Station


コンテクストメニューからAppleScriptを実行するツール。Finder上で選択中のファイルに応じてコンテクストメニューに表示する内容を変更できる。

■Script Menu(Apple)


macOS標準装備、メニューバーから呼び出し可能。アプリケーションごとに自動メニュー切り替え。指定フォルダ以下の内容を階層化したメニューとして表示する。

■Shorcuts Events(Apple)


macOS 12より標準装備。ショートカットをメニューバーから実行できる。メニューバーに表示するよう指定したものが表示される。階層化メニューはサポートしていない。単なるメニューのくせに、アホみたいに動作が遅い。壊れているのかと思えるほど。iCloudを経由して第三者にアクションを配布できるようになっている点が他の環境にない特徴。ただし、まだバグの塊。

■Switch Control(Apple)

macOS標準装備。アクセシビリティ系の機能。画面上に自由に配置できるフローティングパレット式AppleScriptランチャー。知る人ぞ知る超便利機能!!!

■FastScript 3(Red Sweater Software)


Script Menuの強化版。よく使うScriptを上に表示するとか、キーボードショートカットを設定して呼び出せる。キーワード検索によりScriptの絞り込みがインクリメンタルに行えるなど、大量のScriptを効率的に呼び出すための機能を備える。

AS実行環境としてはまだこなれていないService Station

Program Name Name of runtime Support AppleScript document format AS Format NSAlert dialog is displayed in frontmost Can use GUI Scripting functions Can call AppleScript Libraries? Can call AS Library including Frameworks? Can call Generic Cocoa Functions? Can use Cocoa system notification functions?
Service Station osascript Script/Text Script/Applet Script/Text Script No Yes Yes No Yes No
Script Menu osascript Script/Scriptd/Applet Script/Scriptd Yes Yes Yes No Yes Yes
Shortcuts Events MacHelper File Embedded Script Text Yes Yes Yes No Yes No
Switch Control Assistive Control File Embedded Script Script (archived) Yes Yes No No Yes No
FastScript 3 FastScripts Script Runner Script/Scriptd/Applet Script/Scriptd Yes Yes Yes No Yes

GUIなしプロセス中でosascript経由でAppleScriptの実行を行なっているので、Service StationだけNSAlertによるダイアログ表示が最前面に出てこないという問題があります。

ホームディレクトリ下のAppleScriptライブラリは呼べるし、Cocoaの機能やGUI Scriptingの機能も呼べる、標準的な環境に近いレベルにはあると思われます。

実行Scriptにバンドル形式のAppleScript(.scptd)を指定できないというのは、激弱としかいいようがありませんが、作者がバンドル形式のAppleScriptのことを知らないことが原因のように見えます。

コンテクストメニューからAppleScriptを呼び出せるようにする、というのは他のツールに見られない特徴といえますが、いまScript Menuに入れている膨大なファイル処理系のScriptを、そのままコンテクストメニューから呼べるようにすると、邪魔すぎます(膨大なScriptが表示されて上下にスクロールしまくり)。

コンテクストメニューへの階層メニュー表示をサポートしないと、自分は他のツールで使っているScriptを移行させられません。ただ、そこまでメニューにAppleScriptをホスティングしているユーザーはそうそういなさそうなので、機能強化してもそれに追いついてこられるユーザーが少なさそう。

作業で使うAppleScriptを、その場でちょっとだけ呼び出すようにして運用しないと、大量のAppleScriptがあふれかえって運用そのものが行えません。使い所が難しいツールといえるのかも? 

自分が「欲しい」と思える機能は、結局自分で作るしかなさそうな気配がしています。


▲Script Menuから呼び出している、Finder上で選択中のファイルに対して実行するScript群。こんなのコンテクストメニューには表示し切れない

Posted in Review | Tagged 12.0savvy Service Station | Leave a comment

マウスの右クリックメニューをカスタマイズするService Station

Posted on 1月 26, 2022 by Takaaki Naganoya

マウスの右クリックで表示されるコンテクストメニューをカスタマイズするツール、「Service Station」(Version 2020.9 (23))を購入して、macOS 12.2+M1 Mac miniの環境で試してみました。

同ツールはMac App Storeで販売されており、フリーでダウンロードしたのち、App内購入(1,840円)で購入できます。

OS標準のScript MenuにFinder上で選択中のファイルを対象としたAppleScriptを大量に仕込んで使っていますが、やはりコンテクストメニューから呼び出せたほうが便利なので、試してみることにしました。

Mac App Storeからダウンロードした状態(フリーで使えるお試し版)ではAppleScriptの起動はできないため、App内購入が必要です。

サポートページ(Github)、Twitterアカウントなどが公開されています。

この手のツールは、AppleScriptに対する知識が少ないデベロッパーが開発したものが多く、実際に使ってみると不満を覚える確率がきわめて高いジャンルです。これまでにも、実際に試すと「使い物にならない」と判断したツールがほとんどであるため、十分な検証が必要でしょう。

# デフォルト状態でAppleScriptの実行を指定できないのは、試用版の制限なのでご注意ください。

Service StationでAppleScript書類をコンテクストメニューから処理してみよう

本ツールのUser Interfaceはきわめてシンプルです。「Rules」でどのようにファイルを特定し、「Menu Items」でオープンするアプリケーションやAppleScriptを指定します。

初期状態では、「Folders」「Images」「Text」の3つのRulesが設定されています。ここに、AppleScript書類を処理するRulesを追加してみましょう。

どのような方法でAppleScript書類を特定できるのか、Rulesのポップアップを調べてみると……

「Kind -> Script」で「AppleScript」を指定するとよさそうです。Rulesを指定したあとで、「Menu Items」にサンプルScriptを指定してみましょう。特定のハンドラ宣言を記述したAppleScriptをここに指定できるようになっています(フラットなScriptだけであってバンドル形式は予想どおり実行できません)。


▲実行Scriptとしてバンドル形式のAppleScript書類(.scptd)を認識しないので、バンドル内に実行バイナリやAppleScriptライブラリを突っ込むのは無理

Service Stationで実行指定するAppleScriptは、~/Library/Application Scripts/com.knurling.ServiceStation.Attendant フォルダに入れる必要があります。

Finder上で試してみると…..AppleScript書類(.scpt、.scptd)を認識しません(ーー;;;


▲この設定にしたくなるが、この指定方法だとAppleScript書類(.scptおよび.scptd)を認識しない。罠なのでこの設定はしてはいけない。作者は.applescriptのテキスト形式のAppleScriptしか試していないもよう

この作者は「AppleScript書類」をテキスト形式(.applescript)でしかチェックしていないようです。なので、さきほどの「Rules」で提示された「Kind -> Script is AppleScript」は罠(Trap)なので選択してはいけません。

拡張子で指定しても応答しません(scpt、scptd)。RulesでUTIを指定できるようなので、

フラットなScript書類「com.apple.applescript.script」、バンドルScript書類「com.apple.applescript.script-bundle」、Script DebuggerのバンドルScript書類「com.latenightsw.osa.bundle」をAny条件で(どれかがヒットしたら該当したものとみなす)登録してみました。

はい。今度は問題なく、Finder上でAppleScript書類を選択した状態で表示させた(マウスの右クリック)コンテクストメニューでサンプルAppleScript(処理用のハンドラを記載しただけ)がメニューに表示され、添付のサンプルScript(「System Setup」タブの「Sample Scripts」ボタンを押すと表示される)を実行できました。

Service Station経由で実行したAppleScript(サンプルScript)は以下のような内容です。

AppleScript名:AppleScript.scpt
on serviceStationDidSelect(targetedURL, selectedItemURLs, menuKind)
  display dialog "targetedURL:
" & targetedURL & "

" & "selectedItemURLs:
"
& selectedItemURLs & "

" & "menuKind:
"
& menuKind
end serviceStationDidSelect

★Click Here to Open This Script 

ランタイム環境はosascript

お約束で、Service StationのAppleScriptランタイム環境名は知っておかなければいけないので、

AppleScript名:Runtime名を表示.scpt
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

on serviceStationDidSelect(targetedURL, selectedItemURLs, menuKind)
  set procInfo to current application’s NSProcessInfo’s processInfo()
  
set aName to procInfo’s processName() as string
  
display dialog aName
end serviceStationDidSelect

★Click Here to Open This Script 

こんなAppleScriptを書いて実験してみると….

のように、「osascript」を呼び出して実装していることがわかりました。

NSAlertダイアログを表示するも、最前面に表示されず

ランタイム環境が「osascript」だと、自前でアラートダイアログを表示させたときに「最前面に表示されない」といった問題が生じる可能性があります(osascriptでお手軽実装するの勘弁してほしい。Script側に苦労を押し付けないでほしい)。あとは、GUIなしプロセスで実行するようなので、GUI Scriptingの認証を通せるか不明です。

また、どこぞのネット上のサーバー上のREST APIにアクセスしようとしてもセキュリティ上の制約で「アクセスできない」可能性もあります(実行プロセス側でネット接続の許可をもらっていないと無理)。今後も検証が必要です。

現時点でみつけた「おや?」という仕様は、Rulesでルールを作った状態で複数のAppleScript書類を選択すると、コンテクストメニューにService Stationの項目が出てこないという点です。画像の複数選択には反応するようですが、自前で設定したRulesだと複数ファイル選択時に応答しません。

# これは、追試によって設定アプリケーションを終了させるまで設定が反映されない部分があることが判明

また、Service StationのRulesから呼び出すAppleScriptのハンドラで、受け渡されるのはHFS path stringであってURLではありませんし(fURLなのか?)、複数のURLを受信できるような表記がありながらも、本バージョンでは1つのURL(正確にはHFS path)しか受け渡されません。

# 追試の結果、複数のパス(fURL)が受け渡されていることが判明

本ツールの開発者はAppleScriptを日常的に書いていない気配が濃厚ですが、それでも修正されれば我慢できないというほどでもないでしょう。


▲予想どおり、NSAlertのダイアログを表示してもランタイムがosascriptなので最前面に表示されなかった(GUIなしの不可視プロセスからosascriptを実行した際の挙動)。CDN上のJavaScriptライブラリの呼び出しは行えた

パラメータの型チェックを試してみました。

AppleScript名:パラメータの型チェック.scpt
on serviceStationDidSelect(targetedURL, selectedItemURLs, menuKind)
  set c1 to (class of targetedURL) as string
  
set c2 to (class of selectedItemURLs) as string
  
set c3 to (class of menuKind) as string
  
  
display dialog "targetedURL:
" & c1 & "

" & "selectedItemURLs:
"
& c2 & "

" & "menuKind:
"
& c3
end serviceStationDidSelect

★Click Here to Open This Script 

サンプルScriptの記述がよくないせいで勘違いしてしまったようです。targetedURLはfURL、selectedItemURLsはList、menuKindはintegerで返ってきていました。

ホームディレクトリ内のAppleScriptライブラリを呼び出す

コンテクストメニューから呼び出すAppleScript内で、ホームディレクトリ以下のAppleScriptライブラリを呼び出すことができるか確認してみました。

結論:呼べる

AppleScript名:AppleScript v2_with_Library.scpt
use AppleScript version "2.4"
use scripting additions
use radioLib : script "displayTextView"

on serviceStationDidSelect(targetedURL as «class furl», selectedItemURLs as list, menuKind as integer)
  set aStr to do shell script "cal 2022"
  
display text view aStr main message "Main Message" sub message "Sub Message" with properties {font name:"Courier", size:13, width:600, height:300}
end serviceStationDidSelect

★Click Here to Open This Script 

Posted in news Review | Tagged 12.0savvy NSProcessInfo Service Station | Leave a comment

16bitカラー値から明度を取得 v1.1

Posted on 1月 20, 2022 by Takaaki Naganoya

choose colorコマンドやiWorkアプリケーションが返してくる16ビットのカラー値({R,G,B})から明度情報を取得するAppleScriptです。0から1までの値を返し、0に近づくほど暗く、1に近づくほど明るい色であることを表現しています。

色情報同士を比較して、明るい箇所に指定している色データと暗い箇所に指定している色データを、RGB値から自動認識するような処理に使っています。

また、ファイル名から「章」(Chapter)の番号を検出して、実際のツメ(Index)の選択部分を暗い色で塗り直す処理も行なっています。

–> Watch Demo Movie

Pages書類の上に作成したツメ(辞書などの端に印刷されているAからZのインデックス)に対して、ツメのオブジェクトを(座標や形状から)自動認識したあとに、色の塗り分け情報を本ルーチンを用いて自動認識。濃い色を現在の選択箇所の色、明るい(淡い)色を通常の箇所の色情報として扱い、あらかじめツメに指定していた色情報を用いて実際の章構成を反映させてツメのオブジェクト(表)を再構成する処理に必須のものです。

明度情報の取得には、グレースケールに変換してグレー度(whiteComponent)を明度とみなして計算しています。直感的にこちらのほうが、まっとうな処理(HSB色空間の色に変換してからBrightnessを取得)よりもしっくり来る計算結果だったので採用しています。

おまけで、2つの色情報のうちどちらが暗いか、結果をインデックス値で返す処理ルーチンをつけています。これも、選択色と非選択色の自動識別のために必要なものです。

AppleScript名:16bitカラー値から明度を取得 v1.1.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/01/20
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—

set a1Col to {26148, 65535, 58650}
set a1Col to choose color default color a1Col
set w1Col to calcBrightnessFrom16bitColorList(a1Col) of colorBrightnessKit
–> 0.900838315487

set a2Col to {2966, 23133, 21203}
set a2Col to choose color default color a2Col
set w2Col to calcBrightnessFrom16bitColorList(a2Col) of colorBrightnessKit
–> 0.37399661541–0に近いのでこちらのほうが暗い

set cIndRes to calcColorPairsDarkerCol(a1Col, a2Col) of colorBrightnessKit
–> {2, 1}–暗い順にインデックス値を返す

–色情報から明度を計算するKit。0に近い値が暗い。CMYKやグレースケール値は対象外。RGBのみ
script colorBrightnessKit
  
  
use AppleScript
  
use framework "Foundation"
  
use framework "AppKit"
  
use scripting additions
  
property parent : AppleScript
  
  
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
  
  
  
–2つの16ビットカラー値でそれぞれ明度を計算し、暗いものから順にインデックス値を返す
  
on calcColorPairsDarkerCol(aCol as list, bCol as list)
    set b1 to calcBrightnessFrom16bitColorList(aCol) of me
    
set b2 to calcBrightnessFrom16bitColorList(bCol) of me
    
if b1 ≥ b2 then
      return {2, 1} –bColのほうが暗い
    else
      return {1, 2} –aColのほうが暗い
    end if
  end calcColorPairsDarkerCol
  
  
  
–16ビットカラー値から明度を計算
  
on calcBrightnessFrom16bitColorList(colList as list)
    copy colList to {rVal, gVal, bVal}
    
–NSColorを作成
    
set aCol to makeNSColorFromRGBAval(rVal, gVal, bVal, 65535, 65535) of me
    
— グレースケール化
    
set gCol to aCol’s colorUsingColorSpaceName:(NSDeviceWhiteColorSpace)
    
set wComp to gCol’s whiteComponent() –whiteComponentを取得することで擬似的に明度情報を取得  
    
return wComp
  end calcBrightnessFrom16bitColorList
  
  
  
–HTMLカラー値あから明度を計算
  
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
end script

★Click Here to Open This Script 

Posted in Color list | Tagged 10.15savvy 11.0savvy 12.0savvy NSColor | Leave a comment

SafariでブックマークされたURL一覧を取得

Posted on 1月 7, 2022 by Takaaki Naganoya

Safariのブックマークに登録されたURL一覧を取得するAppleScriptです。

SafariのAppleScript対応機能に、ブックマーク操作系のものは存在していません。そのため、Bookmarks.plistを直接読み込んでデータの絞り込みを行なっています。

Bookmarks.plistを実際に読んでみると、ツリー(フォルダ)とリーフ(個別のブックマーク)があって、本Scriptではリーフ部分しか読んでいないのですが、とりあえず試作レベルということで。

読むのはいいんですが、追加が大変そうなので(BookmarkのIDとか外部で勝手に追加できるものなんだろうか。UUIDっぽいけど)ブックマーク登録は野蛮にGUI Scripting経由でメニューを操作することになるのでしょう。

AppleScript名:SafariのBookmarks.plistから登録URLを取得
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/01/07
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.7"
use framework "Foundation"
use scripting additions

script spdB
  property urlList : {}
end script

set (urlList of spdB) to getBookmarkedURLs() of me
set (urlList of spdB) to cleanUp1DList((urlList of spdB), missing value) of me –Sweep missing value items

–Read Bookmarked URLs
on getBookmarkedURLs()
  set newPath to "~/Library/Safari/Bookmarks.plist"
  
set aRec to my readPlistAt:newPath
  
return ((aRec’s Children)’s valueForKey:"URLString") as list
end getBookmarkedURLs

–Read Plist
on readPlistAt:thePath
  set thePath to current application’s NSString’s stringWithString:thePath
  
set thePath to thePath’s stringByExpandingTildeInPath()
  
set theDict to current application’s NSDictionary’s dictionaryWithContentsOfFile:thePath
  
return theDict
end readPlistAt:

–1D Listのスイープ
on cleanUp1DList(aList as list, cleanUpItems as list)
  set bList to {}
  
repeat with i in aList
    set j to contents of i
    
if j is not in cleanUpItems then
      set the end of bList to j
    end if
  end repeat
  
return bList
end cleanUp1DList

★Click Here to Open This Script 

Posted in Record | Tagged 10.15savvy 11.0savvy 12.0savvy Safari | Leave a comment

Intel MacとApple Silicon Macの速度差〜画像処理

Posted on 1月 2, 2022 by Takaaki Naganoya

macOS 11から12に移行して、なぜかリリースが近づくにつれて細かいバグや巨大なバグが顕在化し、まだ手放しでおすすめできる状況にないのが心苦しいところですが、AppleScriptからのCocoa呼び出しについてはIntel Mac/Apple Silicon Macでも速度が向上。とくに、Apple Silicon Macでの速度向上が顕著です。

で、特定の処理(巨大なlistやrecord in list同士の検索)でM1 Mac miniがiMac Proの2.5倍ぐらい速いといったベンチマークは出しているわけですが、いかにもApple Silicon Macで処理が速そうな画像処理のベンチマークを実施してみました。

Intel Mac mini 2014が手元からなくなってしまったので、以前のメインマシンであったMacBook Pro Retina 2012(MacBookPro10,1)と比較してみました。

ベンチマーク内容は、指定の画像が空白かどうかをチェックするというものです。フルHD画像でも4K画像でも8K画像でも、1ピクセルでも白くない点があれば検出できるという処理内容。外部のGPUImage FrameworkやPhotoshopのヒストグラム処理を呼び出すよりもAppleScriptだけで処理した方が速いというものです(8K画像だとPhotoshopの方が速いかも)。


▲画像解像度の変化と処理時間の相関。グラフは数値が小さいほど高速。巨大な画像になると処理速度差が大きくなる傾向にある?

だいたい、MacBook Pro Retina 2012と比べて3〜4倍ぐらいM1 Mac miniの方が高速です。MacBook Pro Retina 2012は2017年のMacBook Pro 13インチといい勝負ぐらいの速度が出ており、古い割にはごく最近まで使えていました。

そこから3〜4倍高速ということで、M1 Mac miniはコストの割にはパワフルです。ファンレスのMacBook Air M1でも同程度の速度が出るはずです。

一方で、M1 Pro/M1 Max搭載のMacBook ProでM1機よりも大幅に高速なのかと言われると……このぐらいの静止画の処理程度だとごくわずかな差しかつかないはずです。下手をすると、速度差がないかもしれません。

→ Download blank_image_detection_benchmark.zip (including script libraries)

–> Download test Data


▲バーが短いほど高速。M1がM1 Maxの2倍高速という結果が出てしまった。M1 Max MBPは2014年のIntel Mac miniより少し速いだけのマシンという結果に。2018年のIntel Mac miniとの比較だとM1 Max MBPよりもIntel Mac miniのほうが速そう

M1、M1 Max、M1 Ultra(最上位機種)で処理時間を比較した結果。予想どおりM1がM1 MaxやM1 Ultraよりも2倍以上高速。もはや8K画像ぐらいは、大きなデータにならないというべきなのか。

AppleScript名:画像の空白判定 v4_bench_時間計測.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/01/01
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.7"
use framework "Foundation"
use framework "AppKit"
use scripting additions
use mdLib : script "Metadata Lib" version "2.0.0"
use easyTable : script "display table by list"

set aFol to choose folder

set aResList to perform search in folders {aFol} predicate string "kMDItemContentTypeTree CONTAINS %@" search arguments {"public.image"}

set aList to {}
repeat with i in aResList
  set a1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
  
  
set iRes to checkImageIsWhite(i) of blankImageKit of me
  
  
set b1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
  
set c1Dat to b1Dat – a1Dat
  
  
set aName to (current application’s NSString’s stringWithString:i)’s lastPathComponent() as string
  
  
if iRes = true then
    set jRes to "White"
  else
    set jRes to "Black"
  end if
  
  
–log {aName, jRes}
  
  
set the end of aList to {aName, jRes, c1Dat}
end repeat

set fLabels to {"File name", "Result", "Estimate(Seconds)"}
set aRes to (display table by list aList main message "Blank Image check" size {800, 600} labels fLabels)
return aList

script blankImageKit
  use AppleScript version "2.7" — High Sierra (10.13) or later
  
use framework "Foundation"
  
use framework "AppKit"
  
use scripting additions
  
property parent : AppleScript
  
  
property NSData : a reference to current application’s NSData
  
property |NSURL| : a reference to current application’s |NSURL|
  
property NSColor : a reference to current application’s NSColor
  
property NSImage : a reference to current application’s NSImage
  
property NSBezierPath : a reference to current application’s NSBezierPath
  
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep
  
  
  
–Compare Original Data and
  
on checkImageIsWhite(aFile)
    set aPOSIXpath to POSIX path of aFile
    
set aURL to |NSURL|’s fileURLWithPath:(aPOSIXpath)
    
    
set aNSImage to NSImage’s alloc()’s initWithContentsOfURL:(aURL)
    
set bNSImage to NSImage’s alloc()’s initWithContentsOfURL:(aURL)
    
    
set fillColor1 to NSColor’s clearColor()
    
set blankNSImage1 to drawImageWithFilledColor(aNSImage, fillColor1) of me
    
    
set fillColor2 to makeNSColorFromRGBAval(65535, 65535, 65535, 65535, 65535) of me –white
    
set blankNSImage2 to drawImageWithFilledColor(bNSImage, fillColor2) of me
    
    
set aTiff to blankNSImage1’s TIFFRepresentation()
    
set bTiff to blankNSImage2’s TIFFRepresentation()
    
    
set chkWhite to (aTiff’s isEqualToData:bTiff) as boolean
    
    
return chkWhite
  end checkImageIsWhite
  
  
  
on getSizeOfImage(anNSImage)
    set aSize to anNSImage’s |size|()
    
set aClass to class of aSize
    
if aClass = record then
      copy aSize to theSize –To macOS 10.12.x
    else –macOS 10.13 or later
      set sizeX to (item 1 of item 2 of aSize)
      
set sizeY to (item 2 of item 2 of aSize)
      
set theSize to {width:sizeX, height:sizeY}
    end if
    
return theSize
  end getSizeOfImage
  
  
  
–指定サイズの画像を作成し、背景を指定色で塗る
  
on drawImageWithFilledColor(anImage, fillColor)
    set aSize to getSizeOfImage(anImage) of me
    
    
anImage’s lockFocus()
    
    
set theRect to {{x:0, y:0}, {width:(width of aSize), height:(height of aSize)}}
    
set theNSBezierPath to NSBezierPath’s bezierPath
    
theNSBezierPath’s appendBezierPathWithRect:theRect
    
fillColor’s |set|()
    
theNSBezierPath’s fill()
    
    
anImage’s unlockFocus()
    
    
return anImage
  end drawImageWithFilledColor
  
  
  
–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
  
end script

★Click Here to Open This Script 

Posted in Image | Tagged 10.14savvy 10.15savvy 11.0savvy 12.0savvy NSBezierPath NSBitmapImageRep NSColor NSData NSDate NSImage NSURL | Leave a comment

Post navigation

  • Older posts
  • Newer posts

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

Google Search

Popular posts

  • 開発機としてM2 Mac miniが来たのでガチレビュー
  • CotEditorで2つの書類の行単位での差分検出
  • macOS 15, Sequoia
  • 指定のWordファイルをPDFに書き出す
  • Pages本執筆中に、2つの書類モード切り替えに気がついた
  • Adobe AcrobatをAppleScriptから操作してPDF圧縮
  • メキシカンハットの描画
  • 与えられた文字列の1D Listのすべての順列組み合わせパターン文字列を返す v3(ベンチマーク用)
  • Numbersで選択範囲のセルの前後の空白を削除
  • Pixelmator Pro v3.6.4でAppleScriptからの操作時の挙動に違和感が
  • AdobeがInDesign v19.4からPOSIX pathを採用
  • Safariで「プロファイル」機能を使うとAppleScriptの処理に影響
  • Cocoa Scripting Course 続刊計画
  • AppleScriptによる並列処理
  • macOS 14.xでScript Menuの実行速度が大幅に下がるバグ
  • NaturalLanguage.frameworkでNLEmbeddingの処理が可能な言語をチェック
  • AppleScript入門③AppleScriptを使った「自動化」とは?
  • Keynote/Pagesで選択中の表カラムの幅を均等割
  • macOS 15 リモートApple Eventsにバグ?
  • Keynote、Pages、Numbers Ver.14.0が登場

Tags

10.11savvy (1102) 10.12savvy (1243) 10.13savvy (1392) 10.14savvy (587) 10.15savvy (438) 11.0savvy (283) 12.0savvy (212) 13.0savvy (189) 14.0savvy (141) 15.0savvy (119) CotEditor (66) Finder (51) iTunes (19) Keynote (115) 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 (54) 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
  • 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年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