Menu

Skip to content
AppleScriptの穴
  • Home
  • Products
  • Books
  • Docs
  • Events
  • Forum
  • About This Blog
  • License
  • 仕事依頼

AppleScriptの穴

Useful & Practical AppleScript archive. Click '★Click Here to Open This Script' Link to download each AppleScript

タグ: 10.14savvy

SafariでURLローディング完了検出

Posted on 8月 10, 2020 by Takaaki Naganoya

Safariで指定URLのページローディングを検出するAppleScriptです。

Safari 13で従来どおり、do javascriptコマンド経由で、

if (do JavaScript "document.readyState" in document 1) is "complete" then

などと処理させてみたら、URLが変更される前に”complete”が返ってきました。どうも、この処理が非同期実行されるのか、表示が反映される前に内部的にはページ遷移が完了しているようです。

現行のSafariにおいては、上記の処理ではページローディング完了検出が行えないことが判明。割と利用する機会が多く、重要な処理であるため、書き換えてみました。

いろいろ実験してみると、documentに新規URLを設定しても、すぐにはURLが変更されないようです。その割にAppleScriptの実行は完了したものとして次の行へと進んでしまいます。普通、こんな挙動を行うアプリケーションはないのですが(OCRで見たことがあったかも?)、ただ、逆にここで処理待ちすると問題が発生するケースもありそうです。

非同期モードと同期モードの両方が存在していて、明示的に選択できるとよいのですが、現状ではそうなっていません。

仕方がないので、旧URLから新URLへの切り替えをループで見張るという処理を書いてみたら、いい感じにローディング検出できました。

AppleScript名:SafariでURLローディング検出.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/08/09
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set aURL to "http://piyocast.com/as/"
openURLWithSafari(aURL)
set aText to getBodyTextFromSafariFrontWindow() of me

on openURLWithSafari(aURL as string)
  if aURL = "" then error "URL is blank"
  
try
    tell application "Safari"
      set d to count every window
      
if d = 0 then
        make new window
        
tell front document
          set URL to aURL
        end tell
      else
        tell front document
          set oldURL to URL
          
set URL to aURL
        end tell
      end if
      
      
detectPageLoaded(10, oldURL, aURL) of me
      
    end tell
  on error
    return false
  end try
end openURLWithSafari

on detectPageLoaded(timeout_value, oldURL, newURL)
  try
    repeat with i from 1 to (timeout_value * 5)
      tell application "Safari"
        tell front document
          set curURL to URL
        end tell
      end tell
      
      
if curURL = newURL then return
      
delay 0.2
    end repeat
  on error
    return false
  end try
  
  
return false
end detectPageLoaded

on getBodyTextFromSafariFrontWindow()
  –フレームを使っていないことが前提条件
  
tell application "Safari"
    return text of front document
  end tell
end getBodyTextFromSafariFrontWindow

★Click Here to Open This Script 

Posted in Internet URL | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy Safari | 1 Comment

githubの機能でMarkdownをhtmlに

Posted on 8月 9, 2020 by Takaaki Naganoya

githubのREST APIを呼び出して、Markdownファイルの内容をHTMLにレンダリングするAppleScriptです。


▲他のプログラムに処理部分を組み込んで表示させたところ(本ScriptはただHTMLレンダリングするだけで表示しません)

MacDownなどのアプリケーションでMarkdownファイルをオープンする方法とコードの行数はどっこいどっこいですが、MacDownを必要としないので、どこの環境でも(インターネット接続していれば)実行できます。

志の低さが目を覆わんばかりの出来で、実に少ない行数でレンダリングできるものの、Markdownをサーバーに送ってレンダリングしてもらうので、処理速度は遅いです。あるいは、githubのREST API処理サーバーにつねに負荷がかかっているとか。

AppleScript名:githubの機能でMarkdownをhtmlに.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/08/09
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

set mdFile to choose file of type {"net.daringfireball.markdown"} with prompt "Choose Markdown"
set mdStr to (read mdFile as «class utf8») as text

do shell script "curl -X POST https://api.github.com/markdown/raw -H ’Content-Type: text/plain’ -d " & quoted form of mdStr
set aString to result

return aString

★Click Here to Open This Script 

Posted in Markdown shell script | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy | Leave a comment

アラートダイアログ上のTable Viewで起動中のアプリケーションを選択 v3c

Posted on 8月 9, 2020 by Takaaki Naganoya

edama2さんからの投稿です。起動中のアプリケーション一覧をダイアログ表示するAppleScriptシリーズで、アプリケーションのアイコン画像やパス情報を表示し、単数/複数のアプリケーション選択ができます。

–> Download Script Bundle archive


▲単一選択(左)のダイアログと、複数選択(右)のダイアログ

タイトルは「アラートダイアログ上のTable Viewで起動中のアプリケーションを選択」
起動中のアプリケーションをiOSライクなレイアウトで表示します
Table Viewにカスタムセルビューを作って表現し、アプリの起動と終了を検知してリアルタイムで更新します
行数は12行に固定し、項目の複数選択がオプションで選べます

AppleScriptObjCフレームワークを呼び出すことにより、Xcod上で記述するAppleScriptアプリケーションのように、各種クラスのサブクラスを定義して利用しているScriptです。さまざまなScripterの技術が積み上がっている感じがして壮観ですが、ほとんどはedama2さんが長い時間をかけて積み上げてきたものの集大成といったものです。

本Scriptは途中で試行錯誤がいろいろあって、返り値がファイルパスだったりアプリケーションオブジェクトになったりと紆余曲折あって、現在の「アプリケーションオブジェクト」になりました。

ただ、実行中のアプリケーション自身を選択すると「current application」になってしまう点に注意が必要です。

AppleScript名:アラートダイアログ上のTable Viewで起動中のアプリケーションを選択 v3c
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppleScriptObjC"
use scripting additions

on run
  my testRun()
end run

on testRun()
  
  
set mes to "選択モードを指定してください"
  
set bOK to "複数選択"
  
set bOther to "単一選択"
  
set bCancel to "キャンセル"
  
set bList to {bCancel, bOther, bOK}
  
  
set userAction to display dialog mes buttons bList default button bOK cancel button bCancel with icon note
  
  
if userAction’s button returned is bOther then
    set isMultiple to false
  else if userAction’s button returned is bOK then
    set isMultiple to true
  end if
  
  
set aMainMes to "Select Runnning Application"
  
set aSubMes to "Sub Message"
  
set execButtonTitle to "OK😁"
  
set dateObj to my chooseRunningApplication:aMainMes subMes:aSubMes withMultipleSelections:(isMultiple) okTitle:execButtonTitle
  
end testRun

on chooseRunningApplication:(aMainMes as text) subMes:(aSubMes as text) withMultipleSelections:(isMultiple as boolean) okTitle:(execButtonTitle as text)
  
  
# Script Bundle内のResourcesフォルダを求める
  
set resourcePath to POSIX path of (path to me) & "Contents/Resources/"
  
set theBundle to current application’s NSBundle’s bundleWithPath:resourcePath
  
theBundle’s loadAppleScriptObjectiveCScripts()
  
  
# subClasses.scptを呼び出す
  
set DialogCore to current application’s AppDelegate’s new()
  
set fRes to DialogCore’s chooseRunningApplication:aMainMes subMes:aSubMes withMultipleSelections:isMultiple okTitle:execButtonTitle
  
  
if fRes is missing value then error number -128
  
return fRes as list
end chooseRunningApplication:subMes:withMultipleSelections:okTitle:

★Click Here to Open This Script 

AppleScript名:subClasses.scpt
#MARK: AppDelegate
script AppDelegate
  property parent : class "NSObject"
  
  
— IBOutlets
  
property theWindow : missing value
  
  
on applicationShouldTerminate:sender
    return current application’s NSTerminateNow
  end applicationShouldTerminate:
  
  
on applicationShouldTerminateAfterLastWindowClosed:sender
    return true
  end applicationShouldTerminateAfterLastWindowClosed:
  
  
on applicationWillFinishLaunching:aNotification
    log my testRun()
  end applicationWillFinishLaunching:
  
  
——————
  
#MARK: テスト
  
on testRun()
    –log "testRun"
    
    
set mes to "選択モードを指定してください"
    
set bOK to "複数選択"
    
set bOther to "単一選択"
    
set bCancel to "キャンセル"
    
set bList to {bCancel, bOther, bOK}
    
    
set userAction to display dialog mes buttons bList default button bOK cancel button bCancel with icon note
    
    
if userAction’s button returned is bOther then
      set isMultiple to false
    else if userAction’s button returned is bOK then
      set isMultiple to true
    end if
    
    
set aMainMes to "Select Runnning Application"
    
set aSubMes to "Sub Message"
    
set execButtonTitle to "OK😁"
    
set dateObj to my chooseRunningApplication:aMainMes subMes:aSubMes withMultipleSelections:(isMultiple) okTitle:execButtonTitle
    
    
return dateObj
  end testRun
  
  
#MARK: アラートダイアログでtableviewを表示
  
property _retrieve_data : missing value
  
on chooseRunningApplication:(aMainMes as text) subMes:(aSubMes as text) withMultipleSelections:(isMultiple as boolean) okTitle:(execButtonTitle as text)
    # reset
    
set my _retrieve_data to missing value
    
    
#
    
if aMainMes = "" then error "Dialog main message is missing"
    
    
#
    
set dataSourceList to {}
    
    
# OKボタンの文字
    
if execButtonTitle = "" then set execButtonTitle to "Execute"
    
    
set thisFileType to "com.apple.application-bundle"
    
    
#
    
set paramObj to {myMessage:aMainMes}
    
set paramObj to paramObj & {mySubMessage:aSubMes}
    
set paramObj to paramObj & {myDataSource:dataSourceList}
    
set paramObj to paramObj & {myType:thisFileType}
    
set paramObj to paramObj & {mySelectType:isMultiple}
    
set paramObj to paramObj & {myOKTitile:execButtonTitle}
    
    
my performSelectorOnMainThread:"raizeAlert:" withObject:paramObj waitUntilDone:true
    
    
if (my _retrieve_data) is missing value then error number -128
    
set retrieveData to my _retrieve_data
    
set my _retrieve_data to missing value
    
    
return retrieveData
  end chooseRunningApplication:subMes:withMultipleSelections:okTitle:
  
  
#MARK: Raize Alert
  
on raizeAlert:paramObj
    set mesText to paramObj’s myMessage as text
    
set infoText to paramObj’s mySubMessage as text
    
set dataSourceList to paramObj’s myDataSource as list
    
set myUTI to paramObj’s myType as text
    
set isMultiple to paramObj’s mySelectType as boolean
    
set okButton to paramObj’s myOKTitile as text
    
    
### set up view
    
#### data sourceにデータを追加
    
set theController to current application’s YKZArrayController’s alloc()’s initWithContent:dataSourceList
    
theController’s setMultipleSelections:isMultiple
    
theController’s setupView()
    
    
### アイコンの指定
    
–set aImage to current application’s NSWorkspace’s sharedWorkspace()’s iconForFileType:myUTI
    
    
set setSize to 128
    
set fontObj to current application’s NSFont’s systemFontOfSize:setSize
    
set aValue to {fontObj}
    
set aKey to {current application’s NSFontAttributeName}
    
set attributes to current application’s NSDictionary’s dictionaryWithObjects:aValue forKeys:aKey
    
    
set strEmoji to current application’s NSString’s stringWithString:"😎"
    
    
set newSizeObj to current application’s NSMakeSize(setSize, setSize)
    
tell current application’s NSImage’s alloc
      tell initWithSize_(newSizeObj)
        lockFocus()
        
strEmoji’s drawInRect:(current application’s NSMakeRect(0, 0, setSize, setSize)) withAttributes:attributes
        
unlockFocus()
        
set aImage to it
      end tell
    end tell
    
    
    
### set up alert
    
tell current application’s NSAlert’s new()
      addButtonWithTitle_(okButton)
      
addButtonWithTitle_("Cancel")
      
setAccessoryView_(theController’s _the_view)
      
setIcon_(aImage)
      
setInformativeText_(infoText)
      
setMessageText_(mesText)
      
tell |window|()
        setInitialFirstResponder_(theController’s _the_view)
      end tell
      
#### show alert in modal loop
      
if runModal() is (current application’s NSAlertSecondButtonReturn) then return
    end tell
    
    
### retrieve data
    
set (my _retrieve_data) to theController’s retrieveSelectItems()
    
return my _retrieve_data
  end raizeAlert:
end script

#MARK: – NSValueTransformer
script YKZURLToIcon
  property parent : class "NSValueTransformer"
  
property allowsReverseTransformation : false –>逆変換
  
property transformedValueClass : a reference to current application’s NSImage –>クラス
  
  
#変換処理
  
on transformedValue:fileURL
    if fileURL is missing value then return
    
    
set appPath to fileURL’s |path|()
    
set iconImage to current application’s NSWorkspace’s sharedWorkspace’s iconForFile:appPath
    
return iconImage
  end transformedValue:
end script

script YKZURLToDisplayedName
  property parent : class "NSValueTransformer"
  
property allowsReverseTransformation : false –>逆変換
  
property transformedValueClass : a reference to current application’s NSString –>クラス
  
  
#変換処理
  
on transformedValue:fileURL
    if fileURL is missing value then return
    
    
set appPath to fileURL’s |path|()
    
set displayedName to current application’s NSFileManager’s defaultManager’s displayNameAtPath:appPath
    
return displayedName
  end transformedValue:
end script

script YKZURLToPath
  property parent : class "NSValueTransformer"
  
property allowsReverseTransformation : false –>逆変換
  
property transformedValueClass : a reference to current application’s NSString –>クラス
  
  
#変換処理
  
on transformedValue:fileURL
    if fileURL is missing value then return
    
    
set appPath to fileURL’s |path|()
    
return appPath
  end transformedValue:
end script

script YKZURLToVersion
  property parent : class "NSValueTransformer"
  
property allowsReverseTransformation : false –>逆変換
  
property transformedValueClass : a reference to current application’s NSString –>クラス
  
  
#変換処理
  
on transformedValue:fileURL
    if fileURL is missing value then return
    
    
set appPath to fileURL’s |path|()
    
tell (current application’s NSBundle’s bundleWithURL:fileURL)
      tell its infoDictionary()
        set aVar to objectForKey_("CFBundleShortVersionString")
      end tell
    end tell
    
return aVar
  end transformedValue:
end script

#MARK: – Array Controller
script YKZArrayController
  property parent : class "NSArrayController"
  
  
#MARK: IBOutlets
  
property _the_view : missing value
  
property _table_view : missing value
  
  
#MARK: Property
  
property multipleSelections : false
  
property rowCount : 12
  
  
#MARK: 初期化
  
on initWithContent:aContent
    continue initWithContent:aContent
    
    
#通知の登録
    
tell current application’s NSWorkspace’s sharedWorkspace()’s notificationCenter()
      addObserver_selector_name_object_(me, "changed:", "NSWorkspaceDidLaunchApplicationNotification", missing value)
      
addObserver_selector_name_object_(me, "changed:", "NSWorkspaceDidTerminateApplicationNotification", missing value)
    end tell
    
    
return me
  end initWithContent:
  
  
  
#MARK: 戻り値
  
on retrieveSelectItems()
    set retrieveData to {}
    
    
set aIndexSet to my _table_view’s selectedRowIndexes()
    
set chooseItems to ((my _table_view’s dataSource())’s arrangedObjects()’s objectsAtIndexes:aIndexSet) as list
    
repeat with anItem in chooseItems
      set aPath to anItem’s fileURL
      
set retrieveData’s end to application (aPath as text)
    end repeat
    
    
return retrieveData as list
  end retrieveSelectItems
  
  
#MARK: viewの作成
  
on setupView()
    #Transformerの登録
    
set tNames to {}
    
set tNames’s end to "YKZURLToIcon"
    
set tNames’s end to "YKZURLToDisplayedName"
    
set tNames’s end to "YKZURLToPath"
    
set tNames’s end to "YKZURLToVersion"
    
repeat with aTransformer in tNames
      set theTransformer to current application’s class aTransformer’s new()
      (
current application’s NSValueTransformer’s setValueTransformer:theTransformer forName:aTransformer)
    end repeat
    
log multipleSelections
    
## NSTableView
    
tell current application’s NSTableView’s alloc()
      tell initWithFrame_(current application’s CGRectZero)
        –registerForDraggedTypes_({current application’s NSFilenamesPboardType, (my _data_type)})
        
setAllowsEmptySelection_(false)
        
setAllowsMultipleSelection_(multipleSelections)
        
setDataSource_(me)
        
setDelegate_(me)
        
setDoubleAction_("doubleAction:")
        
–setDraggingSourceOperationMask_forLocal_(current application’s NSDragOperationCopy, false)
        
setGridStyleMask_(current application’s NSTableViewSolidVerticalGridLineMask)
        
setSelectionHighlightStyle_(current application’s NSTableViewSelectionHighlightStyleRegular)
        
setTarget_(me)
        
setUsesAlternatingRowBackgroundColors_(true)
        
setHeaderView_(missing value)
        
setRowHeight_(50)
        
        
set thisRowHeight to rowHeight() as integer
        
set my _table_view to it
      end tell
    end tell
    
    
## NSTableColumn
    
### Columnの並び順を指定する
    
set keyrec to {column1:"Name"}
    
set keyDict to (current application’s NSDictionary’s dictionaryWithDictionary:keyrec)
    
    
set viewWidth to 400 –表示幅を変更
    
set columnsCount to keyDict’s |count|()
    
    
repeat with colNum from 1 to columnsCount
      
      
set keyName to "column" & colNum as text
      
set aTitle to (keyDict’s objectForKey:keyName)
      
      
tell (current application’s NSTableColumn’s alloc()’s initWithIdentifier:(colNum as text))
        tell headerCell()
          setStringValue_(aTitle)
          
set thisHeaderHeight to cellSize()’s height
        end tell
        
        
### バインディングのオプション
        
— ソートを無効にする
        
set anObj to (current application’s NSNumber’s numberWithBool:false)
        
set aKey to current application’s NSCreatesSortDescriptorBindingOption
        
set bOptions to (current application’s NSDictionary’s dictionaryWithObject:anObj forKey:aKey)
        
        
### 表示内容をNSArrayControllerにバインディング
        
bind_toObject_withKeyPath_options_(current application’s NSValueBinding, (my _table_view’s dataSource()), "arrangedObjects", bOptions)
        
        
set aTableColumn to it
      end tell
      
      
### Columnの横幅を調整
      
tell (my _table_view)
        addTableColumn_(aTableColumn)
      end tell
      
      
tell aTableColumn
        setWidth_(viewWidth)
      end tell
    end repeat
    
    
## NSScrollView
    
### Viewの高さを計算
    
set viewHeight to thisRowHeight * rowCount + thisHeaderHeight
    
    
#ダイアログ内のビューサイズを指定
    
set aScreen to current application’s NSScreen’s mainScreen()
    
set screenFrame to aScreen’s frame()
    
set aHeight to current application’s NSHeight(screenFrame)
    
set aWidth to current application’s NSWidth(screenFrame)
    
set maxHeight to aHeight * 0.845
    
set maxWidth to aWidth * 0.94
    
–log viewHeight
    
–log maxHeight
    
–set viewHeight to viewHeight + aSpace + sfHeight
    
if viewHeight > maxHeight then set viewHeight to maxHeight
    
if viewWidth > maxWidth then set viewWidth to maxWidth
    
if viewWidth < 360 then set viewWidth to 360
    
    
set vSize to current application’s NSMakeRect(0, 0, viewWidth, viewHeight)
    
    
### Viewを作成
    
tell current application’s NSScrollView’s alloc()
      tell initWithFrame_(vSize)
        setBorderType_(current application’s NSBezelBorder)
        
setDocumentView_(my _table_view)
        
setHasHorizontalScroller_(true)
        
setHasVerticalScroller_(true)
        
set my _the_view to it
      end tell
    end tell
    
    
my changed:me
    
    
# 1行目を選択
    
my setSelectionIndex:0
    
    
return my _the_view
  end setupView
  
  
#MARK: アプリケーションが切り替わった時
  
— tableViewを作成してから実行する
  
on changed:sender
    log "changed"
    
    
tell (my _table_view)’s dataSource()
      removeObjects_(arrangedObjects())
    end tell
    
    
#起動中のアプリケーション
    
set aList to current application’s NSWorkspace’s sharedWorkspace()’s runningApplications()
    
set sort to (current application’s NSSortDescriptor’s alloc()’s initWithKey:"localizedName" ascending:true selector:"caseInsensitiveCompare:")
    
set sortedList to aList’s sortedArrayUsingDescriptors:(sort as list)
    
    
repeat with anItem in (sortedList as list)
      #普通のアプリだけ
      
set aFlag to anItem’s activationPolicy() is current application’s NSApplicationActivationPolicyRegular
      
if aFlag then
        set theURL to anItem’s bundleURL()
        ((
my _table_view)’s dataSource()’s addObject:{fileURL:theURL})
      end if
      
    end repeat
    
  end changed:
  
  
  
#MARK: Data Source Overrides
  
on numberOfRowsInTableView:aTableView
    return (aTableView’s dataSource())’s content()’s |count|()
  end numberOfRowsInTableView:
  
  
  
on tableView:aTableView viewForTableColumn:aColumn row:aRow
    
    
set aCellView to aTableView’s makeViewWithIdentifier:"YKZTableCellView" owner:me
    
    
if aCellView is missing value then
      
      
set frameRect to current application’s NSMakeRect(0, 0, aColumn’s width, aTableView’s rowHeight())
      
set aCellView to current application’s YKZTableCellView’s alloc’s initWithFrame:frameRect
      
      
set anObj to "YKZURLToIcon"
      
set aKey to current application’s NSValueTransformerNameBindingOption
      
set bOptions to (current application’s NSDictionary’s dictionaryWithObject:anObj forKey:aKey)
      (
aCellView’s imageView())’s bind:(current application’s NSValueBinding) toObject:aCellView withKeyPath:"objectValue.fileURL" options:bOptions
      
      
set anObj to "YKZURLToDisplayedName"
      
set aKey to current application’s NSValueTransformerNameBindingOption
      
set bOptions to (current application’s NSDictionary’s dictionaryWithObject:anObj forKey:aKey)
      (
aCellView’s textField())’s bind:(current application’s NSValueBinding) toObject:aCellView withKeyPath:"objectValue.fileURL" options:bOptions
      
      
set anObj to "YKZURLToPath"
      
set aKey to current application’s NSValueTransformerNameBindingOption
      
set bOptions to (current application’s NSDictionary’s dictionaryWithObject:anObj forKey:aKey)
      (
aCellView’s pathTextField)’s bind:(current application’s NSValueBinding) toObject:aCellView withKeyPath:"objectValue.fileURL" options:bOptions
      
      
set anObj to "YKZURLToVersion"
      
set aKey to current application’s NSValueTransformerNameBindingOption
      
set bOptions to (current application’s NSDictionary’s dictionaryWithObject:anObj forKey:aKey)
      (
aCellView’s varTextField)’s bind:(current application’s NSValueBinding) toObject:aCellView withKeyPath:"objectValue.fileURL" options:bOptions
      
      
return aCellView
    end if
    
    
return missing value
  end tableView:viewForTableColumn:row:
  
  
  
# テーブル内のセルが編集できるか
  
on tableView:aTableView shouldEditTableColumn:aColumn row:aRow
    return false
  end tableView:shouldEditTableColumn:row:
  
  
#
  
on validateProposedFirstResponder:aResponder forEvent:aEvent
    log "validateProposedFirstResponder"
    
return true
    
    
set aBoolean to aResponder’s isKindOfClass:(current application’s NSTableCellView’s |class|())
    
if aBoolean as boolean then
      return true
    end if
    
    
return true
  end validateProposedFirstResponder:forEvent:
  
  
# テーブル内をダブルクリックしたらOKボタンを押す
  
on doubleAction:sender
    log "doubleAction"
    
## ヘッダをクリックした時は何もしない
    
if (sender’s clickedRow()) is -1 then return
    
    
set theEvent to current application’s NSEvent’s ¬
      keyEventWithType:(current application’s NSEventTypeKeyDown) ¬
        location:(current application’s NSZeroPoint) ¬
        
modifierFlags:0 ¬
        
timestamp:0.0 ¬
        
windowNumber:(sender’s |window|()’s windowNumber()) ¬
        
context:(current application’s NSGraphicsContext’s currentContext()) ¬
        
|characters|:return ¬
        
charactersIgnoringModifiers:(missing value) ¬
        
isARepeat:false ¬
        
keyCode:0
    current application’s NSApp’s postEvent:theEvent atStart:(not false)
  end doubleAction:
  
end script

#MARK: – NSTableCellView
script YKZTableCellView
  property parent : class "NSTableCellView"
  
  
property acceptsFirstResponder : true
  
  
property pathTextField : missing value
  
property varTextField : missing value
  
  
on initWithFrame:rect
    continue initWithFrame:rect
    
    
setAutoresizingMask_(current application’s NSViewWidthSizable)
    
    
–set myWidth to current application’s NSWidth(rect)
    
–set myHeight to current application’s NSHeight(rect)
    
    
# アイコン
    
tell current application’s NSImageView’s alloc
      tell initWithFrame_(current application’s NSMakeRect(12, 1, 48, 48))
        setImageScaling_(current application’s NSImageScaleProportionallyUpOrDown)
        
setImageAlignment_(current application’s NSImageAlignCenter)
        
my setImageView:it
        
my addSubview:it
      end tell
    end tell
    
    
# 表示名
    
tell current application’s NSTextField’s alloc
      tell initWithFrame_(current application’s NSMakeRect(66, 26, 280, 17))
        setBordered_(false)
        
setDrawsBackground_(false)
        
setEditable_(false)
        
setLineBreakMode_(current application’s NSLineBreakByTruncatingMiddle)
        
setFont_(current application’s NSFont’s boldSystemFontOfSize:13)
        
my setTextField:it
        
my addSubview:it
      end tell
    end tell
    
    
# パス
    
tell current application’s NSTextField’s alloc
      tell initWithFrame_(current application’s NSMakeRect(66, 6, 316, 17))
        setBordered_(false)
        
setDrawsBackground_(false)
        
setEditable_(false)
        
setLineBreakMode_(current application’s NSLineBreakByTruncatingMiddle)
        
setFont_(current application’s NSFont’s systemFontOfSize:11)
        
set my pathTextField to it
        
my addSubview:it
      end tell
    end tell
    
    
# バージョン
    
tell current application’s NSTextField’s alloc
      tell initWithFrame_(current application’s NSMakeRect(300, 24, 80, 17))
        setBordered_(false)
        
setDrawsBackground_(false)
        
setEditable_(false)
        
setFont_(current application’s NSFont’s systemFontOfSize:11)
        
setLineBreakMode_(current application’s NSLineBreakByTruncatingMiddle)
        
setAlignment_(current application’s NSRightTextAlignment)
        
set my varTextField to it
        
my addSubview:it
      end tell
    end tell
    
    
return me
  end initWithFrame:
end script

★Click Here to Open This Script 

Posted in dialog | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy AppDelegate NSAlert NSBundle NSDictionary NSFileManager NSFont NSFontAttributeName NSImage NSString NSValueTransformer NSWorkspace | Leave a comment

アラートダイアログでMarkdownをプレビュー v2

Posted on 8月 8, 2020 by Takaaki Naganoya

edama2さんから投稿していただいた、Markdown書類をダイアログ上でプレビューするScriptの第二弾です。

–> Download Script Bundle

WKWebViewではなくNSAttributedStringを使ってMarkdownを表示しています。
NSAttributedStringでhtmlが表示できるとわかってWKWebViewの代わりになるかな?と思ったんですが、javascriptは使えないので自前で実行し、NSAttributedStringに<hr>に相当するものがないのとWKWebViewとは描画結果が違うので、プレビューとして使うのはイマイチです。作っておいてなんですが…😢

本Scriptの見どころは2点。「Scriptバンドル内にJavaScriptのライブラリを突っ込んで呼び出しているところ」と、「Markdownを(HTML経由で)NSAttributedStringに変換してプレビューしている」ところです。

ひかえめな説明文とは裏腹に、ずいぶんと攻めているというか、野心的な実装です。

JavaScriptのライブラリをローカルに置く案についてはいろいろedama2さんと意見交換をしていたんですが、割とさらっと書いているところにショックを受けます。これだけでも、相当に試行錯誤が必要な内容なんですが、このレベルに追いつくためには相当の苦労が、、、

AppleScript名:アラートダイアログでMarkdownをプレビュー v2
use AppleScript
use framework "Foundation"
use scripting additions

on run
  my main()
end run

on main()
  set mes to "Markdownファイルを選択してください。"
  
set chooseItems to choose file of type {"net.daringfireball.markdown"} with prompt mes
  
  
#
  
set aScreen to current application’s NSScreen’s mainScreen()
  
set screenFrame to aScreen’s frame()
  
set aHeight to current application’s NSHeight(screenFrame)
  
set aWidth to current application’s NSWidth(screenFrame)
  
set aHeight to aHeight * 0.845
  
set aWidth to aWidth * 0.94 / 2
  
  
set paramObj to {}
  
set paramObj to paramObj & {myMessage:"Markdown preview"}
  
set paramObj to paramObj & {mySubMessage:"file : " & chooseItems’s POSIX path}
  
set paramObj to paramObj & {mdFile:chooseItems}
  
set paramObj to paramObj & {viewWidth:aWidth}
  
set paramObj to paramObj & {viewHeight:aHeight}
  
  
my performSelectorOnMainThread:"displayMarkdownPreview:" withObject:(paramObj) waitUntilDone:true
end main

# Markdownをダイアログで表示
on displayMarkdownPreview:paramObj
  set mesText to myMessage of paramObj as text
  
set infoText to mySubMessage of paramObj as text
  
set mdFile to (mdFile of paramObj) as alias
  
set viewWidth to (viewWidth of paramObj) as integer
  
set viewHeight to (viewHeight of paramObj) as integer
  
  
## MDを読み込む
  
set mdStr to (read mdFile as «class utf8») as text
  
  
## javascriptを読み込む
  
set mePath to path to me
  
set resPath to (mePath & "Contents:Resources:marked.min.js") as text
  
set jsStr to (read (resPath as alias) as «class utf8») as text
  
  
## javascriptでMarkdownをhtmlに変換
  
tell current application’s JSContext’s new()
    evaluateScript_(jsStr)
    
tell objectForKeyedSubscript_("marked")
      tell callWithArguments_({mdStr})
        set resultStr to toString()
      end tell
    end tell
  end tell
  
  
## HTMLを読み込む
  
set mePath to path to me
  
set resPath to (mePath & "Contents:Resources:index.html") as text
  
set htmlStr to (read (resPath as alias) as «class utf8») as text
  
  
## html内の文字を置き換え
  
set aString to current application’s NSString’s stringWithFormat_(htmlStr, resultStr) as text
  
log result
  
  
  
## NSAttributedString
  
set aString to current application’s NSString’s stringWithString:aString
  
set stringData to aString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
  
set aValue to {current application’s NSHTMLTextDocumentType, current application’s NSUTF8StringEncoding}
  
set aKey to {current application’s NSDocumentTypeDocumentAttribute, current application’s NSCharacterEncodingDocumentAttribute}
  
set aOption to current application’s NSDictionary’s dictionaryWithObjects:aValue forKeys:aKey
  
  
tell current application’s NSAttributedString’s alloc()
    tell initWithHTML_options_documentAttributes_(stringData, aOption, missing value)
      set attributedString to it
    end tell
  end tell
  
log result
  
  
# Create a TextView with Scroll View
  
set frameSize to current application’s NSMakeRect(0, 0, viewWidth, viewHeight)
  
tell current application’s NSTextView’s alloc()
    tell initWithFrame_(frameSize)
      setEditable_(false)
      
tell textStorage()
        appendAttributedString_(attributedString)
      end tell
      
set aView to it
    end tell
  end tell
  
tell current application’s NSScrollView’s alloc()
    tell initWithFrame_(frameSize)
      setDocumentView_(aView)
      
set theView to it
    end tell
  end tell
  
  
  
## アイコンの指定
  
set aImage to current application’s NSWorkspace’s sharedWorkspace()’s iconForFileType:"net.daringfireball.markdown"
  
  
## set up alert
  
tell current application’s NSAlert’s new()
    addButtonWithTitle_("Close")
    
setAccessoryView_(theView)
    
setIcon_(aImage)
    
setInformativeText_(infoText)
    
setMessageText_(mesText)
    
tell |window|()
      setInitialFirstResponder_(theView)
    end tell
    
### show alert in modal loop
    
if runModal() is (current application’s NSAlertSecondButtonReturn) then return
  end tell
end displayMarkdownPreview:

★Click Here to Open This Script 

そして、本Scriptをよくよく見回してみると、NSAttributedStringになっているのでPDFに変換するのがとても簡単でした。WkWebView上に表示したWebコンテンツをPDF化しようと試みているものの、うまくできていません。Blocks構文を必要とする機能であるため(なんでこんなものまでBlocks(非同期実行)必要なんだろ?)、AppleScriptからの呼び出しができないためです。Xcode上で他の言語をまじえて組めば不可能ではない気もしますが……

CSSがWeb表示用のものなので、PDF出力時には割とゆったり目で密度の低いレイアウトになってしまうものの、このCSS指定を別のものにできればけっこうMarkdown→PDFの変換を行う部品として使えるレベルになってくるのではないでしょうか。それはそれで、Scriptバンドル内に入れたCSSを指定するとか、Web上のどこかに印刷用のCSSをホスティングしておくなどの方法が必要になることでしょう。

Posted in dialog JavaScript Markdown | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy JSContext NSAlert NSAlertSecondButtonReturn NSAttributedString NSCharacterEncodingDocumentAttribute NSDictionary NSDocumentTypeDocumentAttribute NSScreen NSScrollView NSString NSTextView NSUTF8StringEncoding NSWorkspace | Leave a comment

choose running application AppleScript Library

Posted on 8月 7, 2020 by Takaaki Naganoya

起動中のアプリケーション一覧から、1つを選択するダイアログを提供するライブラリです。

「そういうのがない」という話があって「そういえばなかったね、大した内容じゃないけど」と、作ってみたものです。これで一番左に各アプリケーションのアイコン画像が表示できたら完璧なんですが、そこまではやりませんでした。

CPU Architectureを表示に含んでいるのが、ARMへの移行を目前に控えた時期っぽい感じでしょうか。本来は各アプリケーションへのパスをPOSIX pathで表示していたのですが、途中からなぜか表示されなくなって(不思議)、その機能は割愛しています。

–> Download chooseAppLib(To ~/Library/Script Libraries)

AppleScript名:sample.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/08/07
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
–  http://piyocast.com/as/asinyaye

use apSel : script "choose appLib"

set aRes to choose running application main message "Select a Running App" sub message "Sub Message" size {900, 200}
–> {"Safari", "Safari", "13.1.2", "x86_64"}

★Click Here to Open This Script 

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

起動中のアプリケーションから1つを選択

Posted on 8月 6, 2020 by Takaaki Naganoya

起動中のアプリケーション名一覧から1つを選択して返すダイアログを表示するAppleScriptです。

返り値はアプリケーション名/バンドルID、visibleなプロセスのみか、invisibleなものも含めるかという指定ができます。

choose applicationだと「起動中のアプリケーション」という指定ができないので、作ってみました。

AppleScript名:Choose Runnning App.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/08/06
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

set apName to chooseRunnningApp(true, false) of me
–> "Xcode"

set bID to chooseRunnningApp(true, true) of me
–> "com.apple.dt.Xcode"

on chooseRunnningApp(visibleAppF as boolean, bundleIDF as boolean)
  tell application "System Events"
    set pList to name of every process whose visible is visibleAppF
    
set bList to bundle identifier of every process whose visible is visibleAppF
  end tell
  
  
set cRes to choose from list pList with prompt "Select Runnning Application" without empty selection allowed
  
if cRes = false then error number -128 –Cancel
  
  
if bundleIDF = false then
    set apName to contents of first item of cRes
    
return apName
  else
    set apName to contents of first item of cRes
    
set apInd to retIndexNumInArray(pList, apName) of me
    
set bundleID to contents of item apInd of bList
    
return bundleID
  end if
end chooseRunnningApp

–Sequential Search in 1D Array
on retIndexNumInArray(aList, aTarget)
  script obj
    property list : aList
  end script
  
  
set aCount to 1
  
set hitF to false
  
  
repeat with i in obj’s list
    set j to contents of i
    
if aTarget = j then
      return aCount
    end if
    
    
set aCount to aCount + 1
  end repeat
  
  
if hitF = false then return 0
end retIndexNumInArray

★Click Here to Open This Script 

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

libPhoneNumbermacOSで電話番号のバリデーション v2

Posted on 7月 30, 2020 by Takaaki Naganoya

Googleがgithubで公開しているlibPhoneNumberをmacOSなどに向けてポーティングした「libPhoneNumbermacOS」を呼び出して電話番号の妥当性チェックを行うAppleScriptです。

github上のプロジェクトをダウンロードしてXcodeでビルドすれば、普通にCocoa Frameworkを作れるので各自ご自分でビルドしてください。実行は、macOS 10.14以降であればScript Debuggerが必要です(Xcode上で作成するAppleScriptアプリケーションであれば、とくにScript Debuggerは必要ありません。XcodeのAppleScript編集機能が低すぎて結局Script Debuggerは必要になるのですが)。

これから先、macOSやAppleScriptも電話機能や電話番号との付き合いが増えてくるはずなので、電話番号の妥当性チェックは必要になることでしょう。

libPhoneNumberには電話番号の妥当性チェックの機能のほか、電話番号から位置情報を求められるようですが、Blocks構文の記述が必要なのでソース自体に手を加える必要がありそうなので手を出していません。

AppleScript名:libPhoneNumbermacOSで電話番号のバリデーション v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/07/29
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "libPhoneNumbermacOS" –https://github.com/iziz/libPhoneNumber-iOS
use scripting additions

property NBEPhoneNumberFormatE164 : 0
property NBEPhoneNumberFormatINTERNATIONAL : 1
property NBEPhoneNumberFormatNATIONAL : 2
property NBEPhoneNumberFormatRFC3966 : 3

set pUtil to current application’s NBPhoneNumberUtil’s alloc()’s init()

set {myPhone, pRes} to pUtil’s parse:"03-5297-2311" defaultRegion:"JP" |error|:(reference) –JPNICの電話番号
if pRes is not equal to missing value then return

set vRes to (pUtil’s isValidNumber:myPhone) as boolean

–E164形式(ITU-T(国際電気通信連合 電気通信標準化セクター) E.164勧告)
set vResE164 to pUtil’s format:myPhone numberFormat:(NBEPhoneNumberFormatE164) |error|:(reference)
log {"E164", vResE164}
–> {"E164", {(NSString) "+81352972311", missing value}}

–国際電話形式
set vResINTN to pUtil’s format:myPhone numberFormat:(NBEPhoneNumberFormatINTERNATIONAL) |error|:(reference)
log {"INTERNATIONAL", vResINTN}
–> {"INTERNATIONAL", {(NSString) "+81 3-5297-2311", missing value}}

–国内形式
set vResNATN to pUtil’s format:myPhone numberFormat:(NBEPhoneNumberFormatNATIONAL) |error|:(reference)
log {"NATIONAL", vResNATN}
–> {"NATIONAL", {(NSString) "03-5297-2311", missing value}}

–RFC3966形式
set vResRFC3966 to pUtil’s format:myPhone numberFormat:(NBEPhoneNumberFormatRFC3966) |error|:(reference)
log {"RFC3966", vResRFC3966}
–> {"RFC3966", {(NSString) "tel:+81-3-5297-2311", missing value}}

set cRes to (pUtil’s extractCountryCode:"+81-3-5297-2311" nationalNumber:(missing value)) as integer
–> 81

set nationalNumber to missing value
set {cRes, nRes} to (pUtil’s extractCountryCode:"+81-3-5297-2311" nationalNumber:(reference))

return {cRes as integer, nRes as string}
–> {81, "-3-5297-2311"}

★Click Here to Open This Script 

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

アラートダイアログでMarkdownをプレビュー

Posted on 7月 29, 2020 by Takaaki Naganoya

edama2さんからの投稿です。実際に動かして「こんな素朴な記述でMarkdownのプレビューができるのか?!」とぶっ飛びましたが、箱庭グラフ表示シリーズ(JavaScriptのライブラリに描画丸投げ)と同様、外部のJavaScriptライブラリを呼んで表示しています。

→ Download archive

タイトルは「アラートダイアログでMarkdownをプレビュー」
アラートダイアログ上でMarkdownのプレビュー表示をします
中身はhtml内のjavascriptで変換してWkWebViewで表示しているだけなので今更目新しいこともありません
一応うまく動いていると思いますが、いろんなパターンを試したわけじゃないのでちょっと不安です

技術的に見所が多すぎて困るぐらいの内容です。ちょろっと流せるぐらいの規模ではありません。

JavaScriptのライブラリでMarkdownのプレビューが行えるというのは、割と盲点でした。グラフやらアニメーションやらはさんざんJavaScriptを呼び出して表示させていましたが、Markdownのプレビューまで行えるとは。

主に、Markdownのレンダリング系のフレームワークとか、AppleがXcodeに添付したMarkdownのプレビュー機能あたりが活用できないか調べていたことはありましたが、CDN上のJavaScriptを呼び出してプレビューというのはなかなか強力です。

さらに、本Scriptはblocks構文が必要なAPIに対してパラメータにmissing valueを指定することで呼び出せています。

blocks構文のパラメータにヌル文字やmissing valueを指定することで誤魔化せるケースがあることはedama2さんと話して知っていましたが、実例として提示されたのはこれがはじめてでしょう(macscripter.netでも見かけない)。

また、箱庭WebViewダイアログ系のプログラムが「スクリプトエディタ上から実行すると、実行後にウィンドウのオブジェクトがメモリ上に残ったままになる」という問題を抱えていた点を解決……はできていないですね。Appletで動かせば解決できるのと、親プロセス(スクリプトエディタやScript Debugger)が終了するとまとめて消えるので、その方向でなんとか対処を。


▲添付のサンプルMarkdown書類をプレビューしたところ。表のレンダリングができている点に驚き


▲実際に書籍用にメンテナンスしているMarkdown書類をプレビュー。applescript://のURLリンクも有効。インラインHTMLの類いも使える


▲箱庭Webダイアログの負の遺産、実行するたびにたまるゴミプロセス。これで解消なるか?!→それは無理でした

ちなみに、CotEditorのスクリプトメニューに組み込んで実行してみましたが、ネットワークへのアクセスが必要なためCotEditor側のセキュリティポリシーと合わずに実行できませんでした。 → できました。WebKitをuseし忘れていただけのようです(CDN上のライブラリで円グラフ表示できているので、逆にできないのがおかしいと気づきました)。

macOS標準装備のスクリプトメニュー内から、Applet形式に書き出したAppleScriptを呼び出すスタイルにしたら実行できました。

AppleScript名:アラートダイアログでMarkdownをプレビュー
use AppleScript
use framework “Foundation”
use scripting additions

on run
  my main()
end run


on main()
  set mes to “Markdownファイルを選択してください。”
set chooseItems to choose file of type {“net.daringfireball.markdown”} with prompt mes


  #
set aScreen to current application’s NSScreen’s mainScreen()
set screenFrame to aScreen’s frame()
set aHeight to current application’s NSHeight(screenFrame)
set aWidth to current application’s NSWidth(screenFrame)
set aHeight to aHeight * 0.845
set aWidth to aWidth * 0.94 / 2


  set paramObj to {}
set paramObj to paramObj & {myMessage:“Markdown preview”}
set paramObj to paramObj & {mySubMessage:“file : “ & chooseItems’s POSIX path}
set paramObj to paramObj & {mdFile:chooseItems}
set paramObj to paramObj & {viewWidth:aWidth}
set paramObj to paramObj & {viewHeight:aHeight}


  my performSelectorOnMainThread:“displayMarkdownPreview:” withObject:(paramObj) waitUntilDone:true
end main


# Markdownをダイアログで表示
on displayMarkdownPreview:paramObj
  set mesText to myMessage of paramObj as text
set infoText to mySubMessage of paramObj as text
set mdFile to (mdFile of paramObj) as alias
set viewWidth to (viewWidth of paramObj) as integer
set viewHeight to (viewHeight of paramObj) as integer


  ## HTMLを読み込む
set mePath to path to me
set resPath to (mePath & “Contents:Resources:index.html”) as text
set htmlStr to (read (resPath as alias) as «class utf8») as text


  ## MDを読み込む
set mdStr to (read mdFile as «class utf8») as text


  ## MD内に改行があるとうまく読み込まれないので改行を置き換え
set mdStr to current application’s NSString’s stringWithString:mdStr
set mdStr to mdStr’s stringByReplacingOccurrencesOfString:(linefeed) withString:“\\n”
set mdStr to mdStr’s stringByReplacingOccurrencesOfString:“’” withString:“\\’”


  ## html内の文字を置き換え
set aString to current application’s NSString’s stringWithFormat_(htmlStr, mdStr) as text
log result


  ## baseURL
set aPath to mdFile’s POSIX path
set baseURL to current application’s NSURL’s fileURLWithPath:aPath
set baseURL to baseURL’s URLByDeletingLastPathComponent()


  ##
set aConf to current application’s WKWebViewConfiguration’s new()
tell current application’s WKUserContentController’s new()
    aConf’s setUserContentController:it
  end tell


  ## WebViewを作成&読み込み
set frameSize to current application’s NSMakeRect(0, 0, viewWidth, viewHeight)
tell current application’s WKWebView’s alloc()
    tell initWithFrame_configuration_(frameSize, aConf)
      setNavigationDelegate_(me)
setUIDelegate_(me)
loadHTMLString_baseURL_(aString, baseURL)
set theView to it
    end tell
  end tell


  ## アイコンの指定
set aImage to current application’s NSWorkspace’s sharedWorkspace()’s iconForFileType:“net.daringfireball.markdown”


  ## set up alert
tell current application’s NSAlert’s new()
    addButtonWithTitle_(“Close”)
setAccessoryView_(theView)
setIcon_(aImage)
setInformativeText_(infoText)
setMessageText_(mesText)
tell |window|()
      setInitialFirstResponder_(theView)
    end tell
### show alert in modal loop
if runModal() is (current application’s NSAlertSecondButtonReturn) then return
  end tell


  ##後始末
theView’s stopLoading()
set js to “window.open(’about:blank’,’_self’).close();”
theView’s evaluateJavaScript:js completionHandler:(missing value)
set theView to missing value
end displayMarkdownPreview:

★Click Here to Open This Script 
Posted in dialog JavaScript Markdown | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy | Leave a comment

画像の空白判定プログラムの検証

Posted on 7月 28, 2020 by Takaaki Naganoya

画像の全ピクセルが白かどうかチェックする処理ルーチンは、必要に迫られて作ったものです。しかも、高速処理が求められます。

アイコン画像よりも小さな、たかだか1024 x 768ピクセルの画像であっても、全画素の空白をループでチェックしたら78万ピクセルあるわけで、地道に画像に対して座標を指定しつつ78万回カラーチェックを行うのは現実的ではありません。

作成した空白チェックのルーチンは3つ。

(1)Photoshopの明度ヒストグラム機能を利用するもの

Adobe Photoshopの明度ヒストグラム機能を利用するもの。はるかかなた昔から使っており、信頼性も高かったものの実行にはPhotoshopを要するため、どこでも同様に実行するわけにはいきませんでした。HTMLをPDF出力させたときに、無駄な空白ページが末尾にできることをチェックしたりと、重要な処理に使ってきました(プリントアウト時に無駄紙を省けるとか。枚数が増えると割と切実な問題です)。

(2)GPUImage.frameworkを利用するもの

オープンソースのGPUImage.framework(Objective-Cで書かれた初代のGPUImage 1)を呼び出して明度ヒストグラム計算を実行。スピード、コストなどの面で問題を解決できていますが、GPUImage自体がSwiftで書き直されたり、OpenGLからMetal向けに書き直されたりで、GPUImage 1自体の継続性については問題がある状態です。

(3)AppleScriptだけで書き直したもの

Cocoaの機能を利用して画像の空白チェックを実現。元画像のコピーを作って、白くぬりつぶして、オリジナル画像との照合を行う。同じであれば空白画像、同じでなければ空白画像ではないという判定を行います。4K解像度以下であれば最速。

そして、今後(1)〜(3)のどれを使い続けるべきかを、macOS 10.14.6でチェックしてみました。テストプログラムでは空白画像検出時にtrueを、空白でない場合にはfalseを返す仕様に。

(1) (2) (3)
1024x768_1_black.png false true false
4K_3840x2160_1_pixel_black.psd false true false
1x1_white.png true false true

結果は、(1)と(3)が同じ結果を返しました。(2)だけ結果が異なるケースが見られたため、Photoshopの有無に左右されないことを考えると(3)が有力といえます。

実際に、Mac App Store上で販売しているPDF差分検出ツール「Double PDF」ではv2.0からはGPUImageの利用をやめ、処理内容をすべてAppleScriptだけで行うことでスピードアップを果たしています。

この空白画像の検出以外でどの程度GPUImage 1がmacOS 10.14以降の環境で使えるか、使えないかは別のテストが必要でしょう。

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

カラーリストの処理

Posted on 7月 27, 2020 by Takaaki Naganoya

カラーリストまわりの情報を取得するAppleScriptです。

カラーピッカーで取得できる各種色セットの内容を取得できたりと、割と使いでがあります。

AppleScript名:使用可能なカラーリスト名称一覧を取得.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/07/26
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

set cList to ((current application’s NSColorList’s availableColorLists())’s valueForKeyPath:"name") as list
–> {"Apple", "System", "World", "Europe", "Japanese", "Scrivener", "AquaPro", "Crayons", "Web セーフカラー"}

★Click Here to Open This Script 

AppleScript名:指定名称のカラーリストに登録されているNSColorを配列で取得.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/07/26
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

set aColList to (current application’s NSColorList’s colorListNamed:"Crayons")

set kList to (aColList’s allKeys()) as list
set colList to {}
repeat with i in kList
  set j to contents of i
  
set cVal to (aColList’s colorWithKey:j)
  
set the end of colList to cVal
end repeat

return colList

★Click Here to Open This Script 

Posted in Color System | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSColor NSColorList | Leave a comment

CPUタイプを取得

Posted on 7月 23, 2020 by Takaaki Naganoya

実行中のMacのCPUタイプを取得するAppleScriptです。ARM Macではまた別の結果が返ってくることでしょう。

追記:
匿名希望のDTKユーザー1号さんから教えてもらいました。

set cpuStr to CPU type of (system info)

のDTKマシン上での実行結果は、Rosetta2環境では「Intel」、ARMネイティブ環境では「ARM」と返ってくるのだとか。1号さんに念を押されたのですが、まだβ段階なので将来的に同じ値が返ってくるかは保証できないということです。

正直、予想していたのは「ARM」か「Apple」かの2択だったので納得な内容です(詳細なモデル識別子をスペースを付けて出力してこないことも予想ずみ)。

おそらくですが、Mac用のApple Silicon(ARM)は複数タイプのもの(ノート用、外部GPUを用いるハイエンドデスクトップ用)が出てくるでしょうし、世代ごとにモデル名が変わっていくことでしょう(A14XBionicとか)。それでも、CPUタイプが識別できることの意義は、

「ARM Mac上なのにRosetta2環境で動作しているからパフォーマンスが落ちるかもしれないよ?」

といった警告メッセージを表示するぐらいでしょうか。AppleScriptのsystem infoコマンドで得られるCPU typeについては、Intel Macになってもながらく「Intel 80486」といったいい加減な名前を返してくるぐらいだったので、アーキテクチャ判定以上の情報を得られるという期待は持たないほうがよいでしょう。逆を言えば、Intel 80486の時代にすでにその定数が内部で定義されていた(Intel CPU上でMacOSを動作させるプロジェクトがあった)という証拠ともいえます(Star Trek projectの時代?)。

--macOS 10.14.6+Intel Mac (system info)
{AppleScript version:"2.7", AppleScript Studio version:"1.5.3", system version:"10.14.6", short user name:"me", long user name:"Takaaki Naganoya", user ID:504, user locale:"en_JP", home directory:alias "Machintosh HD:Users:me:", boot volume:"Machintosh HD", computer name:"MBPretina", host name:"MBPretina.local", IPv4 address:"xx.xx.xx.xx", primary Ethernet address:"xx:xx:xx:xx:xx:xx", CPU type:"Intel 80486", CPU speed:2600, physical memory:8192}

--macOS 10.15.6+Intel Mac (system info)
{AppleScript version:"2.7", AppleScript Studio version:"1.5.3", system version:"10.15.6", short user name:"me", long user name:"Takaaki Naganoya", user ID:502, user locale:"ja_JP", home directory:alias "Macintosh HD:Users:me:", boot volume:"Macintosh HD:", computer name:"YasMBP", host name:"YasMBP.local", IPv4 address:"xx.xx.xx.xx", primary Ethernet address:"xx:xx:xx:xx:xx:xx", CPU type:"Intel 80486", CPU speed:2700, physical memory:8192}

--macOS 11.0+Intel Mac (system info)
{AppleScript version:"2.7", AppleScript Studio version:"1.5.3", system version:"11.0", short user name:"me", long user name:"Takaaki Naganoya", user ID:501, user locale:"ja_JP", home directory:alias "Macintosh HD:Users:me:", boot volume:"Macintosh HD:", computer name:"Mac mini 2014", host name:"MacMini2014.local", IPv4 address:"xx.xx.xx.xx", primary Ethernet address:"xx:xx:xx:xx:xx:xx", CPU type:"Intel x86-64h Haswell", CPU speed:2600, physical memory:16384}
AppleScript名:CPUタイプを取得.scpt
set aRes to getCPUType() of me
–> "PowerPC"
–> "Intel"

on getCPUType()
  set cpuStr to CPU type of (system info)
  
set aInd to (offset of " " in cpuStr)
  
if aInd = 0 then return cpuStr
  
set cpuStr to text 1 thru (aInd – 1) of cpuStr
  
return cpuStr
end getCPUType

★Click Here to Open This Script 

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

HandBrakeがAppleScriptに対応したのはいいんだけど……

Posted on 7月 23, 2020 by Takaaki Naganoya

リッピングやメディアトランスコーディングを行うソフトウェア「HandBrake」がAppleScriptに対応するという話を少し前に聞いていました。今日確認したらアップデートしてAppleScript用語辞書がついていることを確認。

ただし……

AppleScript用語辞書がまるっきりダメです。使いものにならない用語ばかりで、何かよそのアプリケーションの用語辞書をコピーしただけのようです。

この辞書では、アプリケーションを起動してバージョンなどの情報を確認するのと、指定のファイルをオープンするぐらいしかできません。キューに指定ムービーを追加するとか、エンコーディング形式を指定するとか、最重要コマンドである「start」といった用語も何もありません。

正直、この出来だと「HandBrake CLI」経由でHandBrakeのコア機能を呼び出した方が使いでがあると思います。

AppleScript名:HandBrakeの情報を取得.scpt
tell application "HandBrake"
  properties
  
–> {frontmost:false, class:application, name:"HandBrake", version:"1.3.3"}
end tell

★Click Here to Open This Script 

AppleScript名:handBrakeで指定ファイルをオープン.scpt
set aFile to choose file

tell application "HandBrake"
  open aFile
end tell

★Click Here to Open This Script 

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

インライン画像つきスタイル付きテキストの作成 v1b

Posted on 7月 22, 2020 by Takaaki Naganoya

スタイル付きテキストの中に画像を入れるAppleScriptです。

–> Download Script bundle with Library


▲上左:macOS 10.13、上右:macOS 10.14、下左:macOS 10.15

画像をNSTextAttachmentに入れてNSAttributedStringに追加するのが本来の処理方法ですが、macOS 10.13と10.14ではNSTextAttachment中の画像が上下逆になるというバグを見つけてしまいました(10.15以降では修正されています)。

ただし、これは全言語共通のバグなので回避方法が紹介されていました。NSTextAttachmentCell経由で画像を突っ込む方法が紹介されています。

これにもとづいて修正+Shane Stanleyからのアドバイスで書き換えたのがこのScriptです。

AppleScript名:インライン画像つきスタイル付きテキストの作成 v1b.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/07/22
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

set anImage to (current application’s NSImage’s imageNamed:(current application’s NSImageNameComputer))

set anAttachment to current application’s NSTextAttachment’s alloc()’s init()
anAttachment’s attachmentCell()’s setImage:anImage
anAttachment’s setBounds:(current application’s NSMakeRect(0, 0, 32, 32))

set img1Str to current application’s NSAttributedString’s attributedStringWithAttachment:anAttachment

set anAssrStr to makeRTFfromParameters("Piyomaru Software", 32, "Times") of me

img1Str’s appendAttributedString:anAssrStr

dispAttrStr("Main message", "Sub message", img1Str, 400, 80) of tvLib

on makeRTFfromParameters(aStr as string, aFontSize as real, aFontName as string)
  set aVal1 to current application’s NSFont’s fontWithName:aFontName |size|:aFontSize
  
set aKey1 to (current application’s NSFontAttributeName)
  
  
set aVal2 to current application’s NSColor’s blackColor()
  
set aKey2 to (current application’s NSForegroundColorAttributeName)
  
  
set aVal3 to 0
  
set akey3 to (current application’s NSKernAttributeName)
  
  
set keyList to {aKey1, aKey2, akey3}
  
set valList to {aVal1, aVal2, aVal3}
  
set attrsDictionary to current application’s NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList
  
  
set attrStr to current application’s NSMutableAttributedString’s alloc()’s initWithString:aStr attributes:attrsDictionary
  
return attrStr
end makeRTFfromParameters

★Click Here to Open This Script 

Posted in dialog RTF | Tagged 10.13savvy 10.14savvy 10.15savvy | Leave a comment

CPUのバイトオーダーを取得

Posted on 7月 22, 2020 by Takaaki Naganoya

実行中のコンピュータ(多分Mac)のCPUのバイトオーダーを取得するAppleScriptです。

これまで、MacのCPUは68k(Big Endian)→PowerPC(Big Endian)→Intel(Little Endian)と来て、次はARM。

一応、IntelとArmは同じLittle Endianなので問題は少ないはずですが、ARM DTKをお持ちの方は試してコッソリ教えていただけるとありがたいです。

この情報がAppleScriptで取得できると何か「いいこと」があるかですが、別にメリットはありません。

ただ、CPUの名前が取得できると、処理速度を推測できてよいでしょう。Intel CPUに対してApple Silicon(ARM)がどの程度のパフォーマンスを発揮できるのか、実機が出てこないとわかりませんけれども。

PowerPCからIntelに変わったときには、先読みが深くなったためか(?)連番ファイルの処理で問題が出て、書き直しが必要になったことがありました。IntelからARMへの移行時には、iOS系のアプリケーションの操作を試みて問題が出たり、セキュリティ上の制限にひっかかったりすることでしょう。

AppleScript名:CPUのバイトオーダーを取得.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/07/22
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

set bRes to getByteOrder() of me
–> true –Little Endian

on getByteOrder()
  set aRes to do shell script "sysctl -n hw.byteorder"
  
if aRes = "4321" then
    return false –Big Endian (PowerPC)
  else
    return true –Little Endian (Intel, Arm..maybe)
  end if
end getByteOrder

★Click Here to Open This Script 

Shane Stanleyからの投稿です。こっちの方がシンプルでいいですね。

AppleScript名:CPUのバイトオーダーを取得 v2.scptd
—
–  Created by: Shane Stanley
–  Created on: 2020/07/23
—

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

set bRes to current application’s NSHostByteOrder() — 1 = little endian, 2 = big endian, 0 = unknown

★Click Here to Open This Script 

Posted in shell script System | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSHostByteOrder | Leave a comment

アラートダイアログ上に印刷対象ページ一覧を表示して対象ページを指定(v2)

Posted on 7月 17, 2020 by Takaaki Naganoya

アラートダイアログ上にボタンタイプのチェックボックスを並べて、選択したボタンのタイトルを選択するAppleScriptです。

書類の印刷対象を、こまかくページ指定するために作成した部品です。

ヘルプボタンにより、全ボタンの選択/非選択状態を作り出せます。


▲macOS 15.3上で、本Scriptの改修版を動かしたところ、クリックした箇所が見てわかるようになった

AppleScript名:アラートダイアログ上に印刷対象ページ一覧を表示して対象ページを指定 v2.scpt
— Created 2020-07-17 by Takaaki Naganoya
— Modified 2024-12-23 by Takaaki Naganoya
— 2020-2024 Piyomaru Software

set aRes to selectByCheckbox("Select each printout page", "Selected pages are the target", 64, "Helvetica") of chooseSeqNum

script chooseSeqNum
  
  
use AppleScript version "2.5"
  
use scripting additions
  
use framework "Foundation"
  
use framework "AppKit"
  
  
property NSFont : a reference to current application’s NSFont
  
property NSView : a reference to current application’s NSView
  
property NSAlert : a reference to current application’s NSAlert
  
property NSColor : a reference to current application’s NSColor
  
property NSButton : a reference to current application’s NSButton
  
property NSOnState : a reference to current application’s NSOnState
  
property NSOffState : a reference to current application’s NSOffState
  
property NSTextField : a reference to current application’s NSTextField
  
property NSButtonTypeToggle : a reference to current application’s NSButtonTypeToggle
  
property NSButtonTypePushOnPushOff : a reference to current application’s NSButtonTypePushOnPushOff
  
property NSMutableArray : a reference to current application’s NSMutableArray
  
property NSButtonTypeOnOff : a reference to current application’s NSButtonTypeOnOff
  
property NSMutableDictionary : a reference to current application’s NSMutableDictionary
  
property NSRunningApplication : a reference to current application’s NSRunningApplication
  
property NSFontAttributeName : a reference to current application’s NSFontAttributeName
  
property NSKernAttributeName : a reference to current application’s NSKernAttributeName
  
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
  
  
property theResult : 0
  
property returnCode : 0
  
property cList : {} –Checkbox button object array
  
property bArray : {}
  
  
  
on selectByCheckbox(aMainMessage, aSubMessage, aMaxPage, myFont)
    set paramObj to {myMessage:aMainMessage, mySubMessage:aSubMessage, maxPage:aMaxPage, fontName:myFont}
    
–my chooseItemByCheckBox:paramObj –for Debugging
    
my performSelectorOnMainThread:"chooseItemByCheckBox:" withObject:(paramObj) waitUntilDone:true
    
–> {1, 3, 5, 7, 9, 11}
    
return cList
  end selectByCheckbox
  
  
on chooseItemByCheckBox:(paramObj)
    set aMainMes to (myMessage of paramObj) as string
    
set aSubMes to (mySubMessage of paramObj) as string
    
set aMaxPage to (maxPage of paramObj) as integer
    
set aFontName to (fontName of paramObj) as string
    
    
set cList to {}
    
    
set colNum to 10
    
set rowNum to (aMaxPage div 10) + 1
    
set aLen to (colNum * rowNum)
    
    
set aButtonCellWidth to 56
    
set aButtonCellHeight to 40
    
    
set viewWidth to aButtonCellWidth * colNum
    
set viewHeight to aButtonCellHeight * (rowNum + 1)
    
    
–define the matrix size where you’ll put the radio buttons
    
set matrixRect to current application’s NSMakeRect(0.0, 0.0, viewWidth, viewHeight)
    
set aView to NSView’s alloc()’s initWithFrame:(matrixRect)
    
    
set aCount to 1
    
set aFontSize to 24
    
set bArray to current application’s NSMutableArray’s new()
    
    
–Make Header (Month, Year)
    
set aCalList to makeSeqNumList(1, aMaxPage) of me
    
set aCount to 1
    
    
    
–Make Calendar (Calendar Body)
    
repeat with y from 1 to rowNum
      repeat with x from 1 to colNum
        –try
        
set j to (contents of item aCount of aCalList)
        
set tmpB to (NSButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(((x – 1) * aButtonCellWidth), ((aLen – aCount) div colNum) * aButtonCellHeight, aButtonCellWidth, aButtonCellHeight)))
        
        (
tmpB’s setTitle:(j as string))
        (
tmpB’s setFont:(NSFont’s fontWithName:aFontName |size|:aFontSize))
        
–set attrTitle to makeRTFfromParameters((aCount as string), aFontName, aFontSize, 0, (aFontSize * 1.2)) of me
        
–(tmpB’s setAttributedTitle:(attrTitle))
        (
tmpB’s setShowsBorderOnlyWhileMouseInside:true)
        (
tmpB’s setAlignment:(current application’s NSCenterTextAlignment))
        (
tmpB’s setEnabled:(j ≠ ""))
        (
tmpB’s setTarget:me)
        (
tmpB’s setAction:("clicked:"))
        (
tmpB’s setButtonType:(NSButtonTypeToggle))
        (
tmpB’s setHidden:(j = ""))
        
        (
tmpB’s setTag:(j))
        (
bArray’s addObject:tmpB)
        
        
set aCount to aCount + 1
        
if aCount > aMaxPage then exit repeat
        
–end try
      end repeat
      
if aCount > aMaxPage then exit repeat
    end repeat
    
    
–Select the first radio button item
    
–(tmpArray’s objectAtIndex:0)’s setState:(current application’s NSOnState)
    
set my theResult to {}
    
    (
aView’s setSubviews:bArray)
    
    
— set up alert  
    
set theAlert to NSAlert’s alloc()’s init()
    
tell theAlert
      its setMessageText:aMainMes
      
its setInformativeText:aSubMes
      
its addButtonWithTitle:"OK"
      
its addButtonWithTitle:"Cancel"
      
its setAccessoryView:aView
      
      
–for Help Button
      
its setShowsHelp:(true)
      
its setDelegate:(me)
      
    end tell
    
    
— show alert in modal loop
    
NSRunningApplication’s currentApplication()’s activateWithOptions:0
    
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
    
if (my returnCode as number) = 1001 then error number -128
    
    
set bNumList to (bArray’s valueForKeyPath:"state") as list
    
–set cList to {}
    
repeat with i from 1 to aMaxPage
      set aFlag to (contents of item i of bNumList) as boolean
      
if aFlag = true then
        set the end of cList to contents of i
      end if
    end repeat
    
    
copy cList to bArray
  end chooseItemByCheckBox:
  
  
  
on doModal:aParam
    set (my returnCode) to aParam’s runModal()
  end doModal:
  
  
  
  
on clicked:aParam
    set aTag to (tag of aParam) as integer
    
–clicked
    
if aTag is not in (my theResult) then
      set the end of (my theResult) to aTag
    else
      set theResult to my deleteItem:aTag fromList:theResult
    end if
  end clicked:
  
  
  
  
on deleteItem:anItem fromList:theList
    set theArray to NSMutableArray’s arrayWithArray:theList
    
theArray’s removeObject:anItem
    
return theArray as list
  end deleteItem:fromList:
  
  
  
  
–1D List(数値)をsort / ascOrderがtrueだと昇順ソート、falseだと降順ソート
  
on sort1DNumList:theList ascOrder:aBool
    tell current application’s NSSet to set theSet to setWithArray_(theList)
    
tell current application’s NSSortDescriptor to set theDescriptor to sortDescriptorWithKey_ascending_(missing value, true)
    
set sortedList to theSet’s sortedArrayUsingDescriptors:{theDescriptor}
    
return (sortedList) as list
  end sort1DNumList:ascOrder:
  
  
  
–Help Button Clicked Event Handler
  
on alertShowHelp:aNotification
    set aRes to display dialog "Do you change all checkbox state?" buttons {"All Off", "All On", "Cancel"} default button 3 with icon 1
    
set bRes to (button returned of aRes) as string
    
    
if bRes = "All Off" then
      set bLen to bArray’s |count|()
      
set theResult to {}
      
repeat with i from 0 to bLen
        ((bArray’s objectAtIndex:i)’s setState:(current application’s NSOffState))
      end repeat
      
    else if bRes = "All On" then
      set bLen to bArray’s |count|()
      
set theResult to {}
      
repeat with i from 0 to bLen
        ((bArray’s objectAtIndex:i)’s setState:(current application’s NSOnState))
        
set the end of theResult to i + 1
      end repeat
    end if
    
    
return false –trueを返すと親ウィンドウ(アラートダイアログ)がクローズする
  end alertShowHelp:
  
  
  
  
–書式つきテキストを組み立てる
  
on makeRTFfromParameters(aStr as string, fontName as string, aFontSize as real, aKerning as real, aLineSpacing as real)
    set aVal1 to NSFont’s fontWithName:fontName |size|:aFontSize
    
set aKey1 to (NSFontAttributeName)
    
    
set aVal2 to NSColor’s blackColor()
    
set aKey2 to (NSForegroundColorAttributeName)
    
    
set aVal3 to aKerning
    
set akey3 to (NSKernAttributeName)
    
    
set aVal4 to 0
    
set akey4 to (NSUnderlineStyleAttributeName)
    
    
set aVal5 to 2 –all ligature ON
    
set akey5 to (NSLigatureAttributeName)
    
    
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, akey7}
    
set valList to {aVal1, aVal2, aVal3, aVal4, aVal5, 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
  
  
  
on makeNSTextField(xPos as integer, yPos as integer, myWidth as integer, myHeight as integer, editableF as boolean, setVal as string, backgroundF as boolean, borderedF as boolean)
    set aNSString to NSTextField’s alloc()’s initWithFrame:(current application’s NSMakeRect(xPos, yPos, myWidth, myHeight))
    
aNSString’s setEditable:(editableF)
    
aNSString’s setStringValue:(setVal)
    
aNSString’s setDrawsBackground:(backgroundF)
    
aNSString’s setBordered:(borderedF)
    
return aNSString
  end makeNSTextField
  
  
  
  
on makeSeqNumList(fromNum as integer, toNum as integer)
    script spd
      property aList : {}
    end script
    
    
set aList of spd to {}
    
    
repeat with i from fromNum to toNum
      set the end of (aList of spd) to i
    end repeat
    
    
return (aList of spd)
  end makeSeqNumList
  
  
end script

★Click Here to Open This Script 

Posted in dialog | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSAlert NSButton NSButtonTypeOnOff NSColor NSFont NSFontAttributeName NSForegroundColorAttributeName NSKernAttributeName NSLigatureAttributeName NSMutableArray NSMutableAttributedString NSMutableDictionary NSMutableParagraphStyle NSOffState NSOnState NSParagraphStyleAttributeName NSRunningApplication NSTextField NSUnderlineStyleAttributeName NSView | Leave a comment

Kamenoko v1.1のMac Pro 2019バグ対策機能が効果を発揮

Posted on 7月 16, 2020 by Takaaki Naganoya

現在Mac App Storeで販売中のKamenoko v1.1には、Mac Pro 2019上でだけ症状が確認されているバグへの対策機能が盛り込まれています。

Mac Pro 2019は三角関数の簡単な計算を間違える「問題マシン」として認識しています(実機ないんで、細かい挙動はわかりません)。

「おそらくこう対策すれば回避できるはず」と想像された方法で機能を実装し、v1.1を動かしたMac Pro 2019ユーザーの知り合いから「大丈夫」との実機確認報告をいただきました。


▲Mac Pro 2019上でのみ報告されているHex Grid座標計算バグ(Kamenoko v1.0+macOS 10.15.5?)

Mac Pro 2019上でのみ、この6角形セルの座標計算でミスが生じることが報告されています。この座標計算はJavaScript Coreの機能をAppleScriptから呼び出して行なっているもので、このJavaScript Coreの関数演算で計算結果に誤差(ないし、想定外の高い計算精度)が発生。

このため、Kamenoko v1.1ではMac Pro 2019対策として各六角形の座標値をあらかじめ計算し、固定データとして保持して使用しています。内部的には、起動時に座標値をすべて計算してNSBezierPathを作ってキャッシュして(作成後の変更なしに)使っていたので、とくに処理フローが大幅に変わったわけではありません。


▲Mac Pro 2019上で動作しているKamenoko v1.1の想像図(実機ないんで)

この関数演算バグがMac Pro 2019上でのみ発生するものなのか、それともXeon搭載機で同様に発生するものなのかは未確認です。

Posted in Bug PRODUCTS | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy Kamenoko | Leave a comment

Kamenoko v1.1をMac App Storeで公開

Posted on 7月 13, 2020 by Takaaki Naganoya

Mac App Storeに「Kamenoko」の本命と位置付けているv1.1をアップロードしました。Mac App Storeへのアップに何も問題なく終わったということはなかったので、今回も何回かのやりとりが必要と思われます。

→ 今回はすぐにレビューを通過しました Now On Saleです

内容をほぼすべてAppleScriptで記述してありますが、本アプリケーションはScriptableではありません。それは、このv1.1でも同様です。

Kamenokoのアプリケーション設計段階で、本アプリケーションのAppleScript対応はあまり考えられませんでした。どちらかといえば、本アプリケーションの書類を一括で書き換えるなどの処理が適していると思われました。

このためには、書類操作用のAppleScriptライブラリを内蔵し、それをAppleScriptで呼び出すスタイルが適していると思われました。

本バージョンもまだAppleScript Libraryは内蔵していませんが、今後のバージョンでの対応を行いたいところです。なぜなら、もう単体でライブラリ自体は動いているからです。

Posted in PRODUCTS | Tagged 10.13savvy 10.14savvy 10.15savvy Kamenoko | Leave a comment

iWork Appがv10.1にアップデートし、Movie書き出しバグの修正とPDF書き出し属性を追加

Posted on 7月 10, 2020 by Takaaki Naganoya

iWorkアプリケーション(Keynote、Numbers、Pages)がアップデートされてv10.1になりました。対象はmacOS 10.14/10.15。

AppleScript系ではバグ修正1点と、機能追加が1点あります。

Keynoteのムービー書き出しオプション(native size)バグ修正

Keynote v10.0の際のアホなバグ(native size指定時にエラー)が修正されました。

AppleScript名:native sizeでムービー書き出し
set outFile to (path to desktop as string) & (do shell script "uuidgen") & ".m4v"

tell application "Keynote"
  tell front document
    export to file outFile as QuickTime movie with properties {class:export options, movie format:native size}
  end tell
end tell

★Click Here to Open This Script 

PDF書き出しオプション(include comments)を追加

また、3アプリケーション共通でPDF書き出し時に「include comments」オプションが指定できるようになりました。


▲include comments属性が追加された


▲Keynote書類に追加した「コメント」


▲KeynoteのGUI上で指定する「コメントを含める」チェックボックス


▲上がinclude comments:falseで書き出したPDF、下がinclude comments:trueで書き出したPDF

AppleScript名:Keynote書類からPDF書き出し v3(10.10対応)
— Created 2017-01-21 by Takaaki Naganoya
— Modified 2020-07-10 by Takaaki Naganoya
— 2017-2020 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set tmpPath to (path to desktop) as string
set aRes to exportKeynoteDocToPDF(tmpPath)

–Keynote書類からPDF書き出し
on exportKeynoteDocToPDF(targFolderPath as string)
  
  
tell application "Keynote"
    set dCount to count every document
    
if dCount = 0 then
      return false
    end if
    
set aPath to file of document 1
  end tell
  
  
set curPath to (current application’s NSString’s stringWithString:(POSIX path of aPath))’s lastPathComponent()’s stringByDeletingPathExtension()’s stringByAppendingString:".pdf"
  
set outPath to (targFolderPath & curPath)
  
  
tell application "Keynote"
    –v10.10で追加されたinclude comments属性の指定を追加してみた
    
set anOpt to {class:export options, export style:IndividualSlides, all stages:false, skipped slides:true, PDF image quality:Best, include comments:false}
    
export document 1 to file outPath as PDF with properties anOpt
  end tell
  
  
return (outPath as alias)
  
end exportKeynoteDocToPDF

★Click Here to Open This Script 

iWorkアプリケーションのAppleScript系機能に望むこと

・slide上の選択中のオブジェクトを扱えるようにしてほしい(selected itemといった予約語で)
・縦書きテキストの制御機能がほしい(強引に作ったけど)
・TOCつきPDFが直接書き出せるように(自分で作ったけど)
・Pagesをなんとかして。レイアウトをScriptから再現できない

Posted in Bug PDF | Tagged 10.14savvy 10.15savvy 11.0savvy Keynote | Leave a comment

辞書.appで指定の単語を検索する v3

Posted on 7月 9, 2020 by Takaaki Naganoya

辞書.appで指定の単語を検索するAppleScriptです。

辞書.app(Dictionary.app)にはAppleScript用語辞書が存在していませんが、URL event経由で検索・表示できるほか、サードパーティのFramework経由でも串刺し検索できるようになっています。

URL eventはApple側から最もセキュリティ面で懸念されている箇所であり、以前はURL event経由でアプリケーション起動もできたのですが、いまはURL event経由のアプリケーション起動は(ごく一部の例外を除き)禁止されている様子です。

ただし、OSバージョンが上がるたびに微妙に辞書名称が変更されており、定数で指定されることに対して微妙にAppleのエンジニアが嫌がらせをしている様子が伺えます。

AppleScript名:辞書.appで指定の単語を検索する v3
— Created 2017-09-19 by Takaaki Naganoya
— 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aText to text returned of (display dialog "Input keyword to search" default answer "")
set encText to encodeURL(aText) of me
activate application "Dictionary"

set aURL to "dict://" & encText
open location aURL

on encodeURL(origStr as string)
  set aStr to current application’s NSString’s stringWithString:origStr
  
set encodedStr to aStr’s stringByAddingPercentEscapesUsingEncoding:(current application’s NSUTF8StringEncoding)
  
return encodedStr as string
end encodeURL

★Click Here to Open This Script 

Shaneからツッコミが入って「stringByAddingPercentEscapesUsingEncoding: はdeprecatedだよー」とのこと。こんな細かいところでAPIが入れ替わっているとはおそろしいところです。

AppleScript名:辞書.appで指定の単語を検索する v4
— Created 2017-09-19 by Takaaki Naganoya
— Modified 2020-07-09 by Shane Stanley
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aText to text returned of (display dialog "Input keyword to search" default answer "")
set encText to encodeURL(aText) of me
activate application "Dictionary"

set aURL to "dict://" & encText
open location aURL

on encodeURL(origStr as string)
  set aStr to current application’s NSString’s stringWithString:origStr
  
set encodedStr to aStr’s stringByAddingPercentEncodingWithAllowedCharacters:(current application’s NSCharacterSet’s URLHostAllowedCharacterSet())
  
–It’s just that stringByAddingPercentEscapesUsingEncoding: is deprecated.
  
return encodedStr as string
end encodeURL

★Click Here to Open This Script 

Posted in URL | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy Dictionary.app | Leave a comment

指定ファイルのメタデータ表示 v2

Posted on 7月 7, 2020 by Takaaki Naganoya

指定ファイルのメタデータをTable UIで表示するAppleScriptです。

テーブル表示用のライブラリ「display table by list」のアップデート版(v1.3)を利用しています。同ライブラリは特定用途のために間に合わせで作っただけだったので、バグを直して汎用性を高めました(無駄なウィンドウの半透明表示をやめた)。また、アイコン表示用のURL指定を省略したときにエラーになる点を修正しました。

–> Download displayTable.scptd(AppleScript Library)

データのテキスト化ライブラリ「everythingToText」も利用していますが、これソースもオープンにしていてよく使っているのですが、とくに決まったURLから配布というのは行なっていませんね。機能が素朴すぎてライブラリとして配布するのがためらわれるところです。

–> Download displayMetadataByTablev2

というわけで、ライブラリを含んだScript Bundleをダウンロードできるようにしておきました(↑)。

AppleScript名:指定ファイルのメタデータ表示 v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/07/07
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
use easyTable : script "display table by list"
use eText : script "everythingToTextKit"

property |NSURL| : a reference to current application’s |NSURL|
property NSMetadataItem : a reference to current application’s NSMetadataItem

set aFile to choose file
set aPOSIX to POSIX path of aFile
set aURL to |NSURL|’s fileURLWithPath:(aPOSIX)
set aMetaInfo to NSMetadataItem’s alloc()’s initWithURL:aURL
set attrList to (aMetaInfo’s attributes()) as list

set aList to {}
repeat with i in attrList
  set metaDict to (aMetaInfo’s valuesForAttributes:{i as string}) as record
  
set recStr to convToStr(metaDict) of eText
  
set the end of aList to {i as string, recStr as string}
  
–set the end of aList to (recStr as string)
end repeat

set fLabels to {"Attribute", "Value"}

set aRes to (display table by list aList main message "Metadata" sub message aPOSIX size {1200, 800} labels fLabels)

★Click Here to Open This Script 

Posted in dialog file Metadata | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSMetadataItem NSURL | 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を採用
  • AppleScriptによる並列処理
  • Safariで「プロファイル」機能を使うとAppleScriptの処理に影響
  • Cocoa Scripting Course 続刊計画
  • macOS 14.xでScript Menuの実行速度が大幅に下がるバグ
  • AppleScript入門③AppleScriptを使った「自動化」とは?
  • Keynote/Pagesで選択中の表カラムの幅を均等割
  • デフォルトインストールされたフォント名を取得するAppleScript
  • macOS 15 リモートApple Eventsにバグ?
  • Keynote、Pages、Numbers Ver.14.0が登場
  • macOS 15でも変化したText to Speech環境
  • AppleScript入門① AppleScriptってなんだろう?
  • 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 (132) CotEditor (66) Finder (51) iTunes (19) Keynote (117) NSAlert (61) NSArray (51) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (53) NSDictionary (28) NSFileManager (23) NSFont (21) NSImage (41) NSJSONSerialization (21) NSMutableArray (63) NSMutableDictionary (22) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (119) NSURL (98) NSURLRequest (23) NSUTF8StringEncoding (30) NSView (33) NSWorkspace (20) Numbers (76) Pages (55) Safari (44) Script Editor (27) WKUserContentController (21) WKUserScript (20) WKWebView (23) WKWebViewConfiguration (22)

カテゴリー

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

アーカイブ

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

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

メタ情報

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

Forum Posts

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

メタ情報

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