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

タグ: 14.0savvy

書式つきテキストを組み立てて、画像を追加

Posted on 11月 25, 2024 by Takaaki Naganoya

書式つきテキスト(NSAttributedString)を作成し、その先頭にコンピュータアイコン画像を追加してダイアログ表示するAppleScriptです。

–> Download Script Archive with Libraries

AppleScript名:書式つきテキストを組み立てて、画像を追加
— Created 2017-09-25 by Takaaki Naganoya
— Modified 2017-09-27 by Shane Stanley
— Modified 2024-11-25 by Takaaki Naganoya
— 2017-2024 Piyomaru Software
use AppleScript
use scripting additions
use framework "Foundation"
use framework "AppKit"
use tv : script "tvLib"
use hwName : script "hardwareNameLib"

property NSFont : a reference to current application’s NSFont
property NSColor : a reference to current application’s NSColor
property NSString : a reference to current application’s NSString
property NSImage : a reference to current application’s NSImage
property NSTextAttachment : a reference to current application’s NSTextAttachment
property NSAttributedString : a reference to current application’s NSAttributedString
property NSMutableDictionary : a reference to current application’s NSMutableDictionary
property NSFontAttributeName : a reference to current application’s NSFontAttributeName
property NSKernAttributeName : a reference to current application’s NSKernAttributeName
property NSImageNameComputer : a reference to current application’s NSImageNameComputer
property NSMutableParagraphStyle : a reference to current application’s NSMutableParagraphStyle
property NSLigatureAttributeName : a reference to current application’s NSLigatureAttributeName
property NSMutableAttributedString : a reference to current application’s NSMutableAttributedString
property NSUnderlineStyleAttributeName : a reference to current application’s NSUnderlineStyleAttributeName
property NSParagraphStyleAttributeName : a reference to current application’s NSParagraphStyleAttributeName
property NSForegroundColorAttributeName : a reference to current application’s NSForegroundColorAttributeName

–Attributed Stringを作成
set aFontSize to 48
set aString to getSystemProfileInAGenre("SPHardwareDataType", "machine_name") of hwName
set anAssrStr to makeRTFfromParameters(aString, "HelveticaNeue-Light", aFontSize, -2, (aFontSize * 1.5)) of me

–添付画像を作成
set anAttach to NSTextAttachment’s alloc()’s init()
set anImage to NSImage’s imageNamed:(NSImageNameComputer)
anAttach’s setImage:anImage

–添付画像をAttributed Stringに添付
set iconString to NSAttributedString’s attributedStringWithAttachment:anAttach
anAssrStr’s insertAttributedString:iconString atIndex:0 –冒頭に添付

–ライブラリを用いてダイアログ表示
dispAttrStr(aString, "Computer Icon", anAssrStr, 600, 200) of tv

–書式つきテキストを組み立てる
on makeRTFfromParameters(aStr as string, fontName as string, aFontSize as real, aKerning as real, aLineSpacing as real)
  –Font
  
set aVal1 to NSFont’s fontWithName:fontName |size|:aFontSize
  
set aKey1 to (NSFontAttributeName)
  
  
–Color
  
set aVal2 to NSColor’s blackColor()
  
set aKey2 to (NSForegroundColorAttributeName)
  
  
–Kerning
  
set aVal3 to aKerning
  
set akey3 to (NSKernAttributeName)
  
  
–Underline
  
set aVal4 to 0
  
set akey4 to (NSUnderlineStyleAttributeName)
  
  
–Ligature
  
set aVal5 to 2 –all ligature ON
  
set akey5 to (NSLigatureAttributeName)
  
  
–縦書き指定–Japanese tategaki setting (Up to down, right to left direction drawing)
  
set aVal6 to false
  
set aKey6 to (current application’s NSVerticalGlyphFormAttributeName)
  
  
–Paragraph space
  
set aParagraphStyle to NSMutableParagraphStyle’s alloc()’s init()
  
aParagraphStyle’s setMinimumLineHeight:(aLineSpacing)
  
aParagraphStyle’s setMaximumLineHeight:(aLineSpacing)
  
set akey7 to (NSParagraphStyleAttributeName)
  
  
set keyList to {aKey1, aKey2, akey3, akey4, akey5, aKey6, akey7}
  
set valList to {aVal1, aVal2, aVal3, aVal4, aVal5, aVal6, aParagraphStyle}
  
set attrsDictionary to NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList
  
  
set attrStr to NSMutableAttributedString’s alloc()’s initWithString:aStr attributes:attrsDictionary
  
return attrStr
end makeRTFfromParameters

★Click Here to Open This Script 

Posted in dialog RTF | Tagged 13.0savvy 14.0savvy 15.0savvy NSAttributedString NSTextAttachment | Leave a comment

KagiのWebブラウザ、Orion

Posted on 11月 23, 2024 by Takaaki Naganoya

たまにMac用のWebブラウザが新登場しているのですが、ほとんどがGoogle Chromiumの互換といいますか、Chromiumのぱちも……といいますか、ほぼそのまま利用して作られていたりして、そのおかげで割としっかりとAppleScript対応機能が実装されたまま多数のWebブラウザがリリースされるというメリットがありました。

そんな中、たまたま見つけた「Orion」。Kagiが作ったWebブラウザとのことです。

AppleScriptから見ると、見たこともないような挙動をするWebブラウザです。

用語辞書の傾向はChrome系というよりも、Safariからとんがったコマンドを削除したようなたたずまい。

そして、必要な機能がついていなくて、割と「何これ?」と首をひねってしまうような出来です。

SafariもGoogle Chromeも、現在のタブを指し示すactive tabとかcurrent tabといった予約語でアクセスできるのですが、それができません。一応、Windowのプロパティとしてcurrent tabがあるのですが、このtabからIDとかIndexが取得できません。

do JavaScriptコマンドがあるので、ちょっとOrion固有の制限が加わりつつもJavaScriptコマンドを実行してWebのソースコードやテキストを取得できたりはしつつ、Webブラウザ上で選択中の要素を取得できなかったりします。

そして、肝心のdo JavaScriptコマンドでtabを指定する必要があるものの、current tabが何であるかを特定できず……仕方ないので、tabから取得できるURLをもとにどのtabがcurrent tabであるかを探し回ってなんとか。

windowの新規作成は、documentを作成することで行うことに。

人間らしく、というレベルはクリアできていないような気がします。久しぶりに、挙動がここまで不完全というか不自然なWebブラウザを見かけました。

AppleScript名:Orionのアプリのプロパティを取得.scpt
tell application "Orion"
  properties
  
–> {frontmost:false, class:application, name:"Orion", version:"0.99"}
end tell

★Click Here to Open This Script 

AppleScript名:OrionでWindowのtitleを取得.scpt
–同じURLを持つTabが複数あった場合には処理が破綻する
tell application "Orion"
  tell window 1
    set aURL to URL of current tab
    
set tList to URL of every tab
    
set tInd to retIndexNumInArray(tList, aURL) of me
    
if tInd = 0 then return
    
    
tell tab tInd –current tabのindexを求める方法がないのに、current tabを指定できないし、具体的にtab idを指定しないといけない
      set aRes to do JavaScript "document.querySelector(’title’).textContent;"
    end tell
  end tell
end tell

–1Dimensionリスト中のシーケンシャルサーチ
on retIndexNumInArray(aList, aTarget)
  set aCount to 1
  
set hitF to false
  
  
repeat with i in aList
    set j to contents of i
    
if aTarget = j then return aCount
    
    
set aCount to aCount + 1
  end repeat
  
  
if hitF = false then return 0
end retIndexNumInArray

★Click Here to Open This Script 

AppleScript名:Orionで新規URLをオープン(新規Tab).scpt
tell application "Orion"
  open location "https://www.apple.com/jp" –新規Tabでオープン
end tell

★Click Here to Open This Script 

AppleScript名:Orionの最前面のWindowのcurrent tabで新規URLをオープン.scpt
tell application "Orion"
  set URL of current tab of window 1 to "https://www.apple.com/jp"
end tell

★Click Here to Open This Script 

AppleScript名:Orionでcurrent tabに対してJavaScript実行してソースを取得.scpt
–同じURLを持つTabが複数あった場合には処理が破綻する
tell application "Orion"
  tell window 1
    set aURL to URL of current tab
    
set tList to URL of every tab
    
set tInd to retIndexNumInArray(tList, aURL) of me
    
if tInd = 0 then return
    
    
tell tab tInd –current tabのindexを求める方法がないのに、current tabを指定できないし、具体的にtab idを指定しないといけない
      set aRes to do JavaScript "document.getElementsByTagName(’html’)[0].innerHTML"
    end tell
  end tell
end tell

–1Dimensionリスト中のシーケンシャルサーチ
on retIndexNumInArray(aList, aTarget)
  set aCount to 1
  
set hitF to false
  
  
repeat with i in aList
    set j to contents of i
    
if aTarget = j then return aCount
    
    
set aCount to aCount + 1
  end repeat
  
  
if hitF = false then return 0
end retIndexNumInArray

★Click Here to Open This Script 

AppleScript名:Orion、WindowのCloseができるが、makeできない.scpt
tell application "Orion"
  close every window
end tell

★Click Here to Open This Script 

AppleScript名:Orionで新規document作成.scpt
tell application "Orion"
  make new document
end tell

★Click Here to Open This Script 

AppleScript名:新規tabの作成.scpt
tell application "Orion"
  tell window 1
    make new tab with properties {URL:"http://www.apple.com/jp"}
  end tell
end tell

★Click Here to Open This Script 

Posted in Object control | Tagged 13.0savvy 14.0savvy 15.0savvy Orion | Leave a comment

余白トリミング実験 v3

Posted on 11月 23, 2024 by Takaaki Naganoya

背景が透過しているPNG画像で、余計な余白部分を自動でトリミングするAppleScriptの試作品です。実際に画像のトリミングを行います。1024×1024ぐらいまでの大きさのPNG画像が想定しているターゲットで、4Kとか8Kぐらいの画像は想定していません。

既存のCやObjective-Cなどの言語で書かれたトリミングのプログラムは、1ドットずつスキャンしていく方式だったので、そのままの処理をインタプリタ方式のAppleScriptで行うと、遅くて話になりません。

そこで、ブロックごとに分割して、ブロック単位で描画部分がないか(同サイズの透明イメージと比較して同じかどうか)チェックするという方式を採用しました。これは、画像がすべて空白かどうかをチェックする処理の原理を応用したものです。


▲テストに利用したPNG画像(196 × 309 ピクセル)

前バージョン(v2)を実際の用途に利用してみたら、トンでもなく使い物にならなかったので、プログラムのおかしなところを見直して、2段階で処理を行うことでさらに精度を上げてみたのが、このv3です。

画像全体を16×16のブロックに分割して、個別に透明なエリアか描画されているエリアかを判定します(パス1)。

そのままだと処理がラフすぎるので、外周部のブロックをさらに16分割し、外周部だけ透明ブロックかどうかの判定を行います(パス2)。

このテスト画像に対しては、それなりの結果が出ています。前バージョンと比べると大幅に性能向上してます。実戦投入してみるとまた別の感想が出てくるかもしれませんが……。


▲実戦投入。SF Symbolsをコピーした内容を指定色で画像化してクリップボードに入れるAppleScriptで使用してみたら、けっこういい感じに切り抜いてくれました

プログラムもまだ試作品段階なので、無駄な処理が多そうです。パス1とパス2で共通部分が多いので、見直すとメイン部分の長さが半分ぐらいになりそうですが、試作品段階なのであんまり短くしすぎると内容を理解しにくくなりそうで。

AppleScript名:余白トリミング実験 v3.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/11/21
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

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

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 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 NSBezierPath : a reference to current application’s NSBezierPath
property NSPNGFileType : a reference to current application’s NSPNGFileType
property NSMutableArray : a reference to current application’s NSMutableArray
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep

–画像分割ブロックサイズ
property imgDivXStep : 16
property imgDivYStep : 16

set aPOSIXpath to POSIX path of (choose file with prompt "PNG画像を選択")

–時間計測用
set a1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()

–画像自動切り抜き
set cImage to autoTrimImageFromPath(aPOSIXpath) of me

–時間計測用
set b1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
set c1Dat to b1Dat – a1Dat
log c1Dat

–ファイル保存
set outPath to POSIX path of (choose file name with prompt "PNG画像の保存ファイル名を指定してください(拡張子入力必須)")
set sRes to saveImageRepAtPathAsPNG(cImage, outPath) of me

–POSIX pathで示したPNG画像(多分)の外周部の余白を自動トリミング
on autoTrimImageFromPath(aPOSIXpath)
  set aURL to |NSURL|’s fileURLWithPath:aPOSIXpath
  
set aImage to NSImage’s alloc()’s initWithContentsOfURL:aURL
  
return autoTrimImage(aImage) of me –return NSImage
end autoTrimImageFromPath

–NSImageの外周部の余白を自動トリミング
on autoTrimImage(aImage)
  script spd
    property outList : {} –Pass 1用
    
property pass2Res : {} –Pass 2用
  end script
  
  
–PASS 1 16 x 16 Whole Area Scan
  
  
set sRes to aImage’s |size|()
  
–> example: {width:196.0, height:309.0}
  
  
set aHeight to height of sRes
  
set aWidth to width of sRes
  
  
set xBlockSize to (aWidth div imgDivXStep)
  
set yBlockSize to (aHeight div imgDivYStep)
  
  
  
–transparent block sample for PASS 1
  
set blankImg1 to makeNSImageWithFilledWithColor(xBlockSize, yBlockSize, current application’s NSColor’s clearColor()) of me
  
set blankBit1 to blankImg1’s TIFFRepresentation()
  
  
  
  
set (outList of spd) to {}
  
  
repeat with yy from 0 to (aHeight – yBlockSize) by yBlockSize
    set oneLine to ""
    
    
repeat with xx from 0 to (aWidth – xBlockSize) by xBlockSize
      –crop a part of image and check transparent
      
set tmpImg to (my cropNSImageBy:{xx, yy, xBlockSize, yBlockSize} fromImage:aImage)
      
set tmpBit to tmpImg’s TIFFRepresentation()
      
set chkTrans to (blankBit1’s isEqualToData:tmpBit) as boolean
      
      
      
if chkTrans = false then –Not transparent block
        set the end of (outList of spd) to {xPos:xx, yPos:yy}
      end if
      
    end repeat
  end repeat
  
  
  
  
–最大値、最小値を取得
  
set nArray to (NSMutableArray’s arrayWithArray:(outList of spd))
  
  
set xMin to calcMin("xPos", nArray) of me
  
set xMax to calcMax("xPos", nArray) of me
  
  
set yMin to calcMin("yPos", nArray) of me
  
set yMax to calcMax("yPos", nArray) of me
  
  
  
  
–PASS 2: Edge Blocks 64 x 64 scan Most Edge blocks only
  
  
–transparent block sample for PASS 2 (1/4 size)
  
set blankImg2 to makeNSImageWithFilledWithColor(xBlockSize div 4, yBlockSize div 4, current application’s NSColor’s clearColor()) of me
  
set blankBit2 to blankImg2’s TIFFRepresentation()
  
  
  
set aArray to current application’s NSArray’s arrayWithArray:(outList of spd)
  
  
set westList to filterRecListByLabel1(aArray, "xPos == %@", xMin) of me as list
  
set eastList to filterRecListByLabel1(aArray, "xPos == %@", xMax) of me as list
  
set northLIst to filterRecListByLabel1(aArray, "yPos == %@", yMax) of me as list
  
set southLIst to filterRecListByLabel1(aArray, "yPos == %@", yMin) of me as list
  
  
set pass2List to westList & eastList & northLIst & southLIst
  
  
set (pass2Res of spd) to {}
  
  
repeat with i in pass2List
    set origPX to xPos of i
    
set origPY to yPos of i
    
    
repeat with y from 0 to 3
      repeat with x from 0 to 3
        
        
set tmpPX to origPX + (xBlockSize div 4) * x
        
set tmpPY to origPY + (yBlockSize div 4) * y
        
        
set tmpImg to (my cropNSImageBy:{tmpPX, tmpPY, xBlockSize div 4, yBlockSize div 4} fromImage:aImage)
        
set tmpBit2 to tmpImg’s TIFFRepresentation()
        
set chkTrans to (blankBit2’s isEqualToData:tmpBit2) as boolean
        
        
if chkTrans = false then –Not transparent block
          set the end of (pass2Res of spd) to {xPos:tmpPX, yPos:tmpPY}
        end if
      end repeat
    end repeat
  end repeat
  
  
  
set bArray to current application’s NSArray’s arrayWithArray:(pass2Res of spd)
  
  
set x2Min to calcMin("xPos", bArray) of me
  
set x2Max to calcMax("xPos", bArray) of me
  
  
set y2Min to calcMin("yPos", bArray) of me
  
set y2Max to calcMax("yPos", bArray) of me
  
  
–オリジナル画像を切り抜きして返す(NSImage)
  
return my cropNSImageTo:{x2Min, y2Min, x2Max + (xBlockSize div 4), y2Max + (yBlockSize div 4)} fromImage:aImage
end autoTrimImage

on calcMin(aLabel as string, nArray)
  set aStr to "@min." & aLabel
  
set aRes to nArray’s valueForKeyPath:aStr
  
return aRes as anything
end calcMin

on calcMax(aLabel as string, nArray)
  set aStr to "@max." & aLabel
  
set aRes to nArray’s valueForKeyPath:aStr
  
return aRes as anything
end calcMax

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

on cropNSImageTo:{x1, y1, x2, y2} fromImage:theImage
  set newWidth to x2 – x1
  
set newHeight to y2 – y1
  
  
set newRect to {{x:x1, y:y1}, {width:newWidth, height:newHeight}}
  
  
theImage’s lockFocus()
  
set theRep to NSBitmapImageRep’s alloc()’s initWithFocusedViewRect:newRect
  
theImage’s unlockFocus()
  
  
set outImage to NSImage’s alloc()’s initWithSize:(theRep’s |size|())
  
outImage’s addRepresentation:theRep
  
  
return outImage
end cropNSImageTo:fromImage:

–NSImageを指定の大きさでトリミング
on cropNSImageBy:{x1, y1, newWidth, newHeight} fromImage:theImage
  set theSize to (theImage’s |size|()) as record
  
set oldHeight to height of theSize
  
  
set newRect to {{x:x1, y:y1}, {width:newWidth, height:newHeight}}
  
  
theImage’s lockFocus()
  
set theRep to NSBitmapImageRep’s alloc()’s initWithFocusedViewRect:newRect
  
theImage’s unlockFocus()
  
  
set outImage to NSImage’s alloc()’s initWithSize:(theRep’s |size|())
  
outImage’s addRepresentation:theRep
  
  
return outImage
end cropNSImageBy:fromImage:

–画像を指定パスにPNG形式で保存
on saveImageRepAtPathAsPNG(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))
  
return (myNewImageData’s writeToFile:newPath atomically:true) as boolean
end saveImageRepAtPathAsPNG

–リストに入れたレコードを、指定の属性ラベルの値で抽出
on filterRecListByLabel1(aArray, aPredicate as string, aVal)
  set aPredicate to current application’s NSPredicate’s predicateWithFormat_(aPredicate, aVal)
  
set filteredArray to aArray’s filteredArrayUsingPredicate:aPredicate
  
return filteredArray
end filterRecListByLabel1

★Click Here to Open This Script 

Posted in Image | Tagged 13.0savvy 14.0savvy 15.0savvy | 1 Comment

余白トリミング実験 v2

Posted on 11月 21, 2024 by Takaaki Naganoya

背景が透過しているPNG画像で、余計な余白部分を自動でトリミングするAppleScriptの試作品です。実際に画像のトリミングを行います。1024×1024ぐらいまでの大きさのPNG画像が想定しているターゲットで、4Kとか8Kぐらいの画像は想定していません。

この、背景透過画像の余計な余白を自動トリミングする、という部品は割と(個人的に)重要なのでいろいろ試してみたものです。


▲テストに利用したPNG画像(196 × 309 ピクセル)


▲オリジナル画像をPreview.appで表示させたところ。背景の余白がある


▲本Scriptで自動トリミングを行ったところ

いろいろチューニングしてみましたが、画像の空白エリアの検出は、「元画像の分割数」に応じていろいろ切り抜きすぎたり、余白が多すぎたりとかなり変動が生じました。

32×32分割だと処理速度的に0.4秒@M2なので、16×16前後が向いている感じでした。20×20ぐらいでも試していますが、結局、切り抜きすぎるのは避けたいところです。

AppleScript名:余白トリミング実験 v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/11/21
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.8" — macOS 12 or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

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 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 NSBezierPath : a reference to current application’s NSBezierPath
property NSPNGFileType : a reference to current application’s NSPNGFileType
property NSMutableArray : a reference to current application’s NSMutableArray
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep

–画像分割ブロックサイズ
property imgDivXStep : 16
property imgDivYStep : 16

script spd
  property outList : {}
end script

set aFile to POSIX path of (choose file with prompt "PNG画像を選択")

–時間計測用
set a1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()

set aURL to |NSURL|’s fileURLWithPath:aFile
set aImage to NSImage’s alloc()’s initWithContentsOfURL:aURL

set sRes to aImage’s |size|()
–> example: {width:196.0, height:309.0}

set aHeight to height of sRes
set aWidth to width of sRes

set xBlockSize to (aWidth div imgDivXStep)
set yBlockSize to (aHeight div imgDivYStep)

–transparent block sample
set blankImg to makeNSImageWithFilledWithColor(xBlockSize, yBlockSize, current application’s NSColor’s clearColor()) of me
set blankBit to blankImg’s TIFFRepresentation()

set (outList of spd) to {}

repeat with y from 0 to (aHeight – yBlockSize) by yBlockSize
  set oneLine to ""
  
  
repeat with x from 0 to (aWidth – xBlockSize) by xBlockSize
    –crop a part of image and check transparent
    
set tmpImg to (my cropNSImageBy:{x, y, xBlockSize, yBlockSize} fromImage:aImage)
    
set tmpBit to tmpImg’s TIFFRepresentation()
    
set chkTrans to (blankBit’s isEqualToData:tmpBit) as boolean
    
    
if chkTrans = false then –Not transparent block
      set the end of (outList of spd) to {xPos:x, yPos:y}
    end if
  end repeat
  
end repeat

–時間計測用
set b1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
set c1Dat to b1Dat – a1Dat
log c1Dat

–最大値、最小値を取得
set nArray to (NSMutableArray’s arrayWithArray:(outList of spd))

set xMin to calcMin("xPos", nArray) of me
set xMax to calcMax("xPos", nArray) of me

set yMin to calcMin("yPos", nArray) of me
set yMax to calcMax("yPos", nArray) of me

–オリジナル画像を切り抜き
set cImage to my cropNSImageTo:{xMin + (xBlockSize / 2), yMin + (yBlockSize / 2), xMax + (xBlockSize / 2), yMax + (yBlockSize / 2)} fromImage:aImage

–ファイル保存
set outPath to POSIX path of (choose file name with prompt "PNG画像の保存ファイル名を指定してください(拡張子入力必須)")
saveImageRepAtPathAsPNG(cImage, outPath) of me

on calcMin(aLabel as string, nArray)
  set aStr to "@min." & aLabel
  
set aRes to nArray’s valueForKeyPath:aStr
  
return aRes as anything
end calcMin

on calcMax(aLabel as string, nArray)
  set aStr to "@max." & aLabel
  
set aRes to nArray’s valueForKeyPath:aStr
  
return aRes as anything
end calcMax

–指定サイズの画像を作成し、指定色で塗ってファイル書き出し
on makeNSImageWithFilledWithColor(aWidth, aHeight, fillColor)
  set retinaF to (NSScreen’s mainScreen()’s backingScaleFactor()) as real
  
–>  2.0 (Retina) / 1.0 (Non Retina)
  
  
set anImage to current application’s NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight))
  
anImage’s lockFocus()
  
—
  
set theRect to {{x:0, y:0}, {height:aHeight / retinaF, width:aWidth / retinaF}}
  
set theNSBezierPath to current application’s NSBezierPath’s bezierPath
  
theNSBezierPath’s appendBezierPathWithRect:theRect
  
—
  
fillColor’s |set|() –色設定
  
theNSBezierPath’s fill() –ぬりつぶし
  
—
  
anImage’s unlockFocus()
  
—
  
return anImage
end makeNSImageWithFilledWithColor

on cropNSImageTo:{x1, y1, x2, y2} fromImage:theImage
  set newWidth to x2 – x1
  
set newHeight to y2 – y1
  
set theSize to (theImage’s |size|()) as record
  
set oldHeight to height of theSize
  
  
— transpose y value for Cocoa coordintates
  
set y1 to oldHeight – newHeight – y1
  
set newRect to {{x:x1, y:y1}, {width:newWidth, height:newHeight}}
  
  
theImage’s lockFocus()
  
set theRep to NSBitmapImageRep’s alloc()’s initWithFocusedViewRect:newRect
  
theImage’s unlockFocus()
  
  
set outImage to NSImage’s alloc()’s initWithSize:(theRep’s |size|())
  
outImage’s addRepresentation:theRep
  
  
return outImage
end cropNSImageTo:fromImage:

–NSImageを指定の大きさでトリミング
on cropNSImageBy:{x1, y1, newWidth, newHeight} fromImage:theImage
  set theSize to (theImage’s |size|()) as record
  
set oldHeight to height of theSize
  
  
— transpose y value for Cocoa coordintates
  
set y1 to oldHeight – newHeight – y1
  
set newRect to {{x:x1, y:y1}, {width:newWidth, height:newHeight}}
  
  
theImage’s lockFocus()
  
set theRep to NSBitmapImageRep’s alloc()’s initWithFocusedViewRect:newRect
  
theImage’s unlockFocus()
  
  
set outImage to NSImage’s alloc()’s initWithSize:(theRep’s |size|())
  
outImage’s addRepresentation:theRep
  
  
return outImage
end cropNSImageBy:fromImage:

–画像を指定パスにPNG形式で保存
on saveImageRepAtPathAsPNG(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))
  
return (myNewImageData’s writeToFile:newPath atomically:true) as boolean
end saveImageRepAtPathAsPNG

★Click Here to Open This Script 

Posted in Image | Tagged 13.0savvy 14.0savvy 15.0savvy | Leave a comment

新刊電子書籍「AppleScript基礎テクニック(33)選択中のオブジェクト取得」を刊行

Posted on 11月 21, 2024 by Takaaki Naganoya

新刊電子書籍「AppleScript基礎テクニック(33)複数のアプリをコントロール」を刊行しました。全74ページ、サンプルAppleScriptアーカイブつき。
→ 販売ページ

macOS上のGUIアプリの書類やウィンドウ中で選択中のオブジェクトを取得し、その情報をもとにAppleScriptで処理を行なって、もとの選択オブジェクトに反映させるといった処理を、日常的に行っています。

このような書き方ができると、まるでAppleScriptによってGUIアプリの機能を拡張しているようにも見えます。実際には外部で処理を行なっていたとしても、使い勝手としては拡張しているように振る舞えます。

ある意味、AppleScriptの備える最強の機能といってもよいでしょう。本書で、この強力なselection機能について、その概要から実例、注意点にいたるまで幅広くご紹介いたします。

PDF 74ページ、Zipアーカイブ添付

目次

■最初に:macOS 13以降では最初にステージマネージャを必ずオフにしてください

macOS 13.x
macOS 14.x
macOS 15.x
その他、オフにすることが望ましい機能

■アプリ上の選択中のオブジェクトにアクセスする予約語「selection」

GUIアプリ上の選択中のオブジェクトを知る
選択中のオブジェクトは、1つだけじゃない
選択中のオブジェクトを加工することも
選択中のオブジェクトの情報分析

■選択中のオブジェクトの情報をもとに他のアプリで処理

selection系の機能をサポートしているアプリ一覧
selectを含む予約語を持つアプリと予約語①
selectを含む予約語を持つアプリと予約語②
selectを含む予約語を持つアプリと予約語③

■selectionの主な実例

selectionの取得方法①(Finder)
selectionの取得方法②(Finder)
selectionの書き換え①(Finder)
selectionの書き換え②(Finder)
selectionの取得方法③(Finder)

selectionの取得方法(住所録)
selectionの書き換え(住所録)
selectionの書き換え(住所録)

selectionの取得方法①(Keynote)
selectionの取得方法②(Keynote)
selectionの書き換え(Keynote)

selectionの取得方法①(ミュージック)
selectionの取得方法②(ミュージック)
selectionの書き換え(ミュージック)

selectionの取得方法①(CotEditor)
selectionの取得方法②(CotEditor)
selectionの書き換え(CotEditor)

selectionの取得方法①(Numbers)
selectionの取得方法②(Numbers)
active sheetの取得方法(Numbers)
selection rangeの取得方法①(Numbers)
selection rangeの取得方法②(Numbers)
selection rangeのセル内容書き換え①(Numbers)
selection rangeのセル内容書き換え②(Numbers)
selection rangeのセル内容書き換え③(Numbers)

selectionの取得方法①(Excel)
selectionの取得方法②(Excel)
選択中のワークシートの取得方法(Excel)
selectionの書き換え(Excel)

selectionの取得方法(Pixelmator Pro)
select-を含む予約語解説①(Pixelmator Pro)
select-を含む予約語解説②(Pixelmator Pro)
select-を含むコマンド実例①(Pixelmator Pro)
select-を含むコマンド実例②(Pixelmator Pro)
select-を含むコマンド実例③(Pixelmator Pro)
select-を含むコマンド実例④(Pixelmator Pro)
select-を含むコマンド実例⑤(Pixelmator Pro)
select-を含むコマンド実例⑥(Pixelmator Pro)
select-を含むコマンド実例⑦(Pixelmator Pro)
select-を含むコマンド実例⑧(Pixelmator Pro)
select-を含むコマンド実例⑨(Pixelmator Pro)
select-を含むコマンド実例⑩(Pixelmator Pro)
select-を含むコマンド実例⑪(Pixelmator Pro)

■selectionを使用うえで注意すべき点

注意点1:大量のオブジェクトの受け渡しに要注意
注意点2:情報の書き戻し時には時間がかかる例も
注意点3:選択オブジェクトの種別判定を①
注意点3:選択オブジェクトの種別判定を②

Posted in Books news | Tagged 13.0savvy 14.0savvy 15.0savvy Contacts CotEditor Excel Finder Keynote Music Numbers Pixelmator Pro | Leave a comment

新刊電子書籍「AppleScript基礎テクニック(32)複数のアプリをコントロール」を刊行

Posted on 11月 21, 2024 by Takaaki Naganoya

電子書籍新刊「AppleScript基礎テクニック(32)複数のアプリをコントロール」を刊行しました。全370ページ、サンプルAppleScriptアーカイブつき。
→ 販売ページ

1つのAppleScriptで複数のアプリを操作して処理するのは「常識」ですが、複数のアプリをAppleScriptで操作して処理を行うスタイルは割と独特なものだと指摘されました。

複数アプリの操作はとくに特殊な話ではありませんし、それほど難しい話でもありません。日常的にやっていることなので、その原理がわかれば柔軟で多用途なScriptを書いて「業務を積極的に楽にする」手助けとなることでしょう。

PDF 39ページ、Zipアーカイブ添付

目次

最初に:macOS 13以降では最初にステージマネージャを必ずオフにしてください
macOS 13.x
macOS 14.x
macOS 15.x
その他、オフにすることが望ましい機能

■複数アプリのコントロール3つのパターン

複数アプリのコントロール
自動処理フローから見た各アプリの役割
複数アプリ操作パターン①コマンド呼び出し
複数アプリ操作パターン②ファイル入出力
複数アプリ操作パターン③選択箇所を処理

■複数アプリのコントロール処理の具体例

各アプリは他のアプリのオブジェクトを理解できない
他のアプリのオブジェクトを理解するには
オブジェクトの属性値をよく見てみよう①
オブジェクトの属性値をよく見てみよう②
Keynote上のテキストをPages上に再現①
Keynote上のテキストをPages上に再現②
Keynote上のテキストをPages上に再現③
Keynote上のテキストをPages上に再現④

■GUI Scriptingによるコピペではほとんどの処理を実現できません

GUI Scriptingでコピー&ペースト動作?
異なるアプリ間のオブジェクトのテキスト色の反映

■複数アプリのコントロールその具体例

アプリAのデータをもとにアプリBの機能を利用
複数アプリ、機能の操作例①
複数アプリ、機能の操作例②
複数アプリ、機能の操作例②(参考資料)
複数アプリ、機能の操作例③

Posted in Books news | Tagged 13.0savvy 14.0savvy 15.0savvy | Leave a comment

余白トリミング実験 v1

Posted on 11月 21, 2024 by Takaaki Naganoya

背景が透過しているPNG画像で、余計な余白部分を自動でトリミングするAppleScriptの試作品です。


▲テストに利用したPNG画像(196 × 309 ピクセル)

いまのところ、画像を細かく分割して、透明な画像かどうかをブロックごとにチェックするだけです。

画像が真っ白かどうか、透明かどうかといったチェックは、すでに高速処理できるノウハウがあったので、ただそれを応用したものです。

実際にAppleScriptだけで記述して、そこそこの速度が出ています。画像の分割ブロック数が8×8だといまひとつで、16×16でもイマイチ。32 x 32分割ブロックぐらいで「そんなもんだろ」という印象。


▲8×8分割ブロック(0.04秒ぐらい @MacBook Air M2)


▲16×16分割ブロック(0.1秒ぐらい @MacBook Air M2)


▲32×32分割ブロック(0.5秒ぐらい @MacBook Air M2)

当初は可変サイズ分割を考えていましたが、そこまで難しい処理をしなくても良さそうな雰囲気。

何らかの画像処理を行った結果で透明部分が余計に存在するエリアを削除しておくぐらいなので、そんなにシビアにチューニングしなくてもよさそうな気がします。そんなに巨大な画像を処理しなければいいんじゃないでしょうか。

もしも、巨大な画像を処理する場合には、サムネイル画像を作成して、その画像に対してこのような処理を行えばいいんじゃないでしょうか。

このScriptは、背景が透過していることを前提に組んでありますが、画像の4隅から色をピックアップして、多数決で透過なのか白なのかを決定してもいいかもしれません。「余白がかならず存在する」画像であれば、このやり方でいいかも?

AppleScript名:余白トリミング実験 v1.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/11/21
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.8" — macOS 12 or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

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

property imgDivXStep : 8
property imgDivYStep : 8

set aFile to POSIX path of (choose file)

set a1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()

set aURL to |NSURL|’s fileURLWithPath:aFile
set aImage to NSImage’s alloc()’s initWithContentsOfURL:aURL

set sRes to aImage’s |size|()
–> example: {width:196.0, height:309.0}

set aHeight to height of sRes
set aWidth to width of sRes

set xBlockSize to (aWidth div imgDivXStep)
set yBlockSize to (aHeight div imgDivYStep)

–transparent block sample
set blankImg to makeNSImageWithFilledWithColor(xBlockSize, yBlockSize, current application’s NSColor’s clearColor()) of me
set blankBit to blankImg’s TIFFRepresentation()

set outList to ""

repeat with y from 0 to (aHeight – yBlockSize) by yBlockSize
  set oneLine to ""
  
  
repeat with x from 0 to (aWidth – xBlockSize) by xBlockSize
    –crop a part of image and check transparent
    
set tmpImg to (my cropNSImageBy:{x, y, xBlockSize, yBlockSize} fromImage:aImage)
    
set tmpBit to tmpImg’s TIFFRepresentation()
    
set chkTrans to (blankBit’s isEqualToData:tmpBit) as boolean
    
    
if chkTrans = true then
      set oneLine to oneLine & "□" –Transparent Block
    else
      set oneLine to oneLine & "■" –Not transparent Block
    end if
  end repeat
  
  
set outList to outList & oneLine & return
end repeat

set b1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
set c1Dat to b1Dat – a1Dat
log c1Dat

return outList

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

on cropNSImageTo:{x1, y1, x2, y2} fromImage:theImage
  set newWidth to x2 – x1
  
set newHeight to y2 – y1
  
set theSize to (theImage’s |size|()) as record
  
set oldHeight to height of theSize
  
  
— transpose y value for Cocoa coordintates
  
set y1 to oldHeight – newHeight – y1
  
set newRect to {{x:x1, y:y1}, {width:newWidth, height:newHeight}}
  
  
theImage’s lockFocus()
  
set theRep to NSBitmapImageRep’s alloc()’s initWithFocusedViewRect:newRect
  
theImage’s unlockFocus()
  
  
set outImage to NSImage’s alloc()’s initWithSize:(theRep’s |size|())
  
outImage’s addRepresentation:theRep
  
  
return outImage
end cropNSImageTo:fromImage:

–NSImageを指定の大きさでトリミング
on cropNSImageBy:{x1, y1, newWidth, newHeight} fromImage:theImage
  set theSize to (theImage’s |size|()) as record
  
set oldHeight to height of theSize
  
  
— transpose y value for Cocoa coordintates
  
set y1 to oldHeight – newHeight – y1
  
set newRect to {{x:x1, y:y1}, {width:newWidth, height:newHeight}}
  
  
theImage’s lockFocus()
  
set theRep to NSBitmapImageRep’s alloc()’s initWithFocusedViewRect:newRect
  
theImage’s unlockFocus()
  
  
set outImage to NSImage’s alloc()’s initWithSize:(theRep’s |size|())
  
outImage’s addRepresentation:theRep
  
  
return outImage
end cropNSImageBy:fromImage:

★Click Here to Open This Script 

Posted in Image | Tagged 13.0savvy 14.0savvy 15.0savvy | Leave a comment

アプリのキーワード登録をチェック

Posted on 11月 21, 2024 by Takaaki Naganoya

アプリケーションフォルダ以下にあるアプリをすべてリストアップして、各アプリに「キーワード」が登録されているかをチェックするAppleScriptです。「キーワード」が設定されているものをPOSIX pathの一覧で返します。

「キーワード」というのは、Finder上で「情報を見る」コマンドで表示させたウィンドウで、「詳細情報」の下に表示される「キーワード」です。

最近、これを登録してあるアプリが出始めてきたので、全体でどの程度の数になっているのか調査すべく、書いてみました。実行には「Metadata Lib」AppleScriptライブラリを必要とします。実行環境はScript Debuggerである必要はありません。普通にスクリプトエディタで大丈夫です。

App Store申請時に記述する検索用キーワードとは異なるようです。他のアプリを検索したときにヒットすることを目的に、「iPhoto」「Aperture」などと指定してあるところが戦略的です。たしかに、Spotlightで「Aperture」をキーワードに検索するとPixelmator Proが出てきます。

AppleScript名:指定フォルダ以下のアプリケーションを取得して、アプリのキーワード登録をチェック.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/11/21
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

use AppleScript
use scripting additions
use framework "Foundation"
use framework "AppKit"
use mdLib : script "Metadata Lib" version "2.0.0" –https://macosxautomation.com/applescript/apps/Script_Libs.html

set origPath to {(POSIX path of (path to applications folder))}

set aResList to mdLib’s searchFolders:(origPath) searchString:("kMDItemContentType == %@") searchArgs:{"com.apple.application-bundle"}

set sList to {}

repeat with i in aResList
  set j to contents of i
  
set sRes to retAppKeywordsFromBundleIPath(j) of me
  
if sRes ≠ "" then
    set the end of sList to j
  end if
end repeat

return sList
–> {"/Applications/Pixelmator Pro.app", "/Applications/Dropzone 4.app", "/Applications/Spotify.app", "/Applications/MarsEdit.localized/MarsEdit.app", "/Applications/Keka.app", "/Applications/MindNode.app", "/Applications/NeoFinder.app", "/Applications/Linearity Curve.app", "/Applications/Amazon Kindle.app", "/Applications/PrimeVideo.app"}

–指定パスからアプリケーションの「キーワード」メタデータを取得する
on retAppKeywordsFromBundleIPath(appPath as string)
  set theRecord to mdLib’s fetchMetadataFor:appPath
  
return kMDItemKeywords of theRecord
end retAppKeywordsFromBundleIPath

★Click Here to Open This Script 

Posted in Metadata | Tagged 13.0savvy 14.0savvy 15.0savvy | Leave a comment

(確認中)AppleScript Dropletのバグっぽい動作が解消?

Posted on 11月 18, 2024 by Takaaki Naganoya

macOS 10.12で導入されたセキュリティ系の機能によって、AppleScriptドロップレットの動作が妨げられる現象が確認されてきました。

ドロップしたファイルが数回に分かれてon openハンドラに渡されたり、ドラッグ&ドロップしたファイルすべてがドロップレット側に認識されなかったりするという動作です。

これは、Gatekeeperの動作とquarantine機能(もたらされたファイルが安全かどうか確認されるまでプログラム側に引き渡されない仕組み)の相互作用によるもの、という話になっていますが……認証のためのインタフェースが用意されておらず、ユーザー側から見れば「説明もなしに動かなくなった」という状態でした。

macOS 10.12、10.13、10.14、10.15、11、12、13、14とずーーっとそのままです。レポートしても修正されず、Scripter側でも対策コードを共有するほかなく、この素朴な機能は問題を抱えたままになっていました。

一応、Shane Stanleyによる対策コードによってドロップレットが運用できていたのと、display drop dialogなどの他のドラッグ&ドロップのためのインタフェースを用意できていたのと、もともと個人的にはドロップレットが性に合わなかった(Finder上の選択中のファイルを取得したほうが事故が起こらなくて簡単)ため、対策はできていました。

ただ、初心者にこの状態をどう説明するの? Apple側で説明する気は一切ありません。完全にバグであり、不具合としかユーザーには映りません。

macOS 15betaでも問題が解決されていなかったので、この問題は放置状態のまま解決されないものとばかり思っていました。

それが、macOS 15.2betaか15.1あたりで解消されたようで(バグが出ても直してもレポートを出さないのがApple風味)、確認してみると13.7.2でもドロップしたファイルを見失うといった動作をしなくなった……ような気がします。

macOS 13/14/15と現行のmacOSに対しては同様のアップデートが行われたのではないでしょうか。

まだ確認が不十分だと感じるのと、どうせmacOSのマイナーアップデートでまた使えなくなったりするんだろうというところです。

一方で、Cocoa AppleScript AppletについてはmacOS 12.6以降ずっと動作しない状況が続いています。こちらもレポートしても一切の反応がない状態です。直す気があるのであればいいのですが、その気がないのならスクリプトエディタのテンプレートから削除するといった処置が必要(試してみて動かないというのが最悪)でしょう。

Posted in Droplet | Tagged 13.0savvy 14.0savvy 15.0savvy | 1 Comment

最前面のKeynote書類で選択中のshapeを一番上のガイドオブジェクトの幅をもとに、残りを等分割

Posted on 11月 15, 2024 by Takaaki Naganoya

Keynote書類上で複数Shapeないしtext itemが選択された状態で、一番上にあるitemの幅に、下にあるitemを等分割+位置合わせを行うAppleScriptです。

言葉で言い表すと難しいのですが、画面キャプチャで表現すると一目瞭然です。


▲処理前、4つのshapeオブジェクトを選択状態に


▲処理後、上側のshapeの幅で下のshapeを等分割+ギャップ指定

電子書籍作成時によく行う作業をワンアクションで行えるようにしてみました。

2D ListのソートはVanilla AppleScriptで書かれたものを使っていますが、これはソートする対象のデータが極小なのと、本ScriptをmacOS標準搭載のScript Menuから呼び出すために作ったためです。

2D Listのソートを行うためだけに、BridgePlusを使用=Script DebuggerでEnhanced Appletに書き出す必要があるというのは面倒なので。

AppleScript名:最前面のKeynote書類で選択中のshapeを一番上のガイドオブジェクトの幅をもとに、残りを等分割
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/11/15
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

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

property xGap : 8 –X軸方向のオブジェクトの隙間座標値

tell application "Keynote"
  tell front document
    set aSel to selection
    
if aSel = {} then return
    
set fClass to class of first item of aSel
    
if fClass = slide then return –スライド上のオブジェクトではなく、スライドが選択されていた場合には処理しない
    
    
set objList to {}
    
set posList to {}
    
set aCount to 1
    
    
repeat with i in aSel
      set j to contents of i
      
set tmpClass to class of j
      
      
–条件に合うオブジェクトのみ処理対象に
      
if tmpClass is in {text item, shape} then
        set the end of objList to j
        
set the end of posList to ((position of j) & (width of j) & aCount)
        
        
set aCount to aCount + 1
      end if
    end repeat
    
    
    
set newPosList to shellSortListAscending(posList, 2) of sortLib –Y軸値をもとにソート
    
set guideObj to first item of newPosList –Y軸座標が一番少ない(上)のものをガイドオブジェクトとしてみなす
    
    
set newPosList to shellSortListAscending(rest of newPosList, 1) of sortLib –ガイドオブジェクト以外のオブジェクト座標値をX軸値でソート
    
set guideWidth to contents of item 3 of guideObj
    
    
set xStartPos to item 1 of item 1 of newPosList
    
set yPos to item 2 of item 1 of newPosList
    
set itemsCount to length of newPosList
    
    
set itemWidth to (guideWidth – (xGap * (itemsCount – 1))) / itemsCount
    
    
–下側オブジェクトの位置と幅修正処理
    
copy xStartPos to x
    
repeat with i from 1 to itemsCount
      
      
set y to item 2 of (item i of newPosList)
      
      
set targObj to item (item 4 of (item i of newPosList)) of objList
      
      
tell targObj
        set position of it to {x, y}
        
set width of it to itemWidth
      end tell
      
      
set x to x + itemWidth + (xGap)
      
    end repeat
  end tell
end tell

–Vanilla AppleScriptで書いた2D ListのSorting Lib
script sortLib
  –シェルソートで入れ子のリストを昇順ソート
  
on shellSortListAscending(aSortList, aKeyItem)
    script oBj
      property list : aSortList
    end script
    
set len to count oBj’s list’s items
    
set gap to 1
    
repeat while (gap ≤ len)
      set gap to ((gap * 3) + 1)
    end repeat
    
repeat while (gap > 0)
      set gap to (gap div 3)
      
if (gap < len) then
        repeat with i from gap to (len – 1)
          set temp to oBj’s list’s item (i + 1)
          
set j to i
          
repeat while ((j ≥ gap) and (contents of item aKeyItem of (oBj’s list’s item (j – gap + 1)) > item aKeyItem of temp))
            set oBj’s list’s item (j + 1) to oBj’s list’s item (j – gap + 1)
            
set j to j – gap
          end repeat
          
set oBj’s list’s item (j + 1) to temp
        end repeat
      end if
    end repeat
    
return oBj’s list
  end shellSortListAscending
  
  
  
–シェルソートで入れ子のリストを降順ソート
  
on shellSortListDescending(aSortList, aKeyItem)
    script oBj
      property list : aSortList
    end script
    
set len to count oBj’s list’s items
    
set gap to 1
    
repeat while (gap ≤ len)
      set gap to ((gap * 3) + 1)
    end repeat
    
repeat while (gap > 0)
      set gap to (gap div 3)
      
if (gap < len) then
        repeat with i from gap to (len – 1)
          set temp to oBj’s list’s item (i + 1)
          
set j to i
          
repeat while ((j ≥ gap) and (contents of item aKeyItem of (oBj’s list’s item (j – gap + 1)) < item aKeyItem of temp))
            set oBj’s list’s item (j + 1) to oBj’s list’s item (j – gap + 1)
            
set j to j – gap
          end repeat
          
set oBj’s list’s item (j + 1) to temp
        end repeat
      end if
    end repeat
    
return oBj’s list
  end shellSortListDescending
end script

★Click Here to Open This Script 

Posted in Object control | Tagged 13.0savvy 14.0savvy 15.0savvy Keynote | Leave a comment

ステージマネージャのON_OFF

Posted on 11月 15, 2024 by Takaaki Naganoya

macOS 13で搭載された「ステージマネージャ」機能のオン/オフを行うAppleScriptです。

ステージマネージャは、最前面のアプリのウィンドウだけを表示するようにする仕組みで、iPadOSに搭載されたものがそのままmacOSにも搭載されました。ドラッグ&ドロップをこのステージマネージャに対して行えるのと、表示ウィンドウを最前面のものだけに切り替えるものです。

つまり、マルチウィンドウのGUIに不慣れなユーザーのために用意された機能です。Windowsユーザー向けに用意した、ともいえるでしょう。

このステージマネージャのOn/Offを行います。動作内容はご覧のとおり、単にshellコマンドを呼び出しているだけです。現在オンになっているかどうかも、defaults readコマンドで同様に実行できることでしょう。


▲真っ先にオフにして、二度とオンにすることはなかったステージマネージャ(画面左端)


▲元に戻ると安心します

AppleScript名:ステージマネージャのON_OFF
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/11/15
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

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

set aBool to true
stageManagerControl(aBool) of me

delay 5

set aBool to false
stageManagerControl(aBool) of me

on stageManagerControl(aBool as boolean)
  set sText to "defaults write com.apple.WindowManager GloballyEnabled -bool " & (aBool as string)
  
do shell script sText
end stageManagerControl

★Click Here to Open This Script 

Posted in shell script System | Tagged 13.0savvy 14.0savvy 15.0savvy | Leave a comment

Pagesで選択中のテキストフレーム内のテキストを、指定記号の前まで太らせる

Posted on 11月 10, 2024 by Takaaki Naganoya

以前にKeynote用に作っておいたAppleScriptを、Pages用に書き直しました。

Pages書類、主に奥付けのテキストなどで、「項目名」「:」(セパレータ)「内容」みたいに列挙している箇所を行頭からセパレータの場所の前まで太字の書体に変更します。ヒラギノ角ゴシックでチェックしており、欧文フォントは考慮していません。

Pages v14.2+macOS 15.2Betaで実験しています。


▲実行前


▲実行後

AppleScript名:フォントを記号の前まで太らせる.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/11/01
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

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

property NSFont : a reference to current application’s NSFont
property NSFontManager : a reference to current application’s NSFontManager

–セパレータリスト、表記ゆらぎ対応(ゆらぎ表記個数は可変)
property separatorList : {{":", ":"}, {"mm", "㎜"}, {"cm", "㎝"}}

tell application "Pages"
  tell front document
    set aSel to selection
    
    
    
–Keynote上の選択中のオブジェクトでループ
    
repeat with i in aSel
      set j to contents of i
      
set tmpClass to class of j
      
      
      
–選択中のオブジェクトがテキストアイテムの場合に…….
      
if tmpClass = shape then
        set objText to object text of j
        
set fontName to font of object text of j
        
set fontSize to size of object text of j
        
        
        
–フォントを太らせる(ウェイトを上げる)
        
set fFamilyCount to countFontsInItsFamily(fontName) of me
        
if fFamilyCount = 2 then
          
          
–ヒラギノ角ゴProN W3 → ヒラギノ角ゴProN W6
          
set newFont to incrementFontWeight(fontName, 1) of me
          
        else if fFamilyCount > 4 then
          –ヒラギノ角ゴシック Wn のウェイトを上げ
          
set newFont to incrementFontWeight(fontName, 4) of me
          
        end if
        
        
set aCount to 1
        
set tList to splitByLInes(objText) of me
        
        
        
–行ごとにParseした行ごとのテキストでループ
        
repeat with ii in tList
          set jj to contents of ii
          
          
set anOffset to 0
          
          
–セパレータでループ
          
repeat with iii in separatorList
            –セパレータの「ゆらぎ」表記を考慮してループ
            
repeat with iiii in iii
              set jjjj to contents of iiii
              
set anOffset to offset of jjjj in jj
              
              
if anOffset is not equal to 0 then
                exit repeat
              end if
            end repeat
            
            
if anOffset is not equal to 0 then exit repeat
            
          end repeat
          
          
if anOffset is not equal to 0 then
            try
              set font of characters 1 thru (anOffset – 1) of paragraph aCount of object text of j to newFont
            end try
          end if
          
          
set aCount to aCount + 1
          
        end repeat
      end if
    end repeat
  end tell
end tell

–テキストを行ごとにParse
on splitByLInes(someText) — free to a good home
  set theString to current application’s NSString’s stringWithString:someText
  
set theList to theString’s componentsSeparatedByCharactersInSet:(current application’s NSCharacterSet’s newlineCharacterSet())
  
return theList as list
end splitByLInes

–フォントを太らせる。欧文フォントは考慮していない(別の方法で行う)
on incrementFontWeight(psFontName, incNum)
  set aFont to current application’s NSFont’s fontWithName:psFontName |size|:9.0
  
–> (NSCTFont) "HiraginoSans-W0 9.00 pt. P [] (0x12870af00) fobj=0x11b1e90d0, spc=1.98"
  
  
set fontM to current application’s NSFontManager’s sharedFontManager()
  
  
repeat incNum times
    set aFont to fontM’s convertWeight:true ofFont:aFont
  end repeat
  
  
return (aFont’s fontName()) as string
end incrementFontWeight

–指定フォントのファミリーに属するフォント数を取得
on countFontsInItsFamily(aPSName)
  set aFont to current application’s NSFont’s fontWithName:(aPSName) |size|:9.0
  
set aFamily to aFont’s familyName()
  
set fMan to current application’s NSFontManager’s sharedFontManager()
  
set fList to fMan’s availableMembersOfFontFamily:aFamily
  
return length of (fList as list)
end countFontsInItsFamily

★Click Here to Open This Script 

Posted in Font | Tagged 13.0savvy 14.0savvy 15.0savvy Pages | Leave a comment

FileMaker Pro v21.1.1アップデート

Posted on 11月 8, 2024 by Takaaki Naganoya

FileMaker Pro 2024(v21)がv21.1.1にアップデートしました。

macOS 12.xのサポートが打ち切られ、macOS 13以降が対象となっています。

FileMaker Pro v21.1.1のAppleScript用語辞書に、とくに変更は加えられていません。

Posted in news | Tagged 13.0savvy 14.0savvy 15.0savvy FileMaker Pro | Leave a comment

全フォントのmostCompatibleStringEncodingを求めて集計

Posted on 11月 6, 2024 by Takaaki Naganoya

使用中のmacOS環境にインストールされているフォントのmostCompatibleStringEncodingを求めて、集計出力するAppleScriptです。

mostCompatibleStringEncodingはフォントが対応しているエンコーディングということで、普通そんなものはないように思えますが、EnglishなどのAscii & Numelicだけの言語用フォントであれば、「それにしか対応していない」という意味でのmostCompatibleStringEncodingはあるんじゃないかと。

一応調査するために書いてみたものです。バーコード系のフォントやドットフォントが該当しそうな感じです。

AppleScript名:全フォントのmostCompatibleStringEncodingを求める.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/11/06
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—
use AppleScript
use scripting additions
use framework "Foundation"

property NSFont : a reference to current application’s NSFont
property NSPredicate : a reference to current application’s NSPredicate
property NSFontManager : a reference to current application’s NSFontManager

script spdf
  property fList : {}
  
property outList : {}
end script

set (outList of spdf) to {}
set (fList of spdf) to getEveryFontPSName() of me

repeat with i in (fList of spdf)
  set j to contents of i
  
set aEnc to chkFontsCompatibleEncoding(j) of me
  
–if aEnc is not equal to "default" then set the end of (outList of spdf) to {fontEncoding:aEnc}
  
set the end of (outList of spdf) to {fontEncoding:aEnc}
end repeat

set aCountedList to countEachRecord((outList of spdf)) of me
–> {{aCount:1, aData:{fontEncoding:"NSSymbolStringEncoding"}}, {aCount:860, aData:{fontEncoding:"default"}}, {aCount:1005, aData:{fontEncoding:"NSMacOSRomanStringEncoding"}}}

–Rec in Listの登場頻度を集計して出力
on countEachRecord(aRecList)
  set theCountedSet to current application’s NSCountedSet’s |set|()
  
repeat with i in aRecList
    set j to contents of i
    (
theCountedSet’s addObject:j)
  end repeat
  
  
set theEnumerator to theCountedSet’s objectEnumerator()
  
set anArray to current application’s NSMutableArray’s alloc()’s init()
  
  
repeat
    set aDict to current application’s NSMutableDictionary’s alloc()’s init()
    
    
set aValue to theEnumerator’s nextObject()
    
if aValue is missing value then exit repeat
    
    
set aCount to theCountedSet’s countForObject:aValue
    
    
aDict’s setObject:aCount forKey:"aCount"
    
aDict’s setObject:aValue forKey:"aData"
    
anArray’s addObject:aDict
  end repeat
  
  
return anArray as anything
end countEachRecord

on getEveryFontPSName()
  script spd
    property aList : {}
  end script
  
  
set aFontList to NSFontManager’s sharedFontManager()’s availableFonts()
  
set thePred to NSPredicate’s predicateWithFormat:"NOT SELF BEGINSWITH ’.’"
  
set aFontList to (aFontList’s filteredArrayUsingPredicate:thePred) as list
  
  
set aList of spd to {}
  
repeat with i in aFontList
    set aName to contents of i
    
set the end of aList of spd to aName
  end repeat
  
  
return aList of spd
end getEveryFontPSName

on chkFontsCompatibleEncoding(fontPSName as string)
  set aFont to current application’s NSFont’s fontWithName:(fontPSName) |size|:16
  
  
if aFont’s mostCompatibleStringEncoding() = (current application’s NSASCIIStringEncoding) then
    return "NSASCIIStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSNEXTSTEPStringEncoding) then
    return "NSNEXTSTEPStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSJapaneseEUCStringEncoding) then
    return "NSJapaneseEUCStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSUTF8StringEncoding) then
    return "NSUTF8StringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSISOLatin1StringEncoding) then
    return "NSISOLatin1StringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSSymbolStringEncoding) then
    return "NSSymbolStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSNonLossyASCIIStringEncoding) then
    return "NSNonLossyASCIIStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSShiftJISStringEncoding) then
    return "NSShiftJISStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSISOLatin2StringEncoding) then
    return "NSISOLatin2StringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSUnicodeStringEncoding) then
    return "NSUnicodeStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSWindowsCP1251StringEncoding) then
    return "NSWindowsCP1251StringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSWindowsCP1252StringEncoding) then
    return "NSWindowsCP1252StringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSWindowsCP1253StringEncoding) then
    return "NSWindowsCP1253StringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSWindowsCP1254StringEncoding) then
    return "NSWindowsCP1254StringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSWindowsCP1250StringEncoding) then
    return "NSWindowsCP1250StringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSISO2022JPStringEncoding) then
    return "NSISO2022JPStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSMacOSRomanStringEncoding) then
    return "NSMacOSRomanStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSProprietaryStringEncoding) then
    return "NSProprietaryStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSISO2022JPStringEncoding) then
    return "NSISO2022JPStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSJapaneseEUCStringEncoding) then
    return "NSJapaneseEUCStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSShiftJISStringEncoding) then
    return "NSShiftJISStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSUTF16BigEndianStringEncoding) then
    return "NSUTF16BigEndianStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSUTF16LittleEndianStringEncoding) then
    return "NSUTF16LittleEndianStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSUTF16StringEncoding) then
    return "NSUTF16StringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSUnicodeStringEncoding) then
    return "NSUnicodeStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSUTF32BigEndianStringEncoding) then
    return "NSUTF32BigEndianStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSUTF32LittleEndianStringEncoding) then
    return "NSUTF32LittleEndianStringEncoding"
  else if aFont’s mostCompatibleStringEncoding() = (current application’s NSUTF32StringEncoding) then
    return "NSUTF32StringEncoding"
  else
    return "default"
  end if
end chkFontsCompatibleEncoding

★Click Here to Open This Script 

Posted in Font | Tagged 13.0savvy 14.0savvy 15.0savvy | Leave a comment

PostScript名で指定のフォントのTraitMaskを付与する_v3

Posted on 11月 3, 2024 by Takaaki Naganoya

PostScript名で指定したフォントにTraitMaskを付与し、そのPostScript名の文字列を返すAppleScriptです。

指定フォントのBoldバージョンを取得する、という用途においてはこれで済むのですが、すでにBold指定されたフォントを渡したときにExtra Boldのフォントを返すという処理には使えません。

AppleScript名:PostScript名で指定のフォントのTraitMaskを付与する_v3.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/10/19
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

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

property NSFont : a reference to current application’s NSFont
property NSFontManager : a reference to current application’s NSFontManager

set aName to "TimesNewRomanPSMT"
set traitsNum to (current application’s NSBoldFontMask)
set bName to getTraitedFontName(aName, traitsNum) of me
–> "TimesNewRomanPS-BoldMT"

on getTraitedFontName(aName, traitsNum)
  set bFont to getBoldFontObj(aName, traitsNum) of me
  
return bFont’s fontName() as string
end getTraitedFontName

–BoldフォントのNSFontを取得
on getBoldFontObj(aName, traitsNum)
  set aFont to current application’s NSFont’s fontWithName:aName |size|:9.0
  
–> (NSCTFont) "HelveticaNeue 9.00 pt. P [] (0x4864eb0e0) fobj=0x12ee73e90, spc=2.50"
  
  
set fontM to current application’s NSFontManager’s sharedFontManager()
  
  
–指定のフォントがBoldのtraitを持っているかをチェック
  
set fRes to fontM’s fontNamed:aName hasTraits:traitsNum
  
if (fRes as boolean) = true then return aFont –すでに該当する
  
  
set bFont to fontM’s convertFont:(aFont) toHaveTrait:(traitsNum)
  
  
return bFont
end getBoldFontObj

–指定フォントのファミリーに属するフォント数を取得
on countFontsInItsFamily(aPSName)
  set aFont to current application’s NSFont’s fontWithName:(aPSName) |size|:9.0
  
set aFamily to aFont’s familyName()
  
set fMan to current application’s NSFontManager’s sharedFontManager()
  
set fList to fMan’s availableMembersOfFontFamily:aFamily
  
return length of (fList as list)
end countFontsInItsFamily

★Click Here to Open This Script 

Posted in Font | Tagged 13.0savvy 14.0savvy 15.0savvy NSFontManager | Leave a comment

全フォントから全traitsを調べる v2

Posted on 11月 3, 2024 by Takaaki Naganoya

macOSにインストールされているすべてのフォントに対して、すべてのtraitsを確認して、タブ区切りテキストとして出力するAppleScriptです。

実際にNumbersの表データに入力して、Numbers上のフィルタを用いてtraitsの分布状況を調べてみました。とくに問題はないようです。

AppleScript名:全フォントから全traitsを調べる v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/11/03
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

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

property NSFont : a reference to current application’s NSFont
property NSPredicate : a reference to current application’s NSPredicate
property NSFontManager : a reference to current application’s NSFontManager

set fontStatList to {}
set fList to getEveryFontPSName() of me
set fontM to NSFontManager’s sharedFontManager()

repeat with i in fList
  set j to contents of i
  
set f1Res to (fontM’s fontNamed:(j) hasTraits:(current application’s NSItalicFontMask)) as integer
  
set f2Res to (fontM’s fontNamed:(j) hasTraits:(current application’s NSBoldFontMask)) as integer
  
set f3Res to (fontM’s fontNamed:(j) hasTraits:(current application’s NSUnboldFontMask)) as integer
  
set f4Res to (fontM’s fontNamed:(j) hasTraits:(current application’s NSNonStandardCharacterSetFontMask)) as integer
  
set f5Res to (fontM’s fontNamed:(j) hasTraits:(current application’s NSNarrowFontMask)) as integer
  
set f6Res to (fontM’s fontNamed:(j) hasTraits:(current application’s NSExpandedFontMask)) as integer
  
set f7Res to (fontM’s fontNamed:(j) hasTraits:(current application’s NSCondensedFontMask)) as integer
  
set f8Res to (fontM’s fontNamed:(j) hasTraits:(current application’s NSSmallCapsFontMask)) as integer
  
set f9Res to (fontM’s fontNamed:(j) hasTraits:(current application’s NSPosterFontMask)) as integer
  
set fARes to (fontM’s fontNamed:(j) hasTraits:(current application’s NSCompressedFontMask)) as integer
  
set fBRes to (fontM’s fontNamed:(j) hasTraits:(current application’s NSFixedPitchFontMask)) as integer
  
set fCRes to (fontM’s fontNamed:(j) hasTraits:(current application’s NSUnitalicFontMask)) as integer
  
set the end of fontStatList to {j, f1Res, f2Res, f3Res, f4Res, f5Res, f6Res, f7Res, f8Res, f9Res, fARes, fBRes, fCRes}
end repeat

–結果のリストをタブ区切りテキストに
set sRes to make2DList2TabSepMultilineText(fontStatList) of me
–>
(*
07LightNovelPOP  0  1  0  0  0  0  0  0  0  0  0  0
07YasashisaGothic  0  0  0  0  0  0  0  0  0  0  0  0
07YasashisaGothicBold  0  0  0  0  0  0  0  0  0  0  0  0
7barP  0  0  0  0  0  0  0  0  0  0  0  0
7barSP  0  0  0  0  0  0  0  0  0  0  0  0……..
*)

on getEveryFontPSName()
  set aFontList to NSFontManager’s sharedFontManager()’s availableFonts()
  
set thePred to NSPredicate’s predicateWithFormat:"NOT SELF BEGINSWITH ’.’"
  
set aFontList to (aFontList’s filteredArrayUsingPredicate:thePred) as list
  
  
set aList to {}
  
repeat with i in aFontList
    set aName to contents of i
    
set the end of aList to aName
  end repeat
  
  
return aList
end getEveryFontPSName

on make2DList2TabSepMultilineText(aList)
  set aStr to ""
  
  
repeat with i in aList
    set j to contents of i
    
set tmpStr to list2TABseparatedText(j) of me
    
set aStr to aStr & tmpStr & return
  end repeat
  
  
return aStr
end make2DList2TabSepMultilineText

–リストをタブ区切りのテキストに変換
on list2TABseparatedText(aList)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to tab
  
set bList to aList as string
  
set AppleScript’s text item delimiters to curDelim
  
return bList
end list2TABseparatedText

★Click Here to Open This Script 

Posted in Font | Tagged 13.0savvy 14.0savvy 15.0savvy NSFontManager | Leave a comment

指定フォントの指定Traitが存在するかをチェック

Posted on 11月 3, 2024 by Takaaki Naganoya

欧文フォントを太らせる処理を行う下調べとして、指定PostScriptフォント名のフォントファミリーに、指定のバリエーションが存在するかどうかを調べるAppleScriptを書いてみました。

Classic MacOS時代はフォントを変形させてボールド表現を行ったり、イタリック表現を行うなどの機能が実装されていました。

一方、OPENSTEPを源流に持つmacOSは、さまざまなバリエーションのフォントをあらかじめ用意しておくことが必要です。このあたりの仕様は、なんとなく技術的な後退を感じますが、まあいいでしょう。

そして、NSFontManagerの機能を用いて、指定のフォントバリエーション(ボールド)が存在するかを確認するはずだったのが本AppleScriptです。

ただ、実際に試してみたところ、どのフォントを指定してもダメでした。「ボールド書体はない」と言われます。あれ????


▲SF Pro Text、18のスタイルを持つ


▲Skia、10のスタイルを持つ

そこで、macOSに入っているすべてのフォントのPostScript名を取得して、すべてのフォントのTraitsをチェック。

結果、けっこうな数のフォントがboldのTraitsを持っている、と返ってきました。名前に「Bold」と入っているフォントばかりが。

つまり、NSFontManagerのfontNamed:① hasTraits:② は、指定のフォント自体にTraitsがあるのか調べるAPIであったということです。自分が誤解していたようでした。

AppleScript名:指定フォントの指定Traitsが存在するかをチェック.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/11/02
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

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

–set aName to "HelveticaNeue"
–set aName to "Verdana"
–set aName to "TimesNewRomanPSMT"
set aName to "SFProText-Regular"

–指定のフォントがBoldのtraitを持っているかをチェック
set fontM to current application’s NSFontManager’s sharedFontManager()
set fRes to fontM’s fontNamed:aName hasTraits:(current application’s NSBoldFontMask)
–> false(みんなfalse)

★Click Here to Open This Script 

AppleScript名:全フォントからtraitsを調べる.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/11/03
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

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

property NSFont : a reference to current application’s NSFont
property NSPredicate : a reference to current application’s NSPredicate
property NSFontManager : a reference to current application’s NSFontManager

set okList to {}
set fList to getEveryFontPSName() of me
set fontM to NSFontManager’s sharedFontManager()

repeat with i in fList
  set j to contents of i
  
set fRes to (fontM’s fontNamed:(j) hasTraits:(current application’s NSBoldFontMask))
  
if fRes as boolean = true then set the end of okList to j
end repeat

return okList

on getEveryFontPSName()
  set aFontList to NSFontManager’s sharedFontManager()’s availableFonts()
  
set thePred to NSPredicate’s predicateWithFormat:"NOT SELF BEGINSWITH ’.’"
  
set aFontList to (aFontList’s filteredArrayUsingPredicate:thePred) as list
  
  
set aList to {}
  
repeat with i in aFontList
    set aName to contents of i
    
set the end of aList to aName
  end repeat
  
  
return aList
end getEveryFontPSName

★Click Here to Open This Script 

Posted in Font | Tagged 13.0savvy 14.0savvy 15.0savvy | Leave a comment

Keynoteで選択中のtext itemの冒頭のフォントを太くする v2

Posted on 11月 1, 2024 by Takaaki Naganoya

Keynote書類で選択中のテキストアイテムのうち、各行の冒頭からマークの文字までの間を太文字にするAppleScriptです。

v1を改良し、さまざまな区切り記号に対応させるべく、改修を行なってみたものです。

当初は、各テキストアイテムの内部テキストを解析して、共通記号文字を計算して自動で認識処理を行なってみようかと考えていました。統計処理を行なって共通で登場する文字をピックアップさせることを検討していました。

ただ、これだと複数の選択アイテムで別々の区切り文字を採用している場合に対応できません。

統計処理を行わず、技術的にもっとレベルを下げ、「ゆらぎ」検出のためのオーソドックスな、ゆらぎ表記列挙リストを作って、ひたすらループで処理するように改変。


▲処理前 Keynoteの書類上でテキストアイテムを選択


▲処理後 各テキストアイテムで、指定の記号より前の部分の文字を太くした

なお、本Scriptは書式変更ターゲット文字のピックアップ性能を向上させたものであり、欧文フォントの処理を考慮したものにはなっていません。フォントファミリー内のウェイトを上げたフォントを求めるという処理を行なっています。

fFamilyCount = 2

の場合には、「ヒラギノ角ゴProN W3」を「ヒラギノ角ゴProN W6」に変更する処理を行います。

fFamilyCount > 4

の場合には、「ヒラギノ角ゴシック Wn」のウェイトを上げています。

もしも、利用中のMacにウェイトが多数含まれているフォントをインストールして、Keynote書類上でそのフォントを指定している場合には、ウェイトを上げたフォントを求める処理で、文字を太くするよう処理されることでしょう。

AppleScript名:選択中のtext itemの冒頭のフォントを太くする(フォントのWeightを変更)v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/11/01
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

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

property NSFont : a reference to current application’s NSFont
property NSFontManager : a reference to current application’s NSFontManager

–セパレータリスト、表記ゆらぎ対応(ゆらぎ表記個数は可変)
property separatorList : {{":", ":"}, {"mm", "㎜"}, {"cm", "cm"}}

tell application "Keynote"
  tell front document
    set aSel to selection
    
    
    
–Keynote上の選択中のオブジェクトでループ
    
repeat with i in aSel
      set j to contents of i
      
set tmpClass to class of j
      
      
      
–選択中のオブジェクトがテキストアイテムの場合に…….
      
if tmpClass = text item then
        set objText to object text of j
        
set fontName to font of object text of j
        
set fontSize to size of object text of j
        
        
        
–フォントを太らせる(ウェイトを上げる)
        
set fFamilyCount to countFontsInItsFamily(fontName) of me
        
if fFamilyCount = 2 then
          set newFont to incrementFontWeight(fontName, 1) of me
        else if fFamilyCount > 4 then
          set newFont to incrementFontWeight(fontName, 4) of me
        end if
        
        
set aCount to 1
        
set tList to splitByLInes(objText) of me
        
        
        
–行ごとにParseした行ごとのテキストでループ
        
repeat with ii in tList
          set jj to contents of ii
          
          
set anOffset to 0
          
          
–セパレータでループ
          
repeat with iii in separatorList
            –セパレータの「ゆらぎ」表記を考慮してループ
            
repeat with iiii in iii
              set jjjj to contents of iiii
              
set anOffset to offset of jjjj in jj
              
              
if anOffset is not equal to 0 then
                exit repeat
              end if
            end repeat
            
            
if anOffset is not equal to 0 then exit repeat
            
          end repeat
          
          
if anOffset is not equal to 0 then
            try
              set font of characters 1 thru (anOffset – 1) of paragraph aCount of object text of j to newFont
            end try
          end if
          
          
set aCount to aCount + 1
          
        end repeat
      end if
    end repeat
  end tell
end tell

–テキストを行ごとにParse
on splitByLInes(someText) — free to a good home
  set theString to current application’s NSString’s stringWithString:someText
  
set theList to theString’s componentsSeparatedByCharactersInSet:(current application’s NSCharacterSet’s newlineCharacterSet())
  
return theList as list
end splitByLInes

–フォントを太らせる。欧文フォントは考慮していない(別の方法で行う)
on incrementFontWeight(psFontName, incNum)
  set aFont to current application’s NSFont’s fontWithName:psFontName |size|:9.0
  
–> (NSCTFont) "HiraginoSans-W0 9.00 pt. P [] (0x12870af00) fobj=0x11b1e90d0, spc=1.98"
  
  
set fontM to current application’s NSFontManager’s sharedFontManager()
  
  
repeat incNum times
    set aFont to fontM’s convertWeight:true ofFont:aFont
  end repeat
  
  
return (aFont’s fontName()) as string
end incrementFontWeight

–指定フォントのファミリーに属するフォント数を取得
on countFontsInItsFamily(aPSName)
  set aFont to current application’s NSFont’s fontWithName:(aPSName) |size|:9.0
  
set aFamily to aFont’s familyName()
  
set fMan to current application’s NSFontManager’s sharedFontManager()
  
set fList to fMan’s availableMembersOfFontFamily:aFamily
  
return length of (fList as list)
end countFontsInItsFamily

★Click Here to Open This Script 

Posted in Font Text | Tagged 10.15savvy 11.0savvy 12.0savvy 13.0savvy 14.0savvy 15.0savvy Keynote | Leave a comment

Keynoteで選択中のtext itemの冒頭のフォントを太くする

Posted on 10月 19, 2024 by Takaaki Naganoya

Keynote書類で選択中のテキストアイテムのうち、各行の冒頭から「:」の文字までの間を太文字にするAppleScriptです。


▲処理範囲に入っている文字列


▲処理前


▲処理後

本Scriptは、処理内容が地味な割に、処理内容(の説明)が大変です。かなり複雑な処理をやっているためです。(フォント名を文字列で組み立てるなどの)もっと乱暴な処理もできるのですが、ここはあえて丁寧な処理を行なってみました。

Keynote書類上の選択中のText item(複数の場合もある)内のObject textにアクセス。ここで、文字情報、フォント情報、フォントサイズ情報、文字色情報などが取得できます。

フォントサイズ情報を取得して(テキストアイテム内はすべて同じフォントが指定されているものと想定)、フォント名がPostScript名で返ってくるので、NSFontManagerの機能を用いて、当該フォントが所属するフォントファミリーを求めます。さらに、そのファミリーにいくつのフォントが所属しているのかを求めます。

ここで想定しているのは、ヒラギノ角ゴ W3/W6かヒラギノ角ゴシックW0〜W9です。欧文フォントでは、ボールド書体がファミリー中に存在するかをチェックし、存在すればボールド書体を指定するといったまったく別の処理が必要です。本Scriptはとりあえずやりたいことを詰め込んで動くレベルにまとめただけで、汎用性はあまりありません。

また、Keynoteのtext item中の「行」(paragraph)へのアクセスが安定していません。改行をリターンキーだけで行うか、Shift-Returnで行うか、Control-Returnで行うかといった些細な操作の違いによって行カウントできる行数に差が発生します。

安全のためには、AppleScript上でRTF(NSMutableAttributedString)を作って、そこでフォントの変更を行なってtext itemのobject textに書き戻すのが理想的です。

AppleScript名:選択中のtext itemの冒頭のフォントを太くする.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/10/19
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

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

property NSFont : a reference to current application’s NSFont
property NSFontManager : a reference to current application’s NSFontManager

tell application "Keynote"
  tell front document
    set aSel to selection
    
    
repeat with i in aSel
      set j to contents of i
      
set tmpClass to class of j
      
      
if tmpClass = text item then
        set objText to object text of j
        
set fontName to font of object text of j
        
set fontSize to size of object text of j
        
        
–フォントを太らせる(ウェイトを上げる)
        
set fFamilyCount to countFontsInItsFamily(fontName) of me
        
if fFamilyCount = 2 then
          set newFont to incrementFontWeight(fontName, 1) of me
        else if fFamilyCount > 4 then
          set newFont to incrementFontWeight(fontName, 4) of me
        end if
        
        
set aCount to 1
        
set tList to splitByLInes(objText) of me
        
        
        
repeat with ii in tList
          set jj to contents of ii
          
set anOffset1 to offset of ":" in jj
          
set anOffset2 to offset of ":" in jj
          
          
if {anOffset1, anOffset2} is not equal to {0, 0} then
            if anOffset1 = 0 then
              set offRes to anOffset2
            else if anOffset2 = 0 then
              set offRes to anOffset1
            else
              set offRes to anOffset1
            end if
            
            
try
              set font of characters 1 thru offRes of paragraph aCount of object text of j to newFont
            end try
            
            
set aCount to aCount + 1
          end if
        end repeat
      end if
    end repeat
  end tell
end tell

–テキストを行ごとにParse
on splitByLInes(someText) — free to a good home
  set theString to current application’s NSString’s stringWithString:someText
  
set theList to theString’s componentsSeparatedByCharactersInSet:(current application’s NSCharacterSet’s newlineCharacterSet())
  
return theList as list
end splitByLInes

–フォントを太らせる。欧文フォントは考慮していない(別の方法で行う)
on incrementFontWeight(psFontName, incNum)
  set aFont to current application’s NSFont’s fontWithName:psFontName |size|:9.0
  
–> (NSCTFont) "HiraginoSans-W0 9.00 pt. P [] (0x12870af00) fobj=0x11b1e90d0, spc=1.98"
  
  
set fontM to current application’s NSFontManager’s sharedFontManager()
  
  
repeat incNum times
    set aFont to fontM’s convertWeight:true ofFont:aFont
  end repeat
  
  
return (aFont’s fontName()) as string
end incrementFontWeight

–指定フォントのファミリーに属するフォント数を取得
on countFontsInItsFamily(aPSName)
  set aFont to current application’s NSFont’s fontWithName:(aPSName) |size|:9.0
  
set aFamily to aFont’s familyName()
  
set fMan to current application’s NSFontManager’s sharedFontManager()
  
set fList to fMan’s availableMembersOfFontFamily:aFamily
  
return length of (fList as list)
end countFontsInItsFamily

★Click Here to Open This Script 

Posted in Font | Tagged 13.0savvy 14.0savvy 15.0savvy Keynote | Leave a comment

Numbersの選択範囲で空欄でないセルに指定の文字を入れる

Posted on 10月 17, 2024 by Takaaki Naganoya

Numbersの表を書き換えるためのAppleScriptです。表の選択範囲のうち、空欄でないセルに指定の文字(「●」)を入れます。

電子書籍掲載の「表」を作るのに、割と必要なものです。

「表」をまとめる段階では、

のように、生データをそのままセルに記載しておきますが、場所の利用効率でいえばそのまま生データで掲載していると無駄があります。

そこで、空欄ではないセルについては、「●」などの記号を記入することで、コンパクトな「表」に作り変える作業が発生します。本AppleScriptはそれを自動化したものです。

AppleScript名:選択範囲で空欄でないセルに指定の文字を入れる.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/10/17
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

script spd
  property uniqList : {}
end script

set strMark to "●"

tell application "Numbers"
  tell front document
    tell active sheet
      try
        set theTable to first table whose class of selection range is range
      on error
        display notification "Numbers: There is no selection"
        
return
      end try
      
      
tell theTable
        set (uniqList of spd) to cells of selection range
        
repeat with i in (uniqList of spd)
          set j to contents of i
          
set tmpVal to value of j
          
if tmpVal is not equal to missing value then
            set value of j to strMark
          end if
        end repeat
      end tell
    end tell
  end tell
end tell

★Click Here to Open This Script 

Posted in list Text | Tagged 13.0savvy 14.0savvy 15.0savvy Numbers | Leave a comment

Post navigation

  • Older posts
  • Newer posts

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

Google Search

Popular posts

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

Tags

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

カテゴリー

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

アーカイブ

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