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

タグ: NSString

スタイルつきテキストでスタイルつきテキストを検索 v1.1

Posted on 1月 13 by Takaaki Naganoya

スタイルつきテキストの中をスタイルつきテキストで検索するAppleScriptです。フォント、サイズ、色の属性を考慮して文字とこれらの属性値が合っている場合に合致しているものとみなします。

最初のバージョンはChatGPTに書かせたもので、実際に動かしてみたら激遅だったので、2パスで検索することで高速化してみました。オリジナルより100倍以上速くなっているはずです。

Step1: 検索対象文字列、検索文字列の両方をテキスト化して、テキストベースで出現情報を計算
Step2: 出現情報をもとにスタイルつきテキスト(NSAttributedString)の書式情報の照合を行い、合致するものを出力

という処理に変更しました。ChatGPTが出力してきたAppleScriptは、1文字ずつチェック範囲を変更しながら書式情報とテキスト情報の照合を行うという「脳筋処理」だったので、少なく見積もっても100倍。データ量が増えれば増えるほど高速化の度合いが上昇します。

AppleScript名:find Styled Text in Styled Text_v1.1.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/01/12
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

use AppleScript
use framework "Foundation"
use scripting additions

property NSString : a reference to current application’s NSString
property NSLiteralSearch : a reference to current application’s NSLiteralSearch
property NSMutableArray : a reference to current application’s NSMutableArray

— サンプルデータ
set targetText to "これはサンプルテキストです。サンプルは重要です。サンプルだよー。サンプルサンプル"
set searchText to "サンプル"

— 属性付き文字列の作成
set targetAttributedString to current application’s NSMutableAttributedString’s alloc()’s initWithString:targetText
set searchAttributedString to current application’s NSMutableAttributedString’s alloc()’s initWithString:searchText

— 属性を設定 (例: フォントと色)
set targetFont to current application’s NSFont’s fontWithName:"HiraginoSans-W2" |size|:13
set targetColor to current application’s NSColor’s redColor()
set searchFont to current application’s NSFont’s fontWithName:"HiraginoSans-W2" |size|:13
set searchColor to current application’s NSColor’s redColor()

— 属性を追加
targetAttributedString’s addAttribute:(current application’s NSFontAttributeName) value:targetFont range:{0, targetAttributedString’s |length|()}
targetAttributedString’s addAttribute:(current application’s NSForegroundColorAttributeName) value:targetColor range:{0, targetAttributedString’s |length|()}
searchAttributedString’s addAttribute:(current application’s NSFontAttributeName) value:searchFont range:{0, searchAttributedString’s |length|()}
searchAttributedString’s addAttribute:(current application’s NSForegroundColorAttributeName) value:searchColor range:{0, searchAttributedString’s |length|()}

— 属性付き検索を実行
set matches to searchAttributedStringWithAttributes(targetAttributedString, searchAttributedString) of me
–> {{location:3, |length|:4}, {location:14, |length|:4}, {location:24, |length|:4}, {location:32, |length|:4}, {location:36, |length|:4}}

— NSAttributedStringの属性付き検索を行うハンドラー(複数一致対応)
on searchAttributedStringWithAttributes(targetAttributedString, searchAttributedString)
  set targText to targetAttributedString’s |string|() as string
  
  
set searchAttributes to searchAttributedString’s attributesAtIndex:0 effectiveRange:(missing value)
  
set searchString to searchAttributedString’s |string|() as string
  
  
–テキストベースで検索
  
set strRangeList to searchWordRanges(targText, searchString) of me
  
–あとは、検索箇所の文字書式をループで照合する
  
  
set matList to {} — 結果を格納するリスト
  
  
— ループで対象の文字列が含まれる位置の書式情報を検索
  
repeat with i in strRangeList
    set j to contents of i
    
set tmpLoc to location of j
    
set tmpLen to |length| of j
    
    
— 対象範囲の属性を取得
    
set targetAttributes to (targetAttributedString’s attributesAtIndex:(tmpLoc) effectiveRange:(current application’s NSMakeRange(tmpLoc, tmpLen)))
    
    
if (targetAttributes = searchAttributes) then
      set the end of matList to {location:(tmpLoc as integer), |length|:(tmpLen as integer)} — 属性が一致した場合
    end if
  end repeat
  
  
return matList — 一致したすべての範囲を返す
end searchAttributedStringWithAttributes

–プレーンテキストベースで検索文字列の出現情報を返す(複数対応)
on searchWordRanges(aTargText as string, aSearchStr as string)
  set aStr to NSString’s stringWithString:aTargText
  
set bStr to NSString’s stringWithString:aSearchStr
  
  
set hitArray to NSMutableArray’s alloc()’s init()
  
set cNum to (aStr’s |length|()) as integer
  
  
set aRange to current application’s NSMakeRange(0, cNum)
  
  
repeat
    set detectedRange to aStr’s rangeOfString:bStr options:(NSLiteralSearch) range:aRange
    
set aLen to (detectedRange’s |length|) as number
    
    
if aLen = 0 then exit repeat
    
    
hitArray’s addObject:detectedRange
    
    
set aNum to (detectedRange’s location) as number
    
set bNum to (detectedRange’s |length|) as number
    
    
set aRange to current application’s NSMakeRange(aNum + bNum, cNum – (aNum + bNum))
  end repeat
  
  
return hitArray
end searchWordRanges

★Click Here to Open This Script 

Posted in RTF search | Tagged 13.0savvy 14.0savvy 15.0savvy NSColor NSFont NSLiteralSearch NSMutableArray NSMutableAttributedString NSString | Leave a comment

AS書類を書式で分解して再構成

Posted on 1月 12 by Takaaki Naganoya

AppleScriptの書類を読み込んでNSAttributedStringに変換し、書式情報にもとづいてNSDictionary in NSArrayに変換。この状態でデータ抽出などを行なっていたのですが、このデータをもとにNSAttributedStringに再構成するAppleScriptです。

本Scriptの通しの処理内容としては、読み込んだAppleScriptを書式情報をもとに分解して、再構成するという……大豆から豆腐を作って、豆腐を崩して豆を得る、みたいな内容です。

NSAttributedStringを再構成する部分の処理を書いていなかったので、必要に迫られて書いてみました。

AppleScript構文色分け設定情報をもとに処理するため、色分け設定で複数の構文要素で同じ色を指定している場合にはエラーを返します。単にNSAttributedStringを解釈して再構成する、といった処理であればAppleScript構文色分け設定へのアクセス自体は必要ないところですが、すでに不可分なレベルで組み込まれているため、現状ではそのままです。

いっそ、こうした処理をする前にplistをバックアップし、必要な情報を書き込んだplistを設定ファイルとして使用するといった処理を行った方がいいのかもしれません。これまでは、「そんな処理はとても行えない」と判断していましたが、よくよく考えればとくに苦労せずに実現できそうです。

AppleScript名:AS書類を書式で分解して再構成.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/01/12
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

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

property NSFont : a reference to current application’s NSFont
property NSColor : a reference to current application’s NSColor
property |NSURL| : a reference to current application’s |NSURL|
property NSString : a reference to current application’s NSString
property OSAScript : a reference to current application’s OSAScript
property NSDictionary : a reference to current application’s NSDictionary
property NSUnarchiver : a reference to current application’s NSUnarchiver
property NSMutableDictionary : a reference to current application’s NSMutableDictionary
property NSFontAttributeName : a reference to current application’s NSFontAttributeName
property NSMutableAttributedString : a reference to current application’s NSMutableAttributedString
property NSForegroundColorAttributeName : a reference to current application’s NSForegroundColorAttributeName

property asCol : {}

set asCol to getAppleScriptSourceColors() of me –AppleScript構文色分け設定をplistから読み込む

set aFile to POSIX path of (choose file of type {"com.apple.applescript.script", "com.apple.applescript.script-bundle"})
set aURL to |NSURL|’s fileURLWithPath:(aFile)
set theScript to current application’s OSAScript’s alloc()’s initWithContentsOfURL:aURL |error|:(missing value)
set styledText to theScript’s richTextSource()

–Styled TextをDictionarry in Listに
set sRes to getAttributeRunsFromAttrStringRBO(styledText) of styleTextToDict

–Dictionarry in ListをStyled Textに再構成
set bRes to retAttributedStringFromAttrDict(sRes) of attrDictToAttrStr

script styleTextToDict
  use AppleScript
  
use framework "Foundation"
  
use framework "AppKit"
  
use scripting additions
  
property parent : AppleScript
  
  
–Styled Textを
  
on getAttributeRunsFromAttrStringRBO(theStyledText)
    script aSpd
      property styleList : {}
    end script
    
    
set (styleList of aSpd) to {} —for output
    
    
set thePureString to theStyledText’s |string|() –pure string from theStyledText
    
    
set theLength to theStyledText’s |length|()
    
set startIndex to 0
    
set aCount to 0
    
    
repeat until (startIndex = theLength)
      set {theAtts, theRange} to theStyledText’s attributesAtIndex:startIndex longestEffectiveRange:(reference) inRange:{startIndex, theLength – startIndex}
      
      
–String  
      
set aText to (thePureString’s substringWithRange:theRange) as string
      
set strLen to (length of aText)
      
      
–Color
      
set aColor to (theAtts’s valueForKeyPath:"NSColor")
      
if aColor is not equal to missing value then
        set aSpace to aColor’s colorSpace()
        
        
set aRed to (aColor’s redComponent()) * 255
        
set aGreen to (aColor’s greenComponent()) * 255
        
set aBlue to (aColor’s blueComponent()) * 255
        
        
set colList to {aRed as integer, aGreen as integer, aBlue as integer} –for comparison
        
set colStrForFind to (aRed as integer as string) & " " & (aGreen as integer as string) & " " & (aBlue as integer as string) –for filtering
      else
        set colList to {0, 0, 0}
        
set colStrForFind to "0 0 0"
      end if
      
      
–Font
      
set aFont to (theAtts’s valueForKeyPath:"NSFont")
      
if aFont is not equal to missing value then
        set aDFontName to aFont’s displayName()
        
set aDFontSize to aFont’s pointSize()
      end if
      
      
–Range
      
set the end of (styleList of aSpd) to {stringVal:aText, atrIndex:aCount, colorStr:colStrForFind, colorVal:colList, fontName:aDFontName as string, fontSize:aDFontSize}
      
set startIndex to current application’s NSMaxRange(theRange)
      
      
set aCount to aCount + 1
    end repeat
    
    
return (styleList of aSpd)
    
  end getAttributeRunsFromAttrStringRBO
  
  
–NSColorからRGBの値を取り出す
  
on retColListFromNSColor(aCol, aMAX as integer)
    using terms from scripting additions
      set aRed to round ((aCol’s redComponent()) * aMAX) rounding as taught in school
      
set aGreen to round ((aCol’s greenComponent()) * aMAX) rounding as taught in school
      
set aBlue to round ((aCol’s blueComponent()) * aMAX) rounding as taught in school
    end using terms from
    
if aRed > aMAX then set aRed to aMAX
    
if aGreen > aMAX then set aGreen to aMAX
    
if aBlue > aMAX then set aBlue to aMAX
    
    
return {aRed, aGreen, aBlue}
  end retColListFromNSColor
  
  
–aMaxValを最大値とする数値でNSColorを作成して返す
  
on makeNSColorFromRGBAval(redValue as integer, greenValue as integer, blueValue as integer, alphaValue as integer, aMaxVal as integer)
    set aRedCocoa to (redValue / aMaxVal) as real
    
set aGreenCocoa to (greenValue / aMaxVal) as real
    
set aBlueCocoa to (blueValue / aMaxVal) as real
    
set aAlphaCocoa to (alphaValue / aMaxVal) as real
    
set aColor to NSColor’s colorWithCalibratedRed:aRedCocoa green:aGreenCocoa blue:aBlueCocoa alpha:aAlphaCocoa
    
return aColor
  end makeNSColorFromRGBAval
  
end script

script attrDictToAttrStr
  use AppleScript
  
use framework "Foundation"
  
use framework "AppKit"
  
use scripting additions
  
property parent : AppleScript
  
  
–書式つきテキストを組み立てる(メイン側)
  
on retAttributedStringFromAttrDict(attrRes)
    script aSpd
      property styleList : {}
    end script
    
    
set (styleList of aSpd) to {} —for output
    
    
set allAttrStr to NSMutableAttributedString’s alloc()’s init()
    
    
repeat with i in attrRes
      set j to contents of i
      
set tmpAttrStr to makeRTFfromParameters(stringVal of j, fontName of j, fontSize of j, colorVal of j) of me
      
      (
allAttrStr’s appendAttributedString:tmpAttrStr)
    end repeat
    
    
return allAttrStr
  end retAttributedStringFromAttrDict
  
  
–書式つきテキストを組み立てる(パーツ組み立て用サブ側)
  
on makeRTFfromParameters(aStr as string, fontName as string, aFontSize as real, aColorList as list)
    –Font & Size
    
set aVal1 to NSFont’s fontWithName:fontName |size|:aFontSize
    
set aKey1 to (NSFontAttributeName)
    
    
–Color
    
copy aColorList to {rCol, gCol, bCOl}
    
set aVal2 to makeNSColorFromRGBAval(rCol, gCol, bCOl, 255, 255) of asCol
    
set aKey2 to (NSForegroundColorAttributeName)
    
    
set keyList to {aKey1, aKey2}
    
set valList to {aVal1, aVal2}
    
set attrsDictionary to NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList
    
    
–Text
    
set attrStr to NSMutableAttributedString’s alloc()’s initWithString:aStr attributes:attrsDictionary
    
return attrStr
  end makeRTFfromParameters
  
  
  
–aMaxValを最大値とする数値でNSColorを作成して返す
  
on makeNSColorFromRGBAval(redValue as integer, greenValue as integer, blueValue as integer, alphaValue as integer, aMaxVal as integer)
    set aRedCocoa to (redValue / aMaxVal) as real
    
set aGreenCocoa to (greenValue / aMaxVal) as real
    
set aBlueCocoa to (blueValue / aMaxVal) as real
    
set aAlphaCocoa to (alphaValue / aMaxVal) as real
    
set aColor to NSColor’s colorWithCalibratedRed:aRedCocoa green:aGreenCocoa blue:aBlueCocoa alpha:aAlphaCocoa
    
return aColor
  end makeNSColorFromRGBAval
  
end script

–AppleScriptの構文色分けのカラー値をRGBで取得する
on getAppleScriptSourceColors()
  — get the plist info as a dictionary
  
set thePath to NSString’s stringWithString:"~/Library/Preferences/com.apple.applescript.plist"
  
set thePath to thePath’s stringByExpandingTildeInPath()
  
set theInfo to NSDictionary’s dictionaryWithContentsOfFile:thePath
  
  
— extract relevant part and loop through
  
set theArray to (theInfo’s valueForKey:"AppleScriptSourceAttributes") as list
  
  
set colList to {}
  
  
repeat with i from 1 to count of theArray
    set anEntry to item i of theArray
    
    
set colorData to NSColor of anEntry
    
set theColor to (NSUnarchiver’s unarchiveObjectWithData:colorData)
    
    
set {rVal, gVal, bVal} to retColListFromNSColor(theColor, 255) of me
    
    
set fontData to NSFont of anEntry
    
set theFont to (NSUnarchiver’s unarchiveObjectWithData:fontData)
    
    
set aFontName to theFont’s displayName() as text
    
set aFontSize to theFont’s pointSize()
    
    
set aColRec to {redValue:rVal, greenValue:gVal, blueValue:bVal, fontName:aFontName, fontSize:aFontSize}
    
    
set the end of colList to aColRec
  end repeat
  
  
return colList
end getAppleScriptSourceColors

–NSColorからRGBの値を取り出す
on retColListFromNSColor(aCol, aMAX as integer)
  using terms from scripting additions
    set aRed to round ((aCol’s redComponent()) * aMAX) rounding as taught in school
    
set aGreen to round ((aCol’s greenComponent()) * aMAX) rounding as taught in school
    
set aBlue to round ((aCol’s blueComponent()) * aMAX) rounding as taught in school
  end using terms from
  
  
if aRed > aMAX then set aRed to aMAX
  
if aGreen > aMAX then set aGreen to aMAX
  
if aBlue > aMAX then set aBlue to aMAX
  
  
return {aRed, aGreen, aBlue}
end retColListFromNSColor

★Click Here to Open This Script 

Posted in Color file Font OSA RTF | Tagged 13.0savvy 14.0savvy 15.0savvy NSAttributedString NSColor NSDictionary NSFont NSMutableAttributedString NSMutableDictionary NSString NSUnarchiver NSURL OSAScript | Leave a comment

macOS 13でNSNotFoundバグふたたび

Posted on 12月 1, 2022 by Takaaki Naganoya

また、Appleがやらかしてくれたようです。あの会社はNSNotFoundの定義値を何回間違えたら気が済むんでしょうか。これで通算4回目ぐらいです。macOS 10.12で発生し10.13.1で修正された定義値のミスをまたやったわけで、失敗がまったく生かされていない。大したものです。

今回のバグは、文字列の検索処理を行っているときに発見しました。指定文字列から対象文字列の登場位置と長さをリストで返す処理を行っていたところ、NSRangeからlocationを取得したときに、これ以上見つからない場所まで来たときにNSNotFoundを返すことを期待されるわけですが、そこに前回(macOS 10.12…10.13)と同様のおかしな値を返してきました。

この(↓)AppleScriptをmacOS 13上で実行すると、エラーになります。

追記:macOS 13.1でもエラーになります。

AppleScript名:テキストのキーワード検索(結果をNSRangeのlistで返す).scptd
— Created 2017-08-09 by Takaaki Naganoya
— 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
–http://piyocast.com/as/archives/4771

property NSString : a reference to current application’s NSString
property NSMutableArray : a reference to current application’s NSMutableArray
property NSLiteralSearch : a reference to current application’s NSLiteralSearch

set aStr to "ATGC ACGT ATGC AGTC
ATGC ACGT ATGC AGTC
ATGC ACGT ATGC AGTC
ATGC ACGT ATGC AGTC
"

set aRes to searchWordRanges(aStr, "ATGC") of me as list
–>  {​​​​​{​​​​​​​location:0, ​​​​​​​length:4​​​​​}, ​​​​​{​​​​​​​location:10, ​​​​​​​length:4​​​​​}, ​​​​​{​​​​​​​location:20, ​​​​​​​length:4​​​​​}, ​​​​​{​​​​​​​location:30, ​​​​​​​length:4​​​​​}, ​​​​​{​​​​​​​location:40, ​​​​​​​length:4​​​​​}, ​​​​​{​​​​​​​location:50, ​​​​​​​length:4​​​​​}, ​​​​​{​​​​​​​location:60, ​​​​​​​length:4​​​​​}, ​​​​​{​​​​​​​location:70, ​​​​​​​length:4​​​​​}​​​}

on searchWordRanges(aTargText as string, aSearchStr as string)
  set aStr to NSString’s stringWithString:aTargText
  
set bStr to NSString’s stringWithString:aSearchStr
  
  
set hitArray to NSMutableArray’s alloc()’s init()
  
set cNum to (aStr’s |length|()) as integer
  
  
set aRange to current application’s NSMakeRange(0, cNum)
  
  
repeat
    set detectedRange to aStr’s rangeOfString:bStr options:(NSLiteralSearch) range:aRange
    
set aLoc to detectedRange’s location
    
log aLoc
    
if (detectedRange’s location) is equal to (current application’s NSNotFound) then exit repeat
    
    
hitArray’s addObject:detectedRange
    
    
set aNum to (detectedRange’s location) as number
    
set bNum to (detectedRange’s |length|) as number
    
    
set aRange to current application’s NSMakeRange(aNum + bNum, cNum – (aNum + bNum))
  end repeat
  
  
return hitArray
end searchWordRanges

★Click Here to Open This Script 

症状も前回とまったく同じなので、対処も前回と同じです。Appleは定期的にNSNotFoundの定義値を間違えるトンでもない会社なので(計測された事実)、NSNotFoundまわりはAppleがバグをやらかすことを前提に書いておくべきなんでしょう。

AppleScript名:テキストのキーワード検索(結果をNSRangeのlistで返す)v2.scptd
— Created 2017-08-09 by Takaaki Naganoya
— Modified 2022-12-01 by Takaaki Naganoya
— 2022 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

property NSString : a reference to current application’s NSString
property NSMutableArray : a reference to current application’s NSMutableArray
property NSLiteralSearch : a reference to current application’s NSLiteralSearch

set aStr to "ATGC ACGT ATGC AGTC
ATGC ACGT ATGC AGTC
ATGC ACGT ATGC AGTC
ATGC ACGT ATGC AGTC
"

set aRes to searchWordRanges(aStr, "ATGC") of me as list
–>  {​​​​​{​​​​​​​location:0, ​​​​​​​length:4​​​​​}, ​​​​​{​​​​​​​location:10, ​​​​​​​length:4​​​​​}, ​​​​​{​​​​​​​location:20, ​​​​​​​length:4​​​​​}, ​​​​​{​​​​​​​location:30, ​​​​​​​length:4​​​​​}, ​​​​​{​​​​​​​location:40, ​​​​​​​length:4​​​​​}, ​​​​​{​​​​​​​location:50, ​​​​​​​length:4​​​​​}, ​​​​​{​​​​​​​location:60, ​​​​​​​length:4​​​​​}, ​​​​​{​​​​​​​location:70, ​​​​​​​length:4​​​​​}​​​}
–> {{location:0, |length|:4}, {location:10, |length|:4}, {location:20, |length|:4}, {location:30, |length|:4}, {location:40, |length|:4}, {location:50, |length|:4}, {location:60, |length|:4}, {location:70, |length|:4}}

on searchWordRanges(aTargText as string, aSearchStr as string)
  set aStr to NSString’s stringWithString:aTargText
  
set bStr to NSString’s stringWithString:aSearchStr
  
  
set hitArray to NSMutableArray’s alloc()’s init()
  
set cNum to (aStr’s |length|()) as integer
  
  
set aRange to current application’s NSMakeRange(0, cNum)
  
  
repeat
    set detectedRange to aStr’s rangeOfString:bStr options:(NSLiteralSearch) range:aRange
    
set aLoc to detectedRange’s location
    
    
–macOS 13でAppleが新たに作ったバグを回避
    
if (aLoc > 9.999999999E+9) or (aLoc = current application’s NSNotFound) then exit repeat
    
    
hitArray’s addObject:detectedRange
    
    
set aNum to (detectedRange’s location) as number
    
set bNum to (detectedRange’s |length|) as number
    
    
set aRange to current application’s NSMakeRange(aNum + bNum, cNum – (aNum + bNum))
  end repeat
  
  
return hitArray
end searchWordRanges

★Click Here to Open This Script 

Appleと協議した結果、そこは仕様として認識していないという話で、とくに仕様を変えていないという話で平行線をたどってしまいました。

結局、書き方を少々変えることで問題そのものを「なかったこと」にする方向で決着。納得はできませんが、macOS 10.11とか10.12の時代に書いたScriptでもあり、その実行環境は手元に残っていません(macOS 10.13は何台か存在しています。macOS 11のASのCocoa呼び出しバグの検証時に活躍)。

AppleScript名:テキストのキーワード検索(結果をNSRangeのlistで返す)v3.scptd
— Created 2017-08-09 by Takaaki Naganoya
— Modified 2022-08-29 by Takaaki Naganoya
— 2023 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

property NSString : a reference to current application’s NSString
property NSLiteralSearch : a reference to current application’s NSLiteralSearch
property NSMutableArray : a reference to current application’s NSMutableArray

set aStr to "ATGC ACGT ATGC AGTC
ATGC ACGT ATGC AGTC
ATGC ACGT ATGC AGTC
ATGC ACGT ATGC AGTC
"

set aRes to searchWordRanges(aStr, "ATGC") of me as list
–> {{location:0, |length|:4}, {location:10, |length|:4}, {location:20, |length|:4}, {location:30, |length|:4}, {location:40, |length|:4}, {location:50, |length|:4}, {location:60, |length|:4}, {location:70, |length|:4}}

on searchWordRanges(aTargText as string, aSearchStr as string)
  set aStr to NSString’s stringWithString:aTargText
  
set bStr to NSString’s stringWithString:aSearchStr
  
  
set hitArray to NSMutableArray’s alloc()’s init()
  
set cNum to (aStr’s |length|()) as integer
  
  
set aRange to current application’s NSMakeRange(0, cNum)
  
  
repeat
    set detectedRange to aStr’s rangeOfString:bStr options:(NSLiteralSearch) range:aRange
    
set aLen to (detectedRange’s |length|) as number
    
    
if aLen = 0 then exit repeat
    
    
hitArray’s addObject:detectedRange
    
    
set aNum to (detectedRange’s location) as number
    
set bNum to (detectedRange’s |length|) as number
    
    
set aRange to current application’s NSMakeRange(aNum + bNum, cNum – (aNum + bNum))
  end repeat
  
  
return hitArray
end searchWordRanges

★Click Here to Open This Script 

Posted in Bug list Text | Tagged 13.0savvy NSLiteralSearch NSMakeRange NSMutableArray NSNotFound NSRange NSString | Leave a comment

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

Posted on 1月 28, 2022 by Takaaki Naganoya

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

Thanks Shane!

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

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

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

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

★Click Here to Open This Script 

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

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

Posted on 1月 28, 2022 by Takaaki Naganoya

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

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

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


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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

</style>
</head>
<body>

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

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

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

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

// Add data
chart.data = %@;

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

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

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

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

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

end retHTML

★Click Here to Open This Script 

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

NSString’s stringWithFormat:がクラッシュするバグが修正された

Posted on 7月 18, 2021 by Takaaki Naganoya

macOS 11で発生していた「NSString’s stringWithFormat:」をAppleScriptから呼び出すとクラッシュするというバグが、最新のmacOS 11.5BetaおよびmacOS 12.0Betaで修正されていることを確認しました。
→ macOS 11.5正式版がリリースされ、修正されていることを確認。逆にいえば、AppleScriptでCocoa Scriptingを用いて作ったプログラムは、macOS 11.0〜11.4の環境を動作条件から外す(動作要求条件を11.5以上にする)必要があるということです。

クラッシュしなくなりましたね。問題点について、気がついたらレポートして念押しして、修正内容を確認するという地道な作業の繰り返し、積み重ねで世界の平和が維持されているのでありました。


▲Uni Detector v1.2.1もNSString’s stringWithFormat:メソッドがクラッシュしなくなったおかげで、ちゃんとCPUアーキテクチャごとの構成比率グラフを実行してもアプリケーションごとクラッシュしなくなりました

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

部首で漢字検索

Posted on 2月 21, 2021 by Takaaki Naganoya

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

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

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

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

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

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

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

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

追記:

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

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

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

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

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

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

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

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

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

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

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

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

script jsonStr
  property aJsonDict : missing value
end script

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

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

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

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

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

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

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

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

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

★Click Here to Open This Script 

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

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

Posted on 12月 8, 2020 by Takaaki Naganoya

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

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

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

AppleScript名:HTMLカラー値から明度を取得 v1.1.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/12/07
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

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

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

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

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

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

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

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

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

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

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

★Click Here to Open This Script 

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

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

Posted on 8月 15, 2020 by Takaaki Naganoya

edama2さんからの投稿です。Markdown書類をプレビューするAppleScriptです。

–> Download Script bundle

本Scriptには、画期的な技術が用いられています。普通、AppleScriptObjCでは、WkWebViewによるネットワークアクセスを行うと、ネットワークアクセスを行う子プロセスと、WkWebViewで表示を行う子プロセスが生じて、処理が終了しても残ってしまいます。

スクリプトエディタ上で実行した場合には、スクリプトエディタを終了すればこうした子プロセスはメモリ上からパージされますが、終了するまで子プロセスは残されたままです。

「まー、AppleScriptObjCだから仕方ないよねー」

などと去年の年末に秋葉原でカレーを食べながらバカ話をしていた記憶がありますが、edama2さんがついにこれを回避する記法を編み出してしまったわけです。

回避方法については、やり方を説明されると「なるほど」という単純明快なものです(それを思いつくのがすごい)。osascript経由でAppleScriptを再実行することで、ランタイム環境を明示的にosascriptに指定してプログラムを実行。osascriptの終了とともにメモリ上から子プロセスがパージされるということのようです。

ランタイム環境を動的に生成し、実行後にランタイム環境がメモリ上から消去されるようになっていれば、子プロセス(ゴミ)が残っていてもまとめて消える………AppleScriptのランタイム環境はosascriptのほかCocoa系もあるので、そちらでも試してみるとよいでしょう。

ほかにも、WkWebViewによる表示を行う専用の支援アプリケーションを作っておき、AppleScript用語辞書経由で表示を行わせるという解決策も考えられます(ためしていないですが)。

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

on run args
  if (args’s class) is script then
    set myPath to (path to me)’s POSIX path
set resultText to do shell script “osascript “ & myPath’s quoted form
  else
    my main()
  end if
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 {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”


  current application’s NSRunningApplication’s currentApplication()’s activateWithOptions:0


  ## 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 Markdown URL | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSAlert NSAlertSecondButtonReturn NSRunningApplication NSScreen NSString NSURL NSWorkspace WKUserContentController WKWebView WKWebViewConfiguration | 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

よみがなタグを削除

Posted on 7月 1, 2020 by Takaaki Naganoya

与えられたテキスト(おそらくHTML)から、指定のタグで囲まれた要素を削除するAppleScriptです。

Web上の表をCSVとして書き出すAppleScriptを動かしていて、Wikipediaの表を処理したときに「よみがなタグ」がそのまま文字列として展開されることに気づきました。

その場で既存のルーチンを使いまわして、よみがなタグの削除機能を追加。その追加内容です。


▲上は、Wikipedia掲載の表をそのままCSV化したもの。下は、本Scriptを追加してルビタグを削除するように改良したScriptの処理結果

AppleScript名:指定タグを削除.scpt
— Created 2016-12-12 by Shane Stanley
— Modified 2016-12-14 by edama2
— Modified 2017-11-28 by Takaaki Naganoya
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aStr to getData() of me
set aRes to (trimStrFromTo(aStr, "<span style=\"display:none;speak:none\">", "</span>") of me)
–>  
(*
"
<td><b><a href=\"/wiki/aaaaa" title=\"こちら葛飾区亀有公園前派出所\">こちら葛飾区<br /> 亀有公園前派出所</a></b></td>
<td><a href=\"/wiki/%E7%A7%8B%E6%9C%AC%E6%B2%BB\" title=\"秋本治\">秋本治</a></td>
"
*)

on trimStrFromTo(aParamStr, fromStr, toStr)
  set theScanner to current application’s NSScanner’s scannerWithString:aParamStr
  
set anArray to current application’s NSMutableArray’s array()
  
  
repeat until (theScanner’s isAtEnd as boolean)
    set {theResult, theKey} to theScanner’s scanUpToString:fromStr intoString:(reference)
    
    
theScanner’s scanString:fromStr intoString:(missing value)
    
set {theResult, theValue} to theScanner’s scanUpToString:toStr intoString:(reference)
    
if theValue is missing value then set theValue to ""
    
    
theScanner’s scanString:toStr intoString:(missing value)
    
    
anArray’s addObject:theValue
  end repeat
  
  
if anArray’s |count|() = 0 then return aParamStr
  
  
copy aParamStr to curStr
  
repeat with i in (anArray as list)
    set curStr to repChar(curStr, fromStr & i & toStr, "") of me
  end repeat
  
  
return curStr
end trimStrFromTo

on repChar(aStr, targStr, repStr)
  set aString to current application’s NSString’s stringWithString:aStr
  
set bString to aString’s stringByReplacingOccurrencesOfString:targStr withString:repStr
  
set cString to bString as string
  
return cString
end repChar

on getData()
  return "
<td><span style=\"display:none;speak:none\">こちらかつしかくかめありこうえんまえはしゆつしよ/</span><b><a href=\"/wiki/aaaaa\" title=\"こちら葛飾区亀有公園前派出所\">こちら葛飾区<br /> 亀有公園前派出所</a></b></td>
<td><span style=\"display:none;speak:none\">あきもと おさむ/</span><a href=\"/wiki/%E7%A7%8B%E6%9C%AC%E6%B2%BB\" title=\"秋本治\">秋本治</a></td>
"

end getData

★Click Here to Open This Script 

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

chartJSでアニメーション円グラフをダイアログ表示 v2.scptd

Posted on 6月 30, 2020 by Takaaki Naganoya

アラートダイアログ上にWkWebViewを作成し、その上でChart.jsによる円グラフを表示するAppleScriptです。


▲実行するとテーマ選択ののちにグラフ表示を行います


–> Download chartJSPieChartDemo.scptd(Script Bundle with Lirbrary and HTML)

Chart.jsは、ダイアグラムやフローチャートなどを描画するJavaScriptのライブラリです。割とデータのカスタマイズがしやすい感じです。

AppleScript名:chartJSでアニメーション円グラフをダイアログ表示 v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/06/26
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use webD : script "webDialogLib"

set aRes to first item of (choose from list {"light1", "light2", "dark1", "dark2"} with prompt "Choose theme")

set aList to {{y:45.43, label:"Chrome"}, {y:32.4, label:"Safari"}, {y:6.67, label:"Firefox"}, {y:5.41, label:"Microsoft Edge"}, {y:5.26, label:"Internet Explorer"}, {y:1.19, label:"Samsung Internet"}}
set myTitle to "Desktop Browser Market Share in Japan May 2020"

–https://canvasjs.com/javascript-charts/pie-chart-legends/
set mePath to path to me
set resPath to (mePath as string) & "Contents:Resources:index.html"
set myStr to (read (resPath as alias) as «class utf8») as string

set aJsonStr to array2DToJSONArray(aList) of me
set aString to current application’s NSString’s stringWithFormat_(myStr, aRes as string, myTitle, aJsonStr) as string

set paramObj to {myMessage:"Animation Pie Chart", mySubMessage:"This is a canvasJS test", htmlStr:aString, jsDelimiters:{"<script>", "</script>"}, viewSize:{900, 620}}

webD’s displayWebDialog(paramObj)

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

★Click Here to Open This Script 

Posted in dialog JSON list Record | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSJSONSerialization NSMutableArray NSString | Leave a comment

Mermaid.jsでPie Chartをダイアログ表示

Posted on 6月 28, 2020 by Takaaki Naganoya

アラートダイアログ上にWkWebViewを作成し、その上でMermaid.jsによる円グラフを表示するAppleScriptです。

–> Download mermaidPieChart.scptd(Script Bundle with Script Library)

Mermaid.jsは、ダイアグラムやフローチャートなどを描画するJavaScriptのライブラリです。Markdownのような簡略式のテキストを記述するだけで各種のグラフを描画できることを特徴としています。

AppleScriptのワークフローにおいて、このようなグラフ表示をAppleScript単体で(アプリケーションを介さないで)行う意義については、処理結果の報告などが考えられます。そうした用途においては表示の派手さではなくAS側から意図したデータを表示させやすいかどうかということは重要です。その意味で本ライブラリは用途に叶うものといえます。

反面、派手なアニメーションなどは行いません。何か、他のライブラリと組み合わせるとアニメーションを実現できるのかもしれませんが……。

AppleScript名:Mermaid.jsでPie Chartをダイアログ表示.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/06/26
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use webD : script "webDialogLib"

set aList to {{label:"すごくいい", value:300}, {label:"まあまあ", value:200}, {label:"なんとなく", value:100}}
set myTitle to "集計結果"

set dataStr to ""
repeat with i in aList
  set aLabel to label of i
  
set aVal to value of i
  
set dataStr to dataStr & "\"" & aLabel & "\"" & " : " & (aVal as string) & return
end repeat

–http://mermaid-js.github.io/mermaid/#/pie
set mePath to path to me
set resPath to (mePath as string) & "Contents:Resources:index.html"
set myStr to "<!DOCTYPE html>
<html lang=\"en\">
<head>
<meta charset=\"utf-8\">
</head>
<body>
<div class=\"mermaid\">
pie title %@
%@
</div>
<script src=\"https://cdnjs.cloudflare.com/ajax/libs/mermaid/8.5.2/mermaid.min.js\"></script>
<script>mermaid.initialize({startOnLoad:true});</script>
</body>
</html>"

set aString to current application’s NSString’s stringWithFormat_(myStr, myTitle, dataStr) as string

set paramObj to {myMessage:"Pie Chart", mySubMessage:"This is a mermaid test", htmlStr:aString, jsDelimiters:{"<script>", "</script>"}, viewSize:{800, 480}}

webD’s displayWebDialog(paramObj)

★Click Here to Open This Script 

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

AMChartsで円グラフをダイアログ上に表示 v3

Posted on 6月 27, 2020 by Takaaki Naganoya

アラートダイアログ上にWkWebViewを作成し、その上でAMChartsによる円グラフを表示するAppleScriptです。

ダイアログでテーマ選択したのちに、グラフ表示を行います。

—> Download ampiechartSample(AppleScript bundle with Script Library and HTMLs)

AppleScript名:AMChartsで円グラフをダイアログ上に表示 v3.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/06/25
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use webD : script "webDialogLib"

set themeList to {"dark", "dataviz", "material", "kelly", "frozen", "moonrisekingdom", "spiritedaway"}

set aSel to (choose from list themeList with prompt "Select Theme")
if aSel = false then
  set aTheme to false
  
set aHTML to "index_notheme.html"
else
  set aTheme to contents of first item of aSel
  
if aTheme = "dark" then
    set aTheme to false
    
set aHTML to "index_dark.html"
  else
    set aHTML to "index.html"
  end if
end if

set aList to {{label:"ひよこ王国", value:403}, {label:"ぴよぴよ連邦", value:301}, {label:"ぴよランド", value:101}, {label:"ぴよー", value:65}}
set bList to sortRecListByLabel(aList, {"value"}, {false}) of me –降順ソート

–https://www.amcharts.com/demos/pie-chart/
set mePath to path to me
set resPath to (mePath as string) & "Contents:Resources:" & aHTML
set myStr to (read (resPath as alias) as «class utf8») as string

set jsonStr to array2DToJSONArray(bList) of me as string

if aTheme = false then
  set aString to current application’s NSString’s stringWithFormat_(myStr, jsonStr) as string
else
  set aString to current application’s NSString’s stringWithFormat_(myStr, aTheme, aTheme, jsonStr) as string
end if

set paramObj to {myMessage:"Simple Pie Chart", mySubMessage:"This is a AMCharts test", htmlStr:aString, jsDelimiters:{"<script>", "</script>"}, viewSize:{1000, 550}}

webD’s displayWebDialog(paramObj)

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

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

★Click Here to Open This Script 

Posted in dialog list Sort | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSArray NSJSONSerialization NSMutableArray NSSortDescriptor NSString | Leave a comment

AMChartsでバブルチャート+世界地図をダイアログ上に表示 v2

Posted on 6月 26, 2020 by Takaaki Naganoya

アラートダイアログ上にWkWebViewを作成し、その上でAMChartsによるバブルチャートつき世界地図を表示するAppleScriptです。

–> Download amBubbleMap.zip(Script Bundle with AppleScript Library and HTML)

表示用のデータをAppleScriptのRecord(をListに入れたもの)に変換して、外部から供給するようにして、表示するさいにJSONに変換してHTMLに差し込んで表示しています。

正直、record形式にすると編集が大変なような気がするので、プログラムリスト中から外部に追い出して、plistとかJSONとかいろいろ他の形式で保持しておくといいと思います。もちろん、AppleScriptらしくNumbersの表データ中にデータを展開してもよいのですが、「ならNumbersでグラフ表示させたほうがよいのでは?」というところなので、あえて触れませんでした。

AMChart掲載のグラフはデータを差し込みやすくていいですね。

AppleScript名:AMChartsでバブルチャート+世界地図をダイアログ上に表示 v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/06/25
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use webD : script "webDialogLib"

set aList to retData() of me
set jStr to array2DToJSONArray(aList) of me as string

–https://www.zingchart.com/
set mePath to path to me
set resPath to (mePath as string) & "Contents:Resources:index.html"
set myStr to read (resPath as alias) as «class utf8»

set aString to current application’s NSString’s stringWithFormat_(myStr, jStr) as string

set paramObj to {myMessage:"Map with Bubbles", mySubMessage:"This is a AMCharts test", htmlStr:aString, jsDelimiters:{"<script>", "</script>"}, viewSize:{1000, 620}}

webD’s displayWebDialog(paramObj)

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

on retData()
  return {{|id|:"AF", |name|:"Afghanistan", value:32358260, |color|:"#ff0000"}, {|id|:"AL", |name|:"Albania", value:3215988, |color|:"#00ff00"}, {|id|:"DZ", |name|:"Algeria", value:35980193, |color|:"#0000ff"}, {|id|:"AO", |name|:"Angola", value:19618432, |color|:"#0000ff"}, {|id|:"AR", |name|:"Argentina", value:40764561, |color|:"#ffff00"}, {|id|:"AM", |name|:"Armenia", value:3100236, |color|:"#00ff00"}, {|id|:"AU", |name|:"Australia", value:22605732, |color|:"#8aabb0"}, {|id|:"AT", |name|:"Austria", value:8413429, |color|:"#00ff00"}, {|id|:"AZ", |name|:"Azerbaijan", value:9306023, |color|:"#00ff00"}, {|id|:"BH", |name|:"Bahrain", value:1323535, |color|:"#ff0000"}, {|id|:"BD", |name|:"Bangladesh", value:150493658, |color|:"#ff0000"}, {|id|:"BY", |name|:"Belarus", value:9559441, |color|:"#00ff00"}, {|id|:"BE", |name|:"Belgium", value:10754056, |color|:"#00ff00"}, {|id|:"BJ", |name|:"Benin", value:9099922, |color|:"#0000ff"}, {|id|:"BT", |name|:"Bhutan", value:738267, |color|:"#ff0000"}, {|id|:"BO", |name|:"Bolivia", value:10088108, |color|:"#ffff00"}, {|id|:"BA", |name|:"Bosnia and Herzegovina", value:3752228, |color|:"#00ff00"}, {|id|:"BW", |name|:"Botswana", value:2030738, |color|:"#0000ff"}, {|id|:"BR", |name|:"Brazil", value:196655014, |color|:"#ffff00"}, {|id|:"BN", |name|:"Brunei", value:405938, |color|:"#ff0000"}, {|id|:"BG", |name|:"Bulgaria", value:7446135, |color|:"#00ff00"}, {|id|:"BF", |name|:"Burkina Faso", value:16967845, |color|:"#0000ff"}, {|id|:"BI", |name|:"Burundi", value:8575172, |color|:"#0000ff"}, {|id|:"KH", |name|:"Cambodia", value:14305183, |color|:"#ff0000"}, {|id|:"CM", |name|:"Cameroon", value:20030362, |color|:"#0000ff"}, {|id|:"CA", |name|:"Canada", value:34349561, |color|:"#888822"}, {|id|:"CV", |name|:"Cape Verde", value:500585, |color|:"#0000ff"}, {|id|:"CF", |name|:"Central African Rep.", value:4486837, |color|:"#0000ff"}, {|id|:"TD", |name|:"Chad", value:11525496, |color|:"#0000ff"}, {|id|:"CL", |name|:"Chile", value:17269525, |color|:"#ffff00"}, {|id|:"CN", |name|:"China", value:1.347565324E+9, |color|:"#ff0000"}, {|id|:"CO", |name|:"Colombia", value:46927125, |color|:"#ffff00"}, {|id|:"KM", |name|:"Comoros", value:753943, |color|:"#0000ff"}, {|id|:"CD", |name|:"Congo, Dem. Rep.", value:67757577, |color|:"#0000ff"}, {|id|:"CG", |name|:"Congo, Rep.", value:4139748, |color|:"#0000ff"}, {|id|:"CR", |name|:"Costa Rica", value:4726575, |color|:"#888822"}, {|id|:"CI", |name|:"Cote d’Ivoire", value:20152894, |color|:"#0000ff"}, {|id|:"HR", |name|:"Croatia", value:4395560, |color|:"#00ff00"}, {|id|:"CU", |name|:"Cuba", value:11253665, |color|:"#888822"}, {|id|:"CY", |name|:"Cyprus", value:1116564, |color|:"#00ff00"}, {|id|:"CZ", |name|:"Czech Rep.", value:10534293, |color|:"#00ff00"}, {|id|:"DK", |name|:"Denmark", value:5572594, |color|:"#00ff00"}, {|id|:"DJ", |name|:"Djibouti", value:905564, |color|:"#0000ff"}, {|id|:"DO", |name|:"Dominican Rep.", value:10056181, |color|:"#888822"}, {|id|:"EC", |name|:"Ecuador", value:14666055, |color|:"#ffff00"}, {|id|:"EG", |name|:"Egypt", value:82536770, |color|:"#0000ff"}, {|id|:"SV", |name|:"El Salvador", value:6227491, |color|:"#888822"}, {|id|:"GQ", |name|:"Equatorial Guinea", value:720213, |color|:"#0000ff"}, {|id|:"ER", |name|:"Eritrea", value:5415280, |color|:"#0000ff"}, {|id|:"EE", |name|:"Estonia", value:1340537, |color|:"#00ff00"}, {|id|:"ET", |name|:"Ethiopia", value:84734262, |color|:"#0000ff"}, {|id|:"FJ", |name|:"Fiji", value:868406, |color|:"#8aabb0"}, {|id|:"FI", |name|:"Finland", value:5384770, |color|:"#00ff00"}, {|id|:"FR", |name|:"France", value:63125894, |color|:"#00ff00"}, {|id|:"GA", |name|:"Gabon", value:1534262, |color|:"#0000ff"}, {|id|:"GM", |name|:"Gambia", value:1776103, |color|:"#0000ff"}, {|id|:"GE", |name|:"Georgia", value:4329026, |color|:"#00ff00"}, {|id|:"DE", |name|:"Germany", value:82162512, |color|:"#00ff00"}, {|id|:"GH", |name|:"Ghana", value:24965816, |color|:"#0000ff"}, {|id|:"GR", |name|:"Greece", value:11390031, |color|:"#00ff00"}, {|id|:"GT", |name|:"Guatemala", value:14757316, |color|:"#888822"}, {|id|:"GN", |name|:"Guinea", value:10221808, |color|:"#0000ff"}, {|id|:"GW", |name|:"Guinea-Bissau", value:1547061, |color|:"#0000ff"}, {|id|:"GY", |name|:"Guyana", value:756040, |color|:"#ffff00"}, {|id|:"HT", |name|:"Haiti", value:10123787, |color|:"#888822"}, {|id|:"HN", |name|:"Honduras", value:7754687, |color|:"#888822"}, {|id|:"HK", |name|:"Hong Kong, China", value:7122187, |color|:"#ff0000"}, {|id|:"HU", |name|:"Hungary", value:9966116, |color|:"#00ff00"}, {|id|:"IS", |name|:"Iceland", value:324366, |color|:"#00ff00"}, {|id|:"IN", |name|:"India", value:1.24149196E+9, |color|:"#ff0000"}, {|id|:"ID", |name|:"Indonesia", value:242325638, |color|:"#ff0000"}, {|id|:"IR", |name|:"Iran", value:74798599, |color|:"#ff0000"}, {|id|:"IQ", |name|:"Iraq", value:32664942, |color|:"#ff0000"}, {|id|:"IE", |name|:"Ireland", value:4525802, |color|:"#00ff00"}, {|id|:"IL", |name|:"Israel", value:7562194, |color|:"#ff0000"}, {|id|:"IT", |name|:"Italy", value:60788694, |color|:"#00ff00"}, {|id|:"JM", |name|:"Jamaica", value:2751273, |color|:"#888822"}, {|id|:"JP", |name|:"Japan", value:126497241, |color|:"#ff0000"}, {|id|:"JO", |name|:"Jordan", value:6330169, |color|:"#ff0000"}, {|id|:"KZ", |name|:"Kazakhstan", value:16206750, |color|:"#ff0000"}, {|id|:"KE", |name|:"Kenya", value:41609728, |color|:"#0000ff"}, {|id|:"KP", |name|:"Korea, Dem. Rep.", value:24451285, |color|:"#ff0000"}, {|id|:"KR", |name|:"Korea, Rep.", value:48391343, |color|:"#ff0000"}, {|id|:"KW", |name|:"Kuwait", value:2818042, |color|:"#ff0000"}, {|id|:"KG", |name|:"Kyrgyzstan", value:5392580, |color|:"#ff0000"}, {|id|:"LA", |name|:"Laos", value:6288037, |color|:"#ff0000"}, {|id|:"LV", |name|:"Latvia", value:2243142, |color|:"#00ff00"}, {|id|:"LB", |name|:"Lebanon", value:4259405, |color|:"#ff0000"}, {|id|:"LS", |name|:"Lesotho", value:2193843, |color|:"#0000ff"}, {|id|:"LR", |name|:"Liberia", value:4128572, |color|:"#0000ff"}, {|id|:"LY", |name|:"Libya", value:6422772, |color|:"#0000ff"}, {|id|:"LT", |name|:"Lithuania", value:3307481, |color|:"#00ff00"}, {|id|:"LU", |name|:"Luxembourg", value:515941, |color|:"#00ff00"}, {|id|:"MK", |name|:"Macedonia, FYR", value:2063893, |color|:"#00ff00"}, {|id|:"MG", |name|:"Madagascar", value:21315135, |color|:"#0000ff"}, {|id|:"MW", |name|:"Malawi", value:15380888, |color|:"#0000ff"}, {|id|:"MY", |name|:"Malaysia", value:28859154, |color|:"#ff0000"}, {|id|:"ML", |name|:"Mali", value:15839538, |color|:"#0000ff"}, {|id|:"MR", |name|:"Mauritania", value:3541540, |color|:"#0000ff"}, {|id|:"MU", |name|:"Mauritius", value:1306593, |color|:"#0000ff"}, {|id|:"MX", |name|:"Mexico", value:114793341, |color|:"#888822"}, {|id|:"MD", |name|:"Moldova", value:3544864, |color|:"#00ff00"}, {|id|:"MN", |name|:"Mongolia", value:2800114, |color|:"#ff0000"}, {|id|:"ME", |name|:"Montenegro", value:632261, |color|:"#00ff00"}, {|id|:"MA", |name|:"Morocco", value:32272974, |color|:"#0000ff"}, {|id|:"MZ", |name|:"Mozambique", value:23929708, |color|:"#0000ff"}, {|id|:"MM", |name|:"Myanmar", value:48336763, |color|:"#ff0000"}, {|id|:"NA", |name|:"Namibia", value:2324004, |color|:"#0000ff"}, {|id|:"NP", |name|:"Nepal", value:30485798, |color|:"#ff0000"}, {|id|:"NL", |name|:"Netherlands", value:16664746, |color|:"#00ff00"}, {|id|:"NZ", |name|:"New Zealand", value:4414509, |color|:"#8aabb0"}, {|id|:"NI", |name|:"Nicaragua", value:5869859, |color|:"#888822"}, {|id|:"NE", |name|:"Niger", value:16068994, |color|:"#0000ff"}, {|id|:"NG", |name|:"Nigeria", value:162470737, |color|:"#0000ff"}, {|id|:"NO", |name|:"Norway", value:4924848, |color|:"#00ff00"}, {|id|:"OM", |name|:"Oman", value:2846145, |color|:"#ff0000"}, {|id|:"PK", |name|:"Pakistan", value:176745364, |color|:"#ff0000"}, {|id|:"PA", |name|:"Panama", value:3571185, |color|:"#888822"}, {|id|:"PG", |name|:"Papua New Guinea", value:7013829, |color|:"#8aabb0"}, {|id|:"PY", |name|:"Paraguay", value:6568290, |color|:"#ffff00"}, {|id|:"PE", |name|:"Peru", value:29399817, |color|:"#ffff00"}, {|id|:"PH", |name|:"Philippines", value:94852030, |color|:"#ff0000"}, {|id|:"PL", |name|:"Poland", value:38298949, |color|:"#00ff00"}, {|id|:"PT", |name|:"Portugal", value:10689663, |color|:"#00ff00"}, {|id|:"PR", |name|:"Puerto Rico", value:3745526, |color|:"#888822"}, {|id|:"QA", |name|:"Qatar", value:1870041, |color|:"#ff0000"}, {|id|:"RO", |name|:"Romania", value:21436495, |color|:"#00ff00"}, {|id|:"RU", |name|:"Russia", value:142835555, |color|:"#00ff00"}, {|id|:"RW", |name|:"Rwanda", value:10942950, |color|:"#0000ff"}, {|id|:"SA", |name|:"Saudi Arabia", value:28082541, |color|:"#ff0000"}, {|id|:"SN", |name|:"Senegal", value:12767556, |color|:"#0000ff"}, {|id|:"RS", |name|:"Serbia", value:9853969, |color|:"#00ff00"}, {|id|:"SL", |name|:"Sierra Leone", value:5997486, |color|:"#0000ff"}, {|id|:"SG", |name|:"Singapore", value:5187933, |color|:"#ff0000"}, {|id|:"SK", |name|:"Slovak Republic", value:5471502, |color|:"#00ff00"}, {|id|:"SI", |name|:"Slovenia", value:2035012, |color|:"#00ff00"}, {|id|:"SB", |name|:"Solomon Islands", value:552267, |color|:"#8aabb0"}, {|id|:"SO", |name|:"Somalia", value:9556873, |color|:"#0000ff"}, {|id|:"ZA", |name|:"South Africa", value:50459978, |color|:"#0000ff"}, {|id|:"ES", |name|:"Spain", value:46454895, |color|:"#00ff00"}, {|id|:"LK", |name|:"Sri Lanka", value:21045394, |color|:"#ff0000"}, {|id|:"SD", |name|:"Sudan", value:34735288, |color|:"#0000ff"}, {|id|:"SR", |name|:"Suriname", value:529419, |color|:"#ffff00"}, {|id|:"SZ", |name|:"Swaziland", value:1203330, |color|:"#0000ff"}, {|id|:"SE", |name|:"Sweden", value:9440747, |color|:"#00ff00"}, {|id|:"CH", |name|:"Switzerland", value:7701690, |color|:"#00ff00"}, {|id|:"SY", |name|:"Syria", value:20766037, |color|:"#ff0000"}, {|id|:"TW", |name|:"Taiwan", value:23072000, |color|:"#ff0000"}, {|id|:"TJ", |name|:"Tajikistan", value:6976958, |color|:"#ff0000"}, {|id|:"TZ", |name|:"Tanzania", value:46218486, |color|:"#0000ff"}, {|id|:"TH", |name|:"Thailand", value:69518555, |color|:"#ff0000"}, {|id|:"TG", |name|:"Togo", value:6154813, |color|:"#0000ff"}, {|id|:"TT", |name|:"Trinidad and Tobago", value:1346350, |color|:"#888822"}, {|id|:"TN", |name|:"Tunisia", value:10594057, |color|:"#0000ff"}, {|id|:"TR", |name|:"Turkey", value:73639596, |color|:"#00ff00"}, {|id|:"TM", |name|:"Turkmenistan", value:5105301, |color|:"#ff0000"}, {|id|:"UG", |name|:"Uganda", value:34509205, |color|:"#0000ff"}, {|id|:"UA", |name|:"Ukraine", value:45190180, |color|:"#00ff00"}, {|id|:"AE", |name|:"United Arab Emirates", value:7890924, |color|:"#ff0000"}, {|id|:"GB", |name|:"United Kingdom", value:62417431, |color|:"#00ff00"}, {|id|:"US", |name|:"United States", value:313085380, |color|:"#888822"}, {|id|:"UY", |name|:"Uruguay", value:3380008, |color|:"#ffff00"}, {|id|:"UZ", |name|:"Uzbekistan", value:27760267, |color|:"#ff0000"}, {|id|:"VE", |name|:"Venezuela", value:29436891, |color|:"#ffff00"}, {|id|:"PS", |name|:"West Bank and Gaza", value:4152369, |color|:"#ff0000"}, {|id|:"VN", |name|:"Vietnam", value:88791996, |color|:"#ff0000"}, {|id|:"YE", |name|:"Yemen, Rep.", value:24799880, |color|:"#ff0000"}, {|id|:"ZM", |name|:"Zambia", value:13474959, |color|:"#0000ff"}, {|id|:"ZW", |name|:"Zimbabwe", value:12754378, |color|:"#0000ff"}}
end retData

★Click Here to Open This Script 

Posted in dialog JSON list Record | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSJSONSerialization NSMutableArray NSString | Leave a comment

AMChartsで点滅ポイントつき世界地図をダイアログ上に表示 v2

Posted on 6月 25, 2020 by Takaaki Naganoya

アラートダイアログ上にWkWebViewを作成し、その上でAMChartsによる点滅ポイントつき世界地図を表示するAppleScriptです。

このアラートダイアログによる「箱庭UI」シリーズも、なかなか実用性のあるソリューションにつながる例が少なくて、インパクトとかウケ狙いのものが多いですが、これにはけっこうな実用性を感じました。

世界地図上にプロットする必要のあるデータというのはなかなかありませんが、必要がある場合にはこのように部品として使えるところまで飼い慣らしてあるので、有用性は高いと思われます。

–> Download displayAMChart (Script Bundle with Library and HTML)


▲macOS 11.0Betaでも動きます

AppleScript名:AMChartsで点滅ポイントつき世界地図をダイアログ上に表示 v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/06/23
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use webD : script "webDialogLib"

set zoomScale to 4 –Flash Radius

–Not actual location
set aList to {{title:"Shane Stanley", latitude:-33.5206, longitude:151.1231, |color|:"#0000ff", |url|:"https://latenightsw.com"}, {title:"Takaaki Naganoya (me)", latitude:35.6785, longitude:139.6823, |color|:"#ff0000", |url|:"http://piyocast.com"}, {title:"Jean-Christophe Helary", latitude:34.349399, longitude:134.025012, |color|:"#0000ff", |url|:"http://mac4translators.blogspot.com"}, {title:"Yvan KOENIG", latitude:43.57803, longitude:7.05451, |color|:"#0000ff"}, {title:"Ed Stockly", latitude:34.052235, longitude:-118.243683, |color|:"#0000ff", |url|:"https://www.latimes.com"}, {title:"Mark Alldritt", latitude:45.2512, longitude:-75.42, |color|:"#0000ff", |url|:"https://latenightsw.com"}}

–https://www.amcharts.com/demos/zooming-to-countries-map/
set mePath to path to me
set resPath to (mePath as string) & "Contents:Resources:index.html"
set myStr to read (resPath as alias) as «class utf8»

set jStr to array2DToJSONArray(aList) of me
set aString to current application’s NSString’s stringWithFormat_(myStr, zoomScale as string, jStr) as string

set paramObj to {myMessage:"AppleScripters I know the location", mySubMessage:"This is a AMCharts test", htmlStr:aString, jsDelimiters:{"<script>", "</script>"}, viewSize:{1000, 520}}

webD’s displayWebDialog(paramObj)

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

★Click Here to Open This Script 

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

アラートダイアログ上にWebViewでCesiumを用いて地球儀上に地図を表示

Posted on 6月 21, 2020 by Takaaki Naganoya

アラートダイアログ上にWkWebViewを敷いて、Cesiumを呼び出して地球儀上に地図を表示するAppleScriptです。

もともとのコードは国土地理院のサイトで見つけたものなのですが、地球儀上の地図表示が行えるようです。地球儀以外にも、メルカトル図法などの地図っぽい表示も可能。

右上のメニューから、地図の種類を選択して指定できます。マウスホイールでズームします。

白黒で表示された地図がなかなか面白いところです。

AppleScript名:アラートダイアログ上にWebViewでCesiumを用いて地球儀上に地図を表示.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/06/20
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use framework "WebKit"
use scripting additions

property |NSURL| : a reference to current application’s |NSURL|
property NSAlert : a reference to current application’s NSAlert
property NSString : a reference to current application’s NSString
property NSButton : a reference to current application’s NSButton
property WKWebView : a reference to current application’s WKWebView
property WKUserScript : a reference to current application’s WKUserScript
property NSURLRequest : a reference to current application’s NSURLRequest
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding
property WKUserContentController : a reference to current application’s WKUserContentController
property WKWebViewConfiguration : a reference to current application’s WKWebViewConfiguration
property WKUserScriptInjectionTimeAtDocumentEnd : a reference to current application’s WKUserScriptInjectionTimeAtDocumentEnd

property returnCode : 0

–set aRecArray to {{5, 20}, {25, 67}, {85, 21}, {100, 33}, {220, 88}, {250, 50}, {330, 95}, {410, 12}, {475, 44}, {480, 90}}
–set jsonStr to array2DToJSONArray(aRecArray) of me

–https://github.com/gsi-cyberjapan/gsitiles-cesium/blob/gh-pages/index.html
set myStr to "<!DOCTYPE html>
<html>
<head>
<meta charset=\"UTF-8\">
<title>GSI Tiles on Cesium</title>
<script src=\"https://cesium.com/downloads/cesiumjs/releases/1.63.1/Build/Cesium/Cesium.js\"></script>
<link href=\"https://cesium.com/downloads/cesiumjs/releases/1.63.1/Build/Cesium/Widgets/widgets.css\" rel=\"stylesheet\">
<style>
#cesiumContainer {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
margin: 0;
overflow: hidden;
padding: 0;
font-family: sans-serif;
}
html {
height: 100%;
}
body {
padding: 0;
margin: 0;
overflow: hidden;
height: 100%;
}
</style>
</head>

<body>
<div id=\"cesiumContainer\"></div>
<script>
var viewer = new Cesium.Viewer(’cesiumContainer’, {
imageryProvider: new Cesium.createOpenStreetMapImageryProvider({
url: ’https://cyberjapandata.gsi.go.jp/xyz/std/’,
credit: new Cesium.Credit(’地理院タイル’, ’’, ’https://maps.gsi.go.jp/development/ichiran.html’)
}),
baseLayerPicker: true,
geocoder: false,
homeButton: false
});

viewer.camera.setView({
destination : Cesium.Cartesian3.fromDegrees(140.00, 36.14, 20000000.0)
});
</script>
</body>
</html>"

–set aString to current application’s NSString’s stringWithFormat_(myStr, jsonStr) as string

set paramObj to {myMessage:"Cesium Test", mySubMessage:"This is a Cesium test", htmlStr:myStr}
–my browseStrWebContents:paramObj–for debug
my performSelectorOnMainThread:"browseStrWebContents:" withObject:(paramObj) waitUntilDone:true

on browseStrWebContents:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set htmlString to (htmlStr of paramObj)
  
  
set aWidth to 1220
  
set aHeight to 720
  
  
–WebViewをつくる
  
set aConf to WKWebViewConfiguration’s alloc()’s init()
  
  
–指定HTML内のJavaScriptをFetch
  
set jsSource to pickUpFromToStr(htmlString, "<script>", "</script>") of me
  
  
set userScript to WKUserScript’s alloc()’s initWithSource:jsSource injectionTime:(WKUserScriptInjectionTimeAtDocumentEnd) forMainFrameOnly:true
  
set userContentController to WKUserContentController’s alloc()’s init()
  
userContentController’s addUserScript:(userScript)
  
aConf’s setUserContentController:userContentController
  
  
set aWebView to WKWebView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight)) configuration:aConf
  
aWebView’s setNavigationDelegate:me
  
aWebView’s setUIDelegate:me
  
aWebView’s setTranslatesAutoresizingMaskIntoConstraints:true
  
using terms from scripting additions
    set bURL to |NSURL|’s fileURLWithPath:(POSIX path of (path to me))
  end using terms from
  
aWebView’s loadHTMLString:htmlString baseURL:(bURL)
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
–its addButtonWithTitle:"Cancel"
    
its setAccessoryView:aWebView
    
    
set myWindow to its |window|
  end tell
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
  
–Stop Web View Action
  
set bURL to |NSURL|’s URLWithString:"about:blank"
  
set bReq to NSURLRequest’s requestWithURL:bURL
  
aWebView’s loadRequest:bReq
  
  
if (my returnCode as number) = 1001 then error number -128
end browseStrWebContents:

on doModal:aParam
  set (my returnCode) to (aParam’s runModal()) as number
end doModal:

on viewDidLoad:aNotification
  return true
end viewDidLoad:

on fetchJSSourceString(aURL)
  set jsURL to |NSURL|’s URLWithString:aURL
  
set jsSourceString to NSString’s stringWithContentsOfURL:jsURL encoding:(NSUTF8StringEncoding) |error|:(missing value)
  
return jsSourceString
end fetchJSSourceString

on pickUpFromToStr(aStr as string, s1Str as string, s2Str as string)
  set a1Offset to offset of s1Str in aStr
  
if a1Offset = 0 then return false
  
set bStr to text (a1Offset + (length of s1Str)) thru -1 of aStr
  
set a2Offset to offset of s2Str in bStr
  
if a2Offset = 0 then return false
  
set cStr to text 1 thru (a2Offset – (length of s2Str)) of bStr
  
return cStr as string
end pickUpFromToStr

–リストを任意のデリミタ付きでテキストに
on retArrowText(aList, aDelim)
  set aText to ""
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retArrowText

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

on parseByDelim(aData, aDelim)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set dList to text items of aData
  
set AppleScript’s text item delimiters to curDelim
  
return dList
end parseByDelim

★Click Here to Open This Script 

Posted in dialog JavaScript JSON | Tagged 10.13savvy 10.14savvy 10.15savvy NSAlert NSButton NSRunningApplication NSString NSURL NSURLRequest NSUTF8StringEncoding WKUserContentController WKUserScript WKUserScriptInjectionTimeAtDocumentEnd WKWebView WKWebViewConfiguration | Leave a comment

アラートダイアログ上のWebViewでGio.jsを用いて地球儀+データアニメーション表示 v2a

Posted on 6月 20, 2020 by Takaaki Naganoya

アラートダイアログ上にWkWebViewを配置し、その上にGio.jsによる地球儀+グラフデータ(アニメーション)を表示するAppleScriptです。

Gio.jsは国際間の貿易収支、Webトラフィックなどの可視化を行うさいに利用するライブラリのようです。さまざまな可視化サンプルをかき集めて、実際にWkWebViewで表示できたもののうち、再利用しやすく利用価値の高そうなものということで、このGio.jsを選んでみました。

派手なビジュアライズの部品はいろいろ見て回りましたが、割とすぐ慣れるというか、飽きるというべきなのか、派手に見せたところで実用性はさほど高まらないといった悟りを得るに至った次第です。

本ScriptはAppleScript側のオブジェクトで与えたデータをもとに表示内容を変更するところまでは作り込んでいませんが、一応、Gio.jsをCDN上のものを呼び出すように書き換えておきました。

AppleScript名:アラートダイアログ上にWebViewでGio.jsを用いて地球儀上にデータアニメーションを表示 v2a.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/06/20
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use framework "WebKit"
use scripting additions

property |NSURL| : a reference to current application’s |NSURL|
property NSAlert : a reference to current application’s NSAlert
property NSString : a reference to current application’s NSString
property NSButton : a reference to current application’s NSButton
property WKWebView : a reference to current application’s WKWebView
property WKUserScript : a reference to current application’s WKUserScript
property NSURLRequest : a reference to current application’s NSURLRequest
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding
property WKUserContentController : a reference to current application’s WKUserContentController
property WKWebViewConfiguration : a reference to current application’s WKWebViewConfiguration
property WKUserScriptInjectionTimeAtDocumentEnd : a reference to current application’s WKUserScriptInjectionTimeAtDocumentEnd

property returnCode : 0

–set aRecArray to {{5, 20}, {25, 67}, {85, 21}, {100, 33}, {220, 88}, {250, 50}, {330, 95}, {410, 12}, {475, 44}, {480, 90}}
–set jsonStr to array2DToJSONArray(aRecArray) of me

–https://github.com/webhacck/gio-js-sample/blob/master/sample2.html
set myStr to "<!DOCTYPE html>
<html>
<head>
<title>Gio.js sample</title>
<meta charset=\"utf-8\">
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
</head>
<body>

<div id=\"globalArea\" style=\"width:1000px;height:700px\"></div>

  <script src=\"https://threejs.org/build/three.min.js\"></script>
  <script src=\"https://cdn.jsdelivr.net/npm/giojs@2.2.1/build/gio.min.js\"></script>
  <script>

var container = document.getElementById( \"globalArea\" );

//config用のオプション設定
var config = {
\"control\": {
\"stats\": false,
\"disableUnmentioned\": false,
\"lightenMentioned\": true,
\"inOnly\": false,
\"outOnly\": false,
\"initCountry\": \"JP\",
\"halo\": true
},
\"color\": {
\"surface\": 1744048,
\"selected\": 2141154,
\"in\": 16765762,
\"out\": 5366382,
\"halo\": 2141154,
\"background\": 0
},
\"brightness\": {
\"ocean\": 0.95,
\"mentioned\": 0.28,
\"related\": 0.74
}
};


//dataset
var data= [
{ e: \"JP\", i: \"CN\", v: 8000000 },
{ e: \"JP\", i: \"TH\", v: 3000000 },
{ e: \"JP\", i: \"ID\", v: 1000000 },
{ e: \"US\", i: \"JP\", v: 8000000 },
{ e: \"RU\", i: \"JP\", v: 3000000 },
{ e: \"IN\", i: \"JP\", v: 1000000 }]

//第2引数にconfigを設定する
var controller = new GIO.Controller( container, config );

controller.addData( data );
controller.init();

</script>

</body>
</html>"

–set aString to current application’s NSString’s stringWithFormat_(myStr, jsonStr) as string

set paramObj to {myMessage:"Gio.js Test", mySubMessage:"This is a Gio.js test", htmlStr:myStr}
–my browseStrWebContents:paramObj–for debug
my performSelectorOnMainThread:"browseStrWebContents:" withObject:(paramObj) waitUntilDone:true

on browseStrWebContents:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set htmlString to (htmlStr of paramObj)
  
  
set aWidth to 1020
  
set aHeight to 720
  
  
–WebViewをつくる
  
set aConf to WKWebViewConfiguration’s alloc()’s init()
  
  
–指定HTML内のJavaScriptをFetch
  
set jsSource to pickUpFromToStr(htmlString, "<script>", "</script>") of me
  
  
set userScript to WKUserScript’s alloc()’s initWithSource:jsSource injectionTime:(WKUserScriptInjectionTimeAtDocumentEnd) forMainFrameOnly:true
  
set userContentController to WKUserContentController’s alloc()’s init()
  
userContentController’s addUserScript:(userScript)
  
aConf’s setUserContentController:userContentController
  
  
set aWebView to WKWebView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight)) configuration:aConf
  
aWebView’s setNavigationDelegate:me
  
aWebView’s setUIDelegate:me
  
aWebView’s setTranslatesAutoresizingMaskIntoConstraints:true
  
using terms from scripting additions
    set bURL to |NSURL|’s fileURLWithPath:(POSIX path of (path to me))
  end using terms from
  
aWebView’s loadHTMLString:htmlString baseURL:(bURL)
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
–its addButtonWithTitle:"Cancel"
    
its setAccessoryView:aWebView
    
    
set myWindow to its |window|
  end tell
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
  
–Stop Web View Action
  
set bURL to |NSURL|’s URLWithString:"about:blank"
  
set bReq to NSURLRequest’s requestWithURL:bURL
  
aWebView’s loadRequest:bReq
  
  
if (my returnCode as number) = 1001 then error number -128
end browseStrWebContents:

on doModal:aParam
  set (my returnCode) to (aParam’s runModal()) as number
end doModal:

on viewDidLoad:aNotification
  return true
end viewDidLoad:

on fetchJSSourceString(aURL)
  set jsURL to |NSURL|’s URLWithString:aURL
  
set jsSourceString to NSString’s stringWithContentsOfURL:jsURL encoding:(NSUTF8StringEncoding) |error|:(missing value)
  
return jsSourceString
end fetchJSSourceString

on pickUpFromToStr(aStr as string, s1Str as string, s2Str as string)
  set a1Offset to offset of s1Str in aStr
  
if a1Offset = 0 then return false
  
set bStr to text (a1Offset + (length of s1Str)) thru -1 of aStr
  
set a2Offset to offset of s2Str in bStr
  
if a2Offset = 0 then return false
  
set cStr to text 1 thru (a2Offset – (length of s2Str)) of bStr
  
return cStr as string
end pickUpFromToStr

–リストを任意のデリミタ付きでテキストに
on retArrowText(aList, aDelim)
  set aText to ""
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retArrowText

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

on parseByDelim(aData, aDelim)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set dList to text items of aData
  
set AppleScript’s text item delimiters to curDelim
  
return dList
end parseByDelim

★Click Here to Open This Script 

Posted in dialog | Tagged 10.13savvy 10.14savvy 10.15savvy NSAlert NSButton NSRunningApplication NSString NSURL NSURLRequest NSUTF8StringEncoding WKUserContentController WKUserScript WKUserScriptInjectionTimeAtDocumentEnd WKWebView WKWebViewConfiguration | Leave a comment

指定のPDFからTOCを削除する

Posted on 6月 19, 2020 by Takaaki Naganoya

指定のPDFからTOCを削除して別名保存するAppleScriptです。

TOCを削除した新規ファイルは元ファイルと同じ場所に枝番つきで重複回避しつつ作成されます。

33MBで257ページほどあるPDFで、詳細に目次から記事へのリンクを手動で作成し、TOCを手動で作ったところ、Adobe Actobatが、

などというメッセージを出して保存ができなかったので、中途半端に1個だけエントリが残ったTOCを削除するために用意したものです(既存のScriptに機能があったので、削除機能だけ抽出)。

AppleScript名:指定のPDFからTOCを削除する.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2018/08/18
—
–  Copyright © 2018 Piyomaru Software, All Rights Reserved
—

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

property |NSURL| : a reference to current application’s |NSURL|
property NSString : a reference to current application’s NSString
property PDFDocument : a reference to current application’s PDFDocument
property NSFileManager : a reference to current application’s NSFileManager

–PDFの指定
set aFile to choose file of type {"pdf"} with prompt (progress additional description)
set filePath to aFile’s POSIX path

set fileURL to |NSURL|’s fileURLWithPath:filePath
set aPDFdoc to PDFDocument’s alloc()’s initWithURL:fileURL
set parentOL to aPDFdoc’s outlineRoot()

if parentOL is equal to missing value then
  display dialog "There is no TOC with this PDF"
  
return
end if

set outLineCount to parentOL’s numberOfChildren()
set outLineCount to outLineCount as number

–既存のTOCを削除
repeat with num from (outLineCount – 1) to 0 by -1
  (parentOL’s childAtIndex:num)’s removeFromParent()
end repeat

–保存
set progress description to "PDFを保存"
set progress additional description to "保存先の確認"
tell (NSString’s stringWithString:filePath)
  set parentPath to stringByDeletingLastPathComponent() –>親フォルダ
  
set longFileName to lastPathComponent() –>拡張子ありの名前
end tell
set newFilePath to my pathExists(parentPath, longFileName)

set progress additional description to "書き出し中: " & newFilePath
set newFileURL to |NSURL|’s fileURLWithPath:newFilePath
aPDFdoc’s writeToURL:newFileURL

–名前が重複していないか確認
on pathExists(currentPath as text, fileName as text)
  tell (NSString’s stringWithString:fileName)
    set shortFileName to stringByDeletingPathExtension() as text
    
set aSuffix to pathExtension() as text
  end tell
  
if aSuffix ≠ "" then set aSuffix to "." & aSuffix as text
  
  
set currentPath to NSString’s stringWithString:currentPath
  
set unkonwnPath to (currentPath’s stringByAppendingPathComponent:fileName)
  
  
set aSpace to space
  
set num to 0
  
  
repeat while ((NSFileManager’s defaultManager)’s fileExistsAtPath:unkonwnPath)
    set num to num + 1
    
set tmpName to shortFileName & aSpace & num & aSuffix as text
    
set unkonwnPath to (currentPath’s stringByAppendingPathComponent:tmpName)
  end repeat
  
  
return (unkonwnPath as text)
end pathExists

★Click Here to Open This Script 

Posted in file PDF | Tagged 10.13savvy 10.14savvy 10.15savvy NSFileManager NSString NSURL PDFDocument | Leave a comment

Post navigation

  • Older posts

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

Google Search

Popular posts

  • 開発機としてM2 Mac miniが来たのでガチレビュー
  • macOS 13.6.5 AS系のバグ、一切直らず
  • CotEditorで2つの書類の行単位での差分検出
  • Apple純正マウス、キーボードのバッテリー残量取得
  • macOS 15, Sequoia
  • 初心者がつまづきやすい「log」コマンド
  • 指定のWordファイルをPDFに書き出す
  • Adobe AcrobatをAppleScriptから操作してPDF圧縮
  • メキシカンハットの描画
  • Pages本執筆中に、2つの書類モード切り替えに気がついた
  • 与えられた文字列の1D Listのすべての順列組み合わせパターン文字列を返す v3(ベンチマーク用)
  • 2023年に書いた価値あるAppleScript
  • Pixelmator Pro v3.6.4でAppleScriptからの操作時の挙動に違和感が
  • AdobeがInDesign v19.4からPOSIX pathを採用
  • Safariで「プロファイル」機能を使うとAppleScriptの処理に影響
  • Cocoa Scripting Course 続刊計画
  • NaturalLanguage.frameworkでNLEmbeddingの処理が可能な言語をチェック
  • macOS 14.xでScript Menuの実行速度が大幅に下がるバグ
  • Numbersで選択範囲のセルの前後の空白を削除
  • AppleScriptによる並列処理

Tags

10.11savvy (1102) 10.12savvy (1243) 10.13savvy (1392) 10.14savvy (587) 10.15savvy (438) 11.0savvy (283) 12.0savvy (207) 13.0savvy (176) 14.0savvy (126) 15.0savvy (103) CotEditor (64) Finder (51) iTunes (19) Keynote (115) NSAlert (61) NSArray (51) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (53) NSDictionary (28) NSFileManager (23) NSFont (21) NSImage (41) NSJSONSerialization (21) NSMutableArray (63) NSMutableDictionary (22) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (119) NSURL (98) NSURLRequest (23) NSUTF8StringEncoding (30) NSView (33) NSWorkspace (20) Numbers (74) Pages (53) Safari (44) Script Editor (27) WKUserContentController (21) WKUserScript (20) WKWebView (23) WKWebViewConfiguration (22)

カテゴリー

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

アーカイブ

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