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

macOS 12.3上でFinder上で選択中のファイルをそのままオープンできない件

Posted on 3月 28, 2022 by Takaaki Naganoya

macOS 12.xはAppleScriptの処理系に対して、主にセキュリティ面でいろいろ修正が加わっています。

この修正は、セキュリテイを「高める」という名目のもとに行われているのですが、セキュリティ面での課題さえ片付けられれば、その他に悪影響を及ぼしていたとしても「知ったことではない」というのがAppleの態度です。そして、その問題に対してユーザー側から文句が出てこなければ、そのままです。

–> View Demo Movie

とくに、深謀遠慮な考えとか、素晴らしい見通しとかはなく、「上から言われたからやっている」というやっつけ仕事感を感じます。

AppleはSteve Jobsが作り上げた秘密警察みたいな組織になっていて、チーム間の権限の切り分けが病的なまでに行われており、チームが違うと会社が違うぐらいの隔たりが発生しています。それは、Steve Jobsという「垣根を無視して横断して歩く異物」がいたから成立する組織であって、官僚化、硬直化が絶賛進行中といったところです。

話を戻しますが….たしかに、そうした機能的なアップを伴わない修正で何も問題(副作用)が起こらなければ「セキュリティが高まったのでよかったね」という美談になるわけですが、たいていの場合にはそうなりません。意図していなかった箇所に副作用が生じます。

あるいは、セキュリティのポリシー同士が実は矛盾を生んでいる、という状況になっていて、Aという問題とBという問題を解決した結果、あらたにCというもっと巨大な問題が発生する、とかいった状況は容易にあり得るわけです。それでも、各担当者は誠意をもってその仕事に取り組んでいるわけで、こうした「人間的に尊敬できて素晴らしい能力を持ったスタッフ」による「熱心かつ誠意あふれる真摯な仕事」が合成された結果、「見たことも聞いたこともない間抜けな理由から生じる猛毒にまみれた悪意」が合成されてしまうことが、現在のTim CookのAppleの下ではあり得るのです。

「Finder上で選択中のファイルをそのままオープンする」

というのは、ここ数年というよりもAppleScriptを覚えたてのころにちょろっと書いて実行したぐらいであり、実際のところ「それがどうした?」というレベルの処理です。

AppleScript名:Finder上で選択中のファイルをオープン.scpt
–macOS 12.3でエラーになる処理
tell application "Finder"
  open selection
end tell

★Click Here to Open This Script 

Finder上で選択したファイルに対する処理は、きょうび何かのアプリケーションに渡さなくてもAppleScriptだけで処理できてしまうことが多いということもありますし(画像とか)、選択されたファイルをそのままオープンするという「1=1」みたいな処理はやりません。

選択したフォルダの中をすべてSpotlight経由で走査して、指定の形式のファイルだけをリストアップして、順次処理するようなものになっています。

ただ、10年たっても20年たっても「1=1」みたいな処理しかしていない人がけっこういて驚かされると同時に、意外なところで(Adobeのアプリケーションでアプリケーション間の連携に)使っていたりして、修正されないと困るケースは多いようです。

Shane StanleyがLateNight Softwareのフォーラムに投稿した、こうした処理への迂回Scriptがありました。さすがです。

Finder経由で書類のオープンと、その書類を作成したアプリケーションの起動を促すという、macOS 12.3で問題が起こっている処理を、Cocoaの機能を用いることで迂回してしまおうというものです。

ただ、そのままではFinder上で指定したファイルを1つオープンするという実証コードのレベルのものだったので、複数のファイルが選択されたものをオープンするように書き足してみました。

AppleScript名:macOS 12.3でFinder上の選択中のファイルをオープン.scpt
—
–  Created by: Shane Stanley
–  Created on: 2022/03/24

–  Modified by: Takaaki Naganoya
–  Modified on: 2022/03/27
—
— macOS 12.3でFinder上のselectionをただopenすると、作成したアプリケーションは起動するが、書類はオープンされないバグ
– に対処したもの。複数ファイルの選択状態を処理する場合がほとんどなので、若干追記
– ただ、漫然と選択したファイルをオープンするという処理はやっていないので(なにがしかの処理を自前でやるので)

use framework "AppKit"
use framework "Foundation"
use scripting additions

tell application "Finder"
  set aSel to selection as alias list
  
if aSel = {} then return
end tell

openFiles(aSel) of me

on openFiles(pathList as list)
  repeat with i in pathList
    set j to contents of i
    
openFile(POSIX path of j) of me
  end repeat
end openFiles

on openFile(thePath as string) — POSIX path
  set ws to current application’s NSWorkspace’s sharedWorkspace()
  
set theURL to current application’s |NSURL|’s fileURLWithPath:thePath
  
ws’s openURL:theURL
end openFile

★Click Here to Open This Script 

Posted in Bug file news URL | Tagged 12.0savvy Finder | Leave a comment

macOS 12.x上のAppleScriptのトラブルまとめ

Posted on 3月 20, 2022 by Takaaki Naganoya

現在進行形で発生しているAppleScript系のトラブルについてまとめておきます。macOS 12になって、AppleScriptの処理系の根幹部分にいろいろ手が加わっており(だったら機能追加してほしい気がする)、不具合なのかセキュリティポリシーとの不整合なのか(そんなもん、社内で調整してほしい)よくわからない問題がいろいろ生じています。

Apple自身が機能ごとのリリースノートを出さないようになり、こういうときに困ります。macOS 12.xで見られた不具合の中には、かなりApple自身の邪悪なポリシー運用の結果として顕在化したものもあるので、明文化できないのでしょうか。何をやった結果として発生した問題である、と書いてしまうと「なんでAppleはそんな邪悪なことをやっているの?」と世界中からツッコミを受けるに違いありません。

問題1:Scriptを実行すると「表があふれました」と謎のエラーが表示される(解決したか不明)

macOS 12.3で解消されるか? と見ていましたが、完全に対処できている感じではない様子。
→ 関連情報:SkimのAppleScriptサポート機能にバグ
→ その後、この「表があふれました」エラーには遭遇していないので、問題は解決されたのでしょう。ただし、油断しているとmacOSのマイナーアップデート時に何かやらかす可能性があります。

問題2:12.3betaで発生した「AppleScript書類をオープンできない」問題(解決)

これについては、12.3Release版では発生していないもよう。息が止まるかと思うほど焦りました。電子書籍1つ作るにしても、手間のかかる作業の多くをAppleScriptで自動化。そうでなければ、そんなにポンポン書けません。

問題3:インストールされていないアプリケーションを操作するScriptをオープンできない(未解決)

ただし、そのMacにインストールされていないアプリケーションを操作するScriptをオープンしようとすると、これまでは「どのアプリケーションですか?」とユーザーに問い合わせしていましたが、これが一律にエラーになるようです。
→ macOS 12.5 beta5において、インストールされていないアプリケーションに対するAppleScriptをオープンした場合には、オリジナルのままオープンされ、コンパイル(構文確認)すると書き換えられるといった動作を行うことを確認しています

問題4:悪意を持って作られたAppleScriptバイナリ(アプレット?)のセキュリティ上の問題(CVE-2022-22626)(解決)

悪意を持って作成したAppleScriptバイナリは予期しない強制終了、ないしはプロセスが確保していたメモリを暴露(他のプロセスから読み書き&実行できてしまう?)する問題があったとのこと。

悪意を持って作ったことがないのと、ランタイムプログラムのメモリ処理の問題のようなので(???)、Scriptを書いている側には「そんなのあったの?」という話です。

個人的には、AppleScriptをアプレット化して動かすことは少なく、Script DebuggerかScript Menuで動かしている場合がほとんどです。

問題5:Finder上のselection itemsをオープンした際に、作成したアプリは起動されるがファイルはオープンされない問題

Finder上で選択したファイルを、指定のアプリケーションや、各ファイルを作成したアプリケーションで開かせようとした場合に、アプリケーションのプロセスは起動するものの、指定の書類はオープンされないという問題。macOS 12.3上で発生した新たな問題の様子。

先に対象のアプリケーションを起動しておくとファイルオープンの処理は通るというケースもあれば、そうではないというケースも。
→ macOS 12.3.1/12.4beta1で解消

問題6:macOS 12のスクリプトエディタで、Context Menu機能にバグ(未解決)


macOS 12のスクリプトエディタで、Script Assistantとして/Library/Scriptsに入れているAppleScriptをコンテクストメニューから呼び出せるようになっていますが、そこにカスタムScriptを入れて呼び出すと(絵文字入りファイル名)コンテクストメニュー上に重複した項目が表示されるというバグです。
→ 途中で「直った」という連絡をもらったのですが、まったく直っていませんでした。Appleのエンジニアは字が読めないか、目が見えないのでしょう。最低限、字が読めないとバグは取れないですよね?
→ macOS 14で解決

問題7:アプリケーション同士のイベントのやりとりが2回以上発生するとエラー-609になるバグ

macOS 12.5 beta 5で発生した前代未聞のバグ(?)。

現在のTim Cook体制下で狙っていると見られる「セキュリティ確保のためには動かないコンピュータが最高!」の思想を体現する機能の実現のためか、こうしたアプリケーション同士のイベントの送信をカウントしているようです。これがバグなのか意図したものなのかは不明ですが、カウントして準備を始めたということだけは言えるでしょう。

ただ、Dockに登録したアプリケーションに書類をドラッグ&ドロップすると3回目からはエラーになりますし、FinderのToolbarに登録したアプリケーションのアイコンを3回クリックしてもエラー-609になります。とうてい、まともな状態とは言えません。

macOS 12.5でこの機能がオンになるものとは思っていませんが、Apple側が何かよからぬ企みを行っていることだけは明らかです。

「地獄への道は善意で敷き詰められている」(The road to hell is paved with good intentions)という言葉があります。セキュリティ強化の美名のもとにこれが実現したとき、コンピュータが役立たずの置物になってしまいます。Tim Cook CEOによる最悪の施策として記憶されることでしょう。頭が悪すぎです。
→ macOS 12.5(21G69)で解決???? Release Notesに記載されてもいないので不明

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

ドラッグ&ドロップ機能の未来?

Posted on 3月 17, 2022 by Takaaki Naganoya

目下、Tim Cook体制のもと「セキュリティ至上主義」が掲げられ、機能の有用性とセキュリティ(機能を制限、削除する)をてんびんにかけると、後者が重視されるようになっています。

そんな中、ドラッグ&ドロップの機能についてはいろいろ制約を受けたり、一部で使えなくなっていくのではないかという「懸念」を持っています。

実際、macOS 10.12以降、AppleScriptドロップレット(ファイルのドラッグ&ドロップを受信して動作するAppleScriptの実行プログラム)がOS側のセキュリティ機能による動作の影響(xattr)を受け、まっとうな処理方法では期待されるファイル処理ができなくなっています(回避策はあります)。

このため、macOS上でもFinder上でiOS並みのファイル操作、ドラッグ&ドロップでファイル/フォルダを移動させる程度の処理しか許可されず、アプリケーション側にまとめてファイルを渡すような処理ができなくなる「かも」しれません。

このドラッグ&ドロップによるファイルの一括指示の機能を維持するために、「display drop dialog Script Library」というライブラリをedama2氏との協力のもと(自分は要望を出したぐらいで作ったのはedama2氏)、配布しています。

アラートダイアログで指定のファイルタイプの書類のFinderからのドラッグ&ドロップを受け付けます。わざわざDropletを作らなくてもファイルのドラッグ&ドロップを受け付けるためには、こうしたインタフェースがないとまずいんじゃないか? という予測のもとに企画したものです。

目下、macOS 12.3でFinderに対してファイルのAppleScriptからオープン操作を行わせると、「creatorのアプリケーションは起動するもののファイルがオープンされない」という現象が発生しており(エラーダイアログが出る例があったり、出ない例があったり)、Apple社内でも整合性が取れていない状況のようです。

Appleとしては個別のテクノロジーについて発言したり、WWDCでも技術ではなくマーケティング的なセッションが増えて「見るべきものがない」状況になっていますが、こうした状況は好ましいものとは言えません。

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

Cocoa Scripting Course #4 近日刊行

Posted on 3月 16, 2022 by Takaaki Naganoya

Cocoa Scripting Courseの第4巻、「System Hardware & Software Information」を近日刊行いたします。

→ 発売しました!

第4巻では、ハードウェアやOSのソフトウェア情報、アプリケーション・バンドルからの情報取得を幅広く紹介しています。現時点で480ページぐらいです。

思えば、3巻目を刊行したあとに「M1 MacとmacOS 11の組み合わせだとしぬほどCocoa Scriptingが遅くなる」ことに気づいてAppleにレポート。この問題を片付けるまで続刊の刊行は見合わせざるを得ない状況でした。

「Appleの最新鋭マシンが10年前のMacBook Air 11インチより10倍遅いってマジか?」

みたいなレポートを行い、この煽りまくる(&詳細なデータとAppleScriptのプログラムを添えた)バグレポートが効いたとも言われています(本当のところは分かりませんけれども)。少なくとも、レポートしなかったら直っていなかったことでしょう。

無事、macOS 12でM1およびIntel CPU上でCocoa Scriptingを行なったときのスピード低下問題が解決。

この問題が解決したので、ようやく続刊の刊行に復帰した次第です。以前から地道に続け、飽きたら別の本に着手し、並列で4〜5冊進行しておりました。

Cocoa Scripting Courseはそんなに部数が出る本ではないので、ついつい後回しになりがちです。

Posted in Books news | Leave a comment

[新刊]つたわる資料のつくりかた

Posted on 3月 15, 2022 by Takaaki Naganoya

あらたに電子書籍を刊行しました。「つたわる資料のつくりかた」。資料を作るすべての人に向けた、資料作成の基礎を解説する本です。Amazon Kindleで配信中。

Posted in Books news | Leave a comment

クリップボードの画像を指定色でモノクロ化してクリップボードへ v3

Posted on 3月 13, 2022 by Takaaki Naganoya

クリップボードに入れた画像を、グレースケール化したあとに指定の色のベタ塗り画像とフィルタで合成し、単色の色付き画像に変換するAppleScriptです。

資料に掲載する画像の情報量を減らすために、単色画像に変換したいと考えました。Photoshopだと2つのレイヤーの重ね合わせで指定して処理するような内容です。ただ、もうPhotoshopにできるぐらいのことの大部分は、AppleScriptだけで単独でできてしまうのが2022年的な状況です。

アプリケーションを使わずに処理するためには、CIFilterを用いて画像処理して、単色画像にすることになります。

CIFilterにもいろいろな画像フィルタ機能が用意されているわけで、ここから「どのフィルタを使うか」選ぶことになります。

# フィルタが200種類ぐらいあるんですけど!!

このような場合のために、FileMaker Proで作った「FileMaker Pro PowerPack」だとひととおりのCIFilterをサンプルデータで処理できるようにしておきました。

FileMaker Proのデータベース上にサンプルデータをコピー&ペーストしておけば、DB上でフィルタ処理してどのような処理をしてくれるかがわかります。

いやーー、作っておいてよかったー。「なんでこんなにフィルタ処理ばっかりあるんだよ!」的な話がありましたが、こうして実際に役立つわけで。フィルタの名称、編集できるテストデータ、処理結果が表示されるところまで……「動かせる資料」的なものに仕上がっています>FileMaker Pro PowerPack

ひととおりAppleScriptを作ってみて、いろいろ調整してみたところ……調整し切れなかったので、edama2さんに相談して(送りつけて)こんな感じに仕上がりました。

これでなんとか動くはずなのに、なぜこうなるのか。。。CIFilterを実際に日常的に使うツールで使ったのは実はこれが最初だったので、意外な挙動に割と困りました。


▲画面上の指定範囲のスクリーンショットを撮ってクリップボードへ


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


▲クリップボードの内容をペーストすると、単色化された画像が出力される

AppleScript名:クリップボードの画像を指定色でモノクロ化してクリップボードへ v3.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/03/11
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
–  v2 Takaaki Naganoya : マスクが1/4の大きさになったり2倍になったりしていた
–  v3 edama2:上記の問題に対処。クリーンナップ
—
use AppleScript version "2.7"
use framework "AppKit"
use framework "CoreImage"
use framework "Foundation"
use scripting additions

on run
  my main()
end run

on main()
  –クリップボード内のデータをNSImageとして取得
  
set sourceImg to my getClipboardASImage()
  
  
# 色指定
  
set aColor to my makeNSColorFromRGBA255val(252, 2, 128, 255)
  
  
  
# 同じ大きさの塗りつぶし画像を作成
  
tell current application’s NSImage’s alloc()
    tell initWithSize_(sourceImg’s |size|())
      lockFocus()
      
aColor’s |set|()
      
set aRect to current application’s NSMakeRect(0, 0, its |size|()’s width, its |size|()’s height)
      
current application’s NSBezierPath’s fillRect:aRect
      
unlockFocus()
      
set fillImg to it
    end tell
  end tell
  
  
# NSImage –> CIimage
  
set sourceImage to my convNSImageToCIimage(sourceImg)
  
set fillImage to my convNSImageToCIimage(fillImg)
  
  
set newImage to my filterImage2(fillImage, sourceImage)
  
  
my restoreClipboard({newImage})
end main

on filterImage2(fillImage, sourceImage)
  
  
set redValue to 0.295719844358
  
set greenValue to 0.295719844358
  
set blueValue to 0.295719844358
  
set alphaVlaue to 1.0
  
set aCIColor to current application’s CIColor’s alloc()’s initWithRed:redValue green:greenValue blue:blueValue alpha:alphaVlaue
  
  
tell current application’s CIFilter
    — CIFilter(モノクロ化)
    
tell filterWithName_("CIColorMonochrome")
      setDefaults()
      
setValue_forKey_(sourceImage, "inputImage")
      
setValue_forKey_(aCIColor, "inputColor")
      
set filteredImage to valueForKey_("outputImage")
    end tell
    
    
— CIFilter(モノクロ化)
    
tell filterWithName_("CIAdditionCompositing")
      setDefaults()
      
setValue_forKey_(fillImage, "inputImage")
      
setValue_forKey_(filteredImage, "inputBackgroundImage")
      
set theCIImage to valueForKey_(current application’s kCIOutputImageKey)
    end tell
  end tell
  
  
# CIImage –> NSImage
  
set imageRep to current application’s NSCIImageRep’s alloc()’s initWithCIImage:theCIImage
  
set rNSImage to current application’s NSImage’s alloc()’s initWithSize:(imageRep’s |size|())
  
rNSImage’s addRepresentation:imageRep
  
  
return rNSImage
end filterImage2

# NSImage –> CIimage
on convNSImageToCIimage(aNSImage)
  set tiffDat to aNSImage’s TIFFRepresentation()
  
set aRep to current application’s NSBitmapImageRep’s imageRepWithData:tiffDat
  
set newImg to current application’s CIImage’s alloc()’s initWithBitmapImageRep:aRep
  
return newImg
end convNSImageToCIimage

— クリップボードの内容をNSImageとして取り出して返す
on getClipboardASImage()
  set thePasteboard to current application’s NSPasteboard’s generalPasteboard()
  
set theAttributedStringNSArray to thePasteboard’s readObjectsForClasses:({current application’s NSImage}) options:(missing value)
  
set theNSImage to theAttributedStringNSArray’s objectAtIndex:0
  
return theNSImage
end getClipboardASImage

on restoreClipboard(theArray as list)
  set thePasteboard to current application’s NSPasteboard’s generalPasteboard()
  
thePasteboard’s clearContents()
  
thePasteboard’s writeObjects:theArray
end restoreClipboard

on makeNSColorFromRGBA255val(redValue as integer, greenValue as integer, blueValue as integer, alphaValue as integer)
  set aRedCocoa to (redValue / 255) as real
  
set aGreenCocoa to (greenValue / 255) as real
  
set aBlueCocoa to (blueValue / 255) as real
  
set aAlphaCocoa to (alphaValue / 255) as real
  
set aColor to current application’s NSColor’s colorWithCalibratedRed:aRedCocoa green:aGreenCocoa blue:aBlueCocoa alpha:aAlphaCocoa
  
return aColor
end makeNSColorFromRGBA255val

★Click Here to Open This Script 

Posted in filter Image | Tagged 12.0savvy CIColor CIImage NSBezierPath NSCIImageRep NSColor NSImage NSPasteboard | Leave a comment

指定のPDFの本文テキストの文字数をカウント

Posted on 3月 9, 2022 by Takaaki Naganoya

指定のPDFの本文テキストを取り出し、文字数をカウントするAppleScriptです。


▲「AppleScriptによるWebブラウザ自動操縦ガイド」の文字数をカウントしようとした

300ページを超える、わりと大きな本のPDFデータから文字を取り出したので、それなりの文字数になりました。つまり、Cocoaの有効活用を考えないとデータサイズ的につらそうなデータ量になることが予想されました。

当初、(文字処理については)Cocoaの機能をあまり活用しないv2を作ったものの、処理にM1 Mac miniで30秒ほどかかりました。すべてNSStringのまま(AppleScriptのstringに型変換せずに)処理してみたら、案の定、大幅に処理が高速化され6秒あまりで完了。

ただし、両者でカウントした文字数が1万文字ぐらい違っていたので、(PDFから取得した文字の)Unicode文字のNormalize方式を変更したところ、両者で同じ結果になりました。また、処理速度に改変前から大幅な変化はありませんでした。

文字数を数えるという処理だとさすがにデータ数が膨大になるため、NSStringで処理したほうがメリットが大きいようです。

# あれ? 5文字ぐらい違う、、、、絵文字の部分か?

AppleScript名:指定のPDFの本文テキストの文字数を数える v2
use AppleScript version "2.8" –macOS 12 or later
use framework "Foundation"
use framework "PDFKit" –Comment Out under macOS 11
–use framework "Quartz"–Uncomment under macOS 11
use scripting additions

script spd
  property cRes : ""
  
property cList : {}
end script

set (cRes of spd) to ""
set (cList of spd) to {}

set (cRes of spd) to getTextFromPDF(POSIX path of (choose file of type {"pdf"})) of me
set (cList of spd) to current application’s NSArray’s arrayWithArray:(characters of (cRes of spd))
set cLen to (cList of spd)’s |count|()
return cLen
–> 256137 (24.763sec)

on getTextFromPDF(posixPath)
  set theURL to current application’s |NSURL|’s fileURLWithPath:posixPath
  
set thePDF to current application’s PDFDocument’s alloc()’s initWithURL:theURL
  
return (thePDF’s |string|()’s precomposedStringWithCompatibilityMapping()) as text
end getTextFromPDF

★Click Here to Open This Script 

AppleScript名:指定のPDFの本文テキストの文字数を数える v3
use AppleScript version "2.8" –macOS 12 or later
use framework "Foundation"
use framework "PDFKit" –Comment Out under macOS 11
–use framework "Quartz"–Uncomment under macOS 11
use scripting additions

script spd
  property cRes : ""
  
property cList : {}
end script

set (cRes of spd) to ""
set (cList of spd) to {}

set (cRes of spd) to getTextFromPDF(POSIX path of (choose file of type {"pdf"})) of me
set cLen to (cRes of spd)’s |length|
return cLen as anything
–> 256142 (6.28 sec)

on getTextFromPDF(posixPath)
  set theURL to current application’s |NSURL|’s fileURLWithPath:posixPath
  
set thePDF to current application’s PDFDocument’s alloc()’s initWithURL:theURL
  
return (thePDF’s |string|()’s precomposedStringWithCompatibilityMapping())
end getTextFromPDF

★Click Here to Open This Script 

わずかとはいえ、違いが出ていることは確かなので、1つのPDFに対して2つの処理方法でテキストを取り出して、それを配列に入れて集合演算して差分をとってみました。M1でも処理に1分少々かかりました。こういう処理は、M1 MaxでもM1 Ultraでも所要時間は変わらないことでしょう(逆にM1の方が処理時間が短い可能性まである)。

どうやら改行コードの解釈で文字数カウント結果に違いが出たようです。

AppleScript名:テキストの抽出方法による文字数の相違チェック.scptd
use AppleScript version "2.8" –macOS 12 or later
use framework "Foundation"
use framework "PDFKit" –Comment Out under macOS 11
–use framework "Quartz"–Uncomment under macOS 11
use scripting additions

script spd
  property cRes : ""
  
property cList : {}
end script

set (cRes of spd) to ""
set (cList of spd) to {}

set docPath to POSIX path of (choose file of type {"pdf"})

set (cRes of spd) to getTextFromPDF1(docPath) of me
set (cList of spd) to characters of (cRes of spd)
set anArray to current application’s NSArray’s arrayWithArray:(cList of spd)

set bStr to getTextFromPDF2(docPath) of me
set bArray to current application’s NSMutableArray’s new()
set bLen to (bStr’s |length|) as anything
repeat with i from 0 to (bLen – 1)
  set tmpStr to (bStr’s substringWithRange:(current application’s NSMakeRange(i, 1)))
  (
bArray’s addObject:(tmpStr))
end repeat

set aRes to diffLists(anArray, bArray) of me
set bRes to diffLists(bArray, anArray) of me
return {aRes, bRes}

on getTextFromPDF1(posixPath)
  set theURL to current application’s |NSURL|’s fileURLWithPath:posixPath
  
set thePDF to current application’s PDFDocument’s alloc()’s initWithURL:theURL
  
return (thePDF’s |string|()’s precomposedStringWithCompatibilityMapping()) as text
end getTextFromPDF1

on getTextFromPDF2(posixPath)
  set theURL to current application’s |NSURL|’s fileURLWithPath:posixPath
  
set thePDF to current application’s PDFDocument’s alloc()’s initWithURL:theURL
  
return (thePDF’s |string|()’s precomposedStringWithCompatibilityMapping())
end getTextFromPDF2

–1D List同士のdiffを計算する
on diffLists(aList, bList)
  set aSet to current application’s NSMutableSet’s setWithArray:aList
  
set bSet to current application’s NSMutableSet’s setWithArray:bList
  
set aRes to calcSetDifference(aSet, bSet) of me
  
return aRes
end diffLists

–2つのNSMutableSetの補集合を求める
on calcSetDifference(aSet, bSet)
  aSet’s minusSet:bSet –補集合
  
set aRes to aSet’s allObjects() as list
  
return aRes
end calcSetDifference

★Click Here to Open This Script 

Posted in PDF Text | Tagged 12.0savvy NSURL PDFDocument | Leave a comment

macOS 12のスクリプトエディタで、Context Menu機能にバグ

Posted on 3月 4, 2022 by Takaaki Naganoya

「AppleScriptによるWebブラウザ自動操縦ガイド」に添付している「Piyomaru Context Menu Assistant」。

スクリプトエディタのコンテクストメニューからAppleScriptを呼び出せるスクリプトエディタの機能を利用して、macOS標準装備の貧相で使い物にならないScriptを全部捨てて、そのかわりに強力なものをインストールするものです。


▲macOS標準でインストールされている、Script Assistant。古い、使えない、役に立たないの3拍子


▲Piyomaru Softwareが書籍のオマケでご提供しているPiyomaru Script Assistant(macOS 10.14.6)


▲macOS 12.3 beta 5上で表示したPiyomaru Script Assistant。メニュー項目(≒ファイル名)が2重に表示されている(macOS 12.3 beta5)

このScript Assistantが、macOS 12.3 beta 5上でメニュー項目が重複して表示されてしまうという現象に遭遇しています。

これは、macOS側のAppleが作ったバグであります。

Posted in Bug | Tagged 12.0savvy | 1 Comment

書籍フォルダの階層をさかのぼって、ツメに掲載する最大チャプターを推測 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

新刊発売:AppleScriptによるWebブラウザ自動操縦ガイド

Posted on 3月 2, 2022 by Takaaki Naganoya

macOS用の7つのWebブラウザ(Safari、Chrome、Chromium、Microsoft Edge、Vivaldi、Brave Browser、Opera)を操作するAppleScript本です。PDF形式306ページ。

→ 販売ページ

1章 めんどうな操作を自動化しよう!

人間の手で操作して情報を集めたり、データ入力するのは非効率。スクリプトから操作して自動操作

2章 スクリプトエディタの使い方

AppleScript専用のスクリプトエディタの使い方など、基礎的な内容をご紹介。

3章 WebブラウザをAppleScriptから動かそう

macOS用Webブラウザの大半はAppleScriptから操作可能。AppleScript対応は必須の機能!

4章 Webブラウザの情報を取り出そう

Webブラウザ自体が大量の情報を管理しています。まずは、ブラウザの情報を調べてみましょう。

5章 指定URLをオープンしよう

誰にでも確実に行える操作です。かならず経験しておきましょう。URLをオープンした後が大事です。

6章 コンテンツをキャプチャして保存しよう

表示内容を変化しないデータや、再利用可能なデータとして残しておくことは、重要な処理です。

7章 Webコンテンツにアクセスしよう

HTML内の操作対象にアクセスするための、さまざまなアプローチをご紹介

8章 Webコンテンツを画面部品として操作しよう

画面上の部品と同様にWebコンテンツにアクセスして強引に操作する「奥の手」GUI Scripting

9章 ログイン、ログアウトしてみよう

ユーザー登録が必要なWebサイトの処理を行うために必須の作業です。意外とクリアしにくい箇所

10章 データをダウンロードして処理しよう

直接ダウンロードできないファイルのダウンロード完了を検出して、ファイル処理しよう! ダウンロード後にファイル整理したりファイル名を変更したり

11章 仮想ディスプレイでユーザーの誤操作を防ごう

ユーザーからの操作をガードするために、仮想ディスプレイを用意してWebブラウザを表示! 画面上から強引にScriptで動かすと、ユーザーの誤操作が一番の大敵

12章 さまざまな実行環境を知ろう

AppleScriptにはいろいろな実行環境があって、環境ごとにできる/できないことがあります。時間と気持ちに余裕のある時にでも読んでおくとよいでしょう。

13章 実例:Quoraの統計データを取得しよう

実際に、Quoraのアクセス情報ページにアクセスし、自分の投稿情報を取得してみよう!

14章 さまざまな技術資料。興味があったら読んでね

アプリケーション・オブジェクトの指定方法/AppleScript用語辞書の確認方法/Webブラウザの基礎的なScripting/Google Chrome系のWebブラウザのsdef/AppleScriptの歴史/AppleScriptのエラーコード表/AppleScript予約語一覧/各Webブラウザの用語辞書の変更履歴

Posted in Books news | Tagged Brave Browser Chromium Google Chrome Opera Safari Vivaldi | Leave a comment

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

Post navigation

  • Older posts
  • Newer posts

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

Google Search

Popular posts

  • Numbersで選択範囲のセルの前後の空白を削除
  • macOS 26, Tahoe
  • macOS 15でも変化したText to Speech環境
  • KagiのWebブラウザ、Orion
  • Script Debuggerの開発と販売が2025年に終了
  • 【続報】macOS 15.5で特定ファイル名パターンのfileをaliasにcastすると100%クラッシュするバグ
  • macOS 15 リモートApple Eventsにバグ?
  • NSObjectのクラス名を取得 v2.1
  • 2024年に書いた価値あるAppleScript
  • 有害ではなくなっていたSpaces
  • macOS 15:スクリプトエディタのAppleScript用語辞書を確認できない
  • Xcode上のAppleScriptObjCのプログラムから、Xcodeのログ欄へのメッセージ出力を実行
  • (確認中)AppleScript Dropletのバグっぽい動作が解消?
  • AVSpeechSynthesizerで読み上げテスト
  • AppleScript Dropletのバグっぽい動作が「復活」(macOS 15.5β)
  • 指定フォルダ以下の画像のMD5チェックサムを求めて、重複しているものをピックアップ
  • macOS 26, 15.5でShortcuts.app「AppleScriptを実行」アクションのバグが修正される
  • Numbersで選択中の2列のセルを比較して並べ直して書き戻す v2
  • Apple、macOS標準搭載アプリ「写真」のバージョン表記を間違える
  • Script DebuggerがmacOS 15.x上で起動せず→起動

Tags

10.11savvy (1101) 10.12savvy (1242) 10.13savvy (1391) 10.14savvy (587) 10.15savvy (438) 11.0savvy (283) 12.0savvy (212) 13.0savvy (204) 14.0savvy (159) 15.0savvy (156) CotEditor (66) Finder (52) Keynote (119) NSAlert (61) NSArray (51) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (53) NSDictionary (28) NSFileManager (23) NSFont (21) NSImage (41) NSJSONSerialization (21) NSMutableArray (63) NSMutableDictionary (22) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (119) NSURL (98) NSURLRequest (23) NSUTF8StringEncoding (30) NSView (33) NSWorkspace (20) Numbers (76) Pages (56) Pixelmator Pro (20) 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
  • Newt On Project
  • Noification
  • Notarization
  • Number
  • Object control
  • OCR
  • OSA
  • parallel processing
  • PDF
  • Peripheral
  • process
  • PRODUCTS
  • QR Code
  • Raw AppleEvent Code
  • Record
  • rectangle
  • recursive call
  • regexp
  • Release
  • Remote Control
  • Require Control-Command-R to run
  • REST API
  • Review
  • RTF
  • Sandbox
  • Screen Saver
  • Script Libraries
  • Scripting Additions
  • 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年10月
  • 2025年9月
  • 2025年8月
  • 2025年7月
  • 2025年6月
  • 2025年5月
  • 2025年4月
  • 2025年3月
  • 2025年2月
  • 2025年1月
  • 2024年12月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年6月
  • 2024年5月
  • 2024年4月
  • 2024年3月
  • 2024年2月
  • 2024年1月
  • 2023年12月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年6月
  • 2023年5月
  • 2023年4月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年12月
  • 2019年11月
  • 2019年10月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年5月
  • 2018年4月
  • 2018年3月
  • 2018年2月

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

メタ情報

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

Forum Posts

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

メタ情報

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