AppleScript名:NSPoint(座標)を作成する |
— Created 2017-06-22 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aPoint to current application’s NSMakePoint(100, 100) –> {x:100.0, y:100.0} |
カテゴリー: Record
iTunesライブラリの曲のアーティスト名を集計
iTunesライブラリ中の曲のアーティスト名を集計して、曲数が多い順に集計するAppleScriptです。
アーティスト名のFirst NameとLast Nameの間にスペースが存在している場合としていない場合が(iTunes Music Storeからダウンロード購入した曲でも)混在していたので、こうしたデータのゆらぎに対処しています。
6,827曲のライブラリの集計が、筆者の開発環境(MacBook Pro Retina 2012 Core i7 2.66GHz)で2.7秒ぐらいです。
AppleScript名:iTunesライブラリの曲のアーティスト名を集計 |
— Created 2017-01-07 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "iTunesLibrary" set library to current application’s ITLibrary’s libraryWithAPIVersion:"1.0" |error|:(missing value) if library is equal to missing value then return set allTracks to library’s allMediaItems() set allCount to allTracks’s |count|() set anEnu to allTracks’s objectEnumerator() set newArray to current application’s NSMutableArray’s alloc()’s init() repeat set aPL to anEnu’s nextObject() if aPL = missing value then exit repeat try set aKind to (aPL’s mediaKind) as integer if (aKind as integer) is equal to 2 then –Music, Song set plName to aPL’s artist’s |name| as string set pl2Name to (my changeThis:" " toThat:"" inString:plName) –日本語アーティスト名で姓と名の間にスペースが入っているものがある(表記ゆらぎ)ので対策 newArray’s addObject:(pl2Name) end if on error set aLoc to (aPL’s location’s |path|()) as string –log aLoc end try end repeat set aRes to countItemsByItsAppearance(newArray) of me –> {{theName:"浜田省吾", numberOfTimes:442}, {theName:"B’z", numberOfTimes:379}, {theName:"渡辺岳夫・松山祐士", numberOfTimes:199}, {theName:"VariousArtists", numberOfTimes:192}, {theName:"菅野よう子", numberOfTimes:108}, {theName:"布袋寅泰", numberOfTimes:100}, {theName:"三枝成彰", numberOfTimes:95}, {theName:"宇多田ヒカル", numberOfTimes:94}, {theName:"宮川泰", numberOfTimes:81}, {theName:"MichaelJackson", numberOfTimes:78}, {theName:"稲葉浩志", numberOfTimes:73}, … –出現回数で集計 on countItemsByItsAppearance(aList) set aSet to current application’s NSCountedSet’s alloc()’s initWithArray:aList set bArray to current application’s NSMutableArray’s array() set theEnumerator to aSet’s objectEnumerator() repeat set aValue to theEnumerator’s nextObject() if aValue is missing value then exit repeat bArray’s addObject:(current application’s NSDictionary’s dictionaryWithObjects:{aValue, (aSet’s countForObject:aValue)} forKeys:{"theName", "numberOfTimes"}) end repeat –出現回数(numberOfTimes)で降順ソート set theDesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:"numberOfTimes" ascending:false bArray’s sortUsingDescriptors:{theDesc} return bArray as list end countItemsByItsAppearance on changeThis:findString toThat:repString inString:someText set theString to current application’s NSString’s stringWithString:someText set theString to theString’s stringByReplacingOccurrencesOfString:findString withString:repString options:(current application’s NSRegularExpressionSearch) range:{location:0, |length|:length of someText} return theString as text end changeThis:toThat:inString: |
NSCountedSetでNSDictionaryの登場頻度集計 v2
AppleScript名:NSCountedSetでNSDictionaryの登場頻度集計 v2 |
— Created 2015-09-14 by Takaaki Naganoya — 2015 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aRecList to {{aName:"Piyomaru", aFavorite:"Sleeping"}, {aName:"Piyoko", aFavorite:"TV"}, {aName:"Piyomaru", aFavorite:"Sleeping"}} set aCountedList to countEachRecord(aRecList) –> {{aCount:1, aData:{aName:"Piyoko", aFavorite:"TV"}}, {aCount:2, aData:{aName:"Piyomaru", aFavorite:"Sleeping"}}} on countEachRecord(aRecList) set theCountedSet to current application’s NSCountedSet’s |set|() repeat with i in aRecList set j to contents of i (theCountedSet’s addObject:j) end repeat set theEnumerator to theCountedSet’s objectEnumerator() set anArray to current application’s NSMutableArray’s alloc()’s init() repeat set aDict to current application’s NSMutableDictionary’s alloc()’s init() set aValue to theEnumerator’s nextObject() if aValue is missing value then exit repeat set aCount to theCountedSet’s countForObject:aValue aDict’s setObject:aCount forKey:"aCount" aDict’s setObject:aValue forKey:"aData" anArray’s addObject:aDict end repeat return anArray as list of string or string end countEachRecord |
NSDictionaryのObjectEnumlator, KeyEnumlatorで値列挙
AppleScript名:NSDictionaryのObjectEnumlator, KeyEnumlatorで値列挙 |
— Created 2017-07-30 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aRec to {aaa:1, bbb:2, ccc:3} set aDict to current application’s NSMutableDictionary’s dictionaryWithDictionary:aRec set dEnum to aDict’s objectEnumerator() repeat set aVal to dEnum’s nextObject() if aVal = missing value then exit repeat log aVal (* 15:40:47.098 (* (NSNumber) 1 *) 15:40:47.099 (* (NSNumber) 2 *) 15:40:47.099 (* (NSNumber) 3 *) *) end repeat set kEnum to aDict’s keyEnumerator() repeat set aVal to kEnum’s nextObject() if aVal = missing value then exit repeat log aVal (* 15:50:52.276 (* (NSString) "aaa" *) 15:50:52.276 (* (NSString) "bbb" *) 15:50:52.276 (* (NSString) "ccc" *) *) end repeat |
レコードのうち、最大の値を持つKeyを返す
AppleScript名:レコードのうち、最大の値を持つKeyを返す |
— Created 2016-12-14 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aDict to current application’s NSDictionary’s dictionaryWithDictionary:{sadness:0.01133416, anger:1.03975857E-4, happiness:2.90919736E-4, fear:2.28432211E-4, neutral:0.9830475, contempt:2.4698046E-4, disgust:1.02946949E-4, surprise:0.00464509334} set aMacKey to retMaxValueKey(aDict) of me –> "neutral" on retMaxValueKey(aDict) set aValList to aDict’s allValues() set maxVal to (sort1DNumList(aValList, false) of me)’s firstObject() set keyList to (aDict’s allKeys()) as list repeat with i in keyList set j to contents of i set aTmp to (aDict’s valueForKey:j) set aRes to compareNumerically(maxVal, aTmp) of me if aRes = true then return j end repeat return false end retMaxValueKey –Numerical Strings Compare on compareNumerically(aText as text, bText as text) set aStr to current application’s NSString’s stringWithString:aText return (aStr’s compare:bText options:(current application’s NSNumericSearch)) = current application’s NSOrderedSame end compareNumerically –1D List(数値)をsort / ascOrderがtrueだと昇順ソート、falseだと降順ソート on sort1DNumList(theList, aBool) set theSet to current application’s NSSet’s setWithArray:theList set theDescriptor to current application’s NSSortDescriptor’s sortDescriptorWithKey:(missing value) ascending:aBool set sortedList to theSet’s sortedArrayUsingDescriptors:{theDescriptor} return (sortedList) end sort1DNumList |
レコードの値をクリア v2
AppleScript名:レコードの値をクリア v2 |
— Created 2016-06-06 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.5" use scripting additions use framework "Foundation" set initVal to "" set aaaaaaaRec to {aaa:"111", bbb:2.1234, ccc:-1} set bRec to clearRecordValues(aaaaaaaRec) of me –> {aaa:"", bbb:0, ccc:0} on clearRecordValues(paramRec) set aDic to current application’s NSMutableDictionary’s dictionaryWithDictionary:paramRec set keyList to (aDic’s allKeys() as list) set valList to (aDic’s allValues() as list) repeat with i from 1 to (length of keyList) set aKey to contents of item i of keyList set tmpVal to contents of item i of valList set aClass to class of tmpVal –もともと入っていたデータの型を見て、クリア時の初期値を判定 if aClass is in {number, integer, real} then set initVal to 0 else if aClass is in {string, text, Unicode text} then set initVal to "" else set initVal to missing value end if (aDic’s setValue:initVal forKey:aKey) end repeat return aDic as record end clearRecordValues |
YAMLのじっけん5
AppleScript名:YAMLのじっけん5 |
— Created 2017-02-16 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "YAML" –https://github.com/mirek/YAML.framework –YAMLの文字列からオブジェクトを生成する(1) set aYAMLstr to " — # お好みの映画、ブロック形式 – Casablanca – Spellbound – Notorious — # 買い物リスト、インライン形式、またはフロー形式 [milk, bread, eggs] " set aRes to retObjectFromYAMLString(aYAMLstr) of me log result –> {{"Casablanca", "Spellbound", "Notorious"}, {"milk", "bread", "eggs"}} –YAMLの文字列からオブジェクトを生成する(2) set aYAMLstr to " – {name: John Smith, age: 33} – name: Mary Smith age: 27 " set aRes to retObjectFromYAMLString(aYAMLstr) of me log result –> {{{name:"John Smith", age:"33"}, {name:"Mary Smith", age:"27"}}} –YAMLの文字列からオブジェクトを生成する(3) set aYAMLstr to " men: [John Smith, Bill Jones] women: – Mary Smith – Susan Williams" set aRes to retObjectFromYAMLString(aYAMLstr) of me log result –> {{men:{"John Smith", "Bill Jones"}, women:{"Mary Smith", "Susan Williams"}}} on retObjectFromYAMLString(aYAMLstr as string) set aStr to current application’s NSString’s stringWithString:aYAMLstr set aData to aStr’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set aData to current application’s YAMLSerialization’s objectsWithYAMLString:aStr options:(4096) |error|:(missing value) return aData as list of string or string end retObjectFromYAMLString on retYAMLStringFromObject(anObject) set aString to (current application’s YAMLSerialization’s createYAMLStringWithObject:anObject options:(1) |error|:(missing value)) as list of string or string return aString end retYAMLStringFromObject |
YAMLのじっけん4
AppleScript名:YAMLのじっけん4 |
— Created 2017-02-16 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "YAML" –https://github.com/mirek/YAML.framework –YAMLの文字列からオブジェクトを生成する set aYAMLstr to " – name: Smith email: smith@mail.com – name: Shelton email: shelton@mail.com – name: Kelly email: kelly@mail.com " set aRes to (retObjectFromYAMLString(aYAMLstr) of me) as list of string or string log result –> {{{name:"Smith", email:"smith@mail.com"}, {name:"Shelton", email:"shelton@mail.com"}, {name:"Kelly", email:"kelly@mail.com"}}} set bYAMLstr to " names: [Smith, Shelton, Kelly] emails: [smith@mail.com, shelton@mail.com, kelly@mail.com] " set bRes to retObjectFromYAMLString(bYAMLstr) of me log result –> {{names:{"Smith", "Shelton", "Kelly"}, emails:{"smith@mail.com", "shelton@mail.com", "kelly@mail.com"}}} –オブジェクト(list)からYAMLの文字列を生成する set bStr to retYAMLStringFromObject(bRes) log result (* "— – names: – Smith – Shelton – Kelly emails: – smith@mail.com – shelton@mail.com – kelly@mail.com … " *) on retObjectFromYAMLString(aYAMLstr as string) set aStr to current application’s NSString’s stringWithString:aYAMLstr set aData to aStr’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set aData to current application’s YAMLSerialization’s objectsWithYAMLString:aStr options:(4096) |error|:(missing value) return aData as list of string or string end retObjectFromYAMLString on retYAMLStringFromObject(anObject) set aString to (current application’s YAMLSerialization’s createYAMLStringWithObject:anObject options:(1) |error|:(missing value)) as list of string or string return aString end retYAMLStringFromObject |
YAMLのじっけん
AppleScript名:YAMLのじっけん |
— Created 2017-02-16 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "YAML" –https://github.com/mirek/YAML.framework –YAMLの文字列からオブジェクトを生成する set aYAMLstr to " items: – name: Foo – name: Bar " set aStr to current application’s NSString’s stringWithString:aYAMLstr set aData to aStr’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set aData to (current application’s YAMLSerialization’s objectsWithYAMLString:aStr options:(4096) |error|:(missing value)) as list of string or string log result –> {{items:{{name:"Foo"}, {name:"Bar"}}}} –オブジェクトからYAMLの文字列を取得する set aString to (current application’s YAMLSerialization’s createYAMLStringWithObject:aData options:(1) |error|:(missing value)) as string (* –> "— – items: – name: Foo – name: Bar …" *) |
JSONデータからのしぼりこみ
AppleScript名:JSONデータからのしぼりこみ |
— Created 2016-11-16 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use scripting additions set theJSON to "{\"timeblocksDefs\": { \"normal\": { \"morning\": \"06-09\", \"day\": \"09-18\", \"primetime\": \"18-22\", \"nighttime\": \"22-06\" }, \"lateprime\": { \"morning\": \"06-09\", \"day\": \"09-19\", \"primetime\": \"19-23\", \"nighttime\": \"23-06\" } }} " set theDict to my convertJSONToDictionary:theJSON set theResult to (theDict’s valueForKeyPath:"timeblocksDefs.lateprime") — convert to AS equivalent set theResult to item 1 of ((current application’s NSArray’s arrayWithObject:theResult) as list) on convertJSONToDictionary:jsonString set aString to current application’s NSString’s stringWithString:jsonString set theData to aString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set {theDict, theError} to current application’s NSJSONSerialization’s JSONObjectWithData:theData options:0 |error|:(reference) if theDict is missing value then error (theError’s localizedDescription() as text) number -10000 return theDict end convertJSONToDictionary: |
指定URLのJSONをダウンロードしてRecordに変換 v2.1
AppleScript名:指定URLのJSONをダウンロードしてRecordに変換 v2.1 |
— Created 2016-02-06 by Takaaki Naganoya — Modified 2016-02-08 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" –東京電力電力供給状況API JSON URL(指定された日時の電力使用状況を返す) set a to downloadAndParseJSON("http://tepco-usage-api.appspot.com/2016/2/6/19.json") of me –> {forecast_peak_period:18, forecast_peak_usage:3670, capacity_updated:"2012-02-05 08:30:00", usage:3720, forecast_peak_updated:"2012-02-05 08:30:00", day:6, usage_updated:"2016-02-06 11:05:05", capacity:4484, saving:false, year:2016, month:2, capacity_peak_period:18, forecast:0, hour:19, entryfor:"2016-02-06 10:00:00"} –東京電力電力供給状況API JSON URL(指定された日の毎時の電力使用状況を、配列として返す) set b to downloadAndParseJSON("http://tepco-usage-api.appspot.com/2016/2/6.json") of me –> {{forecast_peak_period:18, forecast_peak_usage:3670, capacity_updated:"2012-02-05 08:30:00", usage:3081, forecast_peak_updated:"2012-02-05 08:30:00", day:6, usage_updated:"2016-02-05 16:05:06", capacity:4484, saving:false, year:2016, month:2, capacity_peak_period:18, forecast:0, hour:0, entryfor:"2016-02-05 15:00:00"}….…{forecast_peak_period:18, forecast_peak_usage:3670, capacity_updated:"2012-02-05 08:30:00", usage:3645, forecast_peak_updated:"2012-02-05 08:30:00", day:6, usage_updated:"2016-02-06 12:05:07", capacity:4484, saving:false, year:2016, month:2, capacity_peak_period:18, forecast:0, hour:20, entryfor:"2016-02-06 11:00:00"}} –東京電力電力供給状況API JSON URL(指定された月の毎日毎時の電力使用状況を、配列として返す) set c to downloadAndParseJSON("http://tepco-usage-api.appspot.com/2016/2.json") of me –> {{forecast_peak_period:18, forecast_peak_usage:4260, capacity_updated:"2012-01-31 23:30:00", usage:2901, forecast_peak_updated:"2012-01-31 23:30:00", day:1, usage_updated:"2016-01-31 16:05:04", capacity:4641, saving:false, year:2016, month:2, capacity_peak_period:18, forecast:0, hour:0, entryfor:"2016-01-31 15:00:00"}……{forecast_peak_period:18, forecast_peak_usage:3670, capacity_updated:"2012-02-05 08:30:00", usage:3645, forecast_peak_updated:"2012-02-05 08:30:00", day:6, usage_updated:"2016-02-06 12:05:07", capacity:4484, saving:false, year:2016, month:2, capacity_peak_period:18, forecast:0, hour:20, entryfor:"2016-02-06 11:00:00"}} on downloadAndParseJSON(aURL) set aRes to downloadDataFromWeb(aURL, 30) of me if aRes = false then return false –download error set jsonString to current application’s NSString’s stringWithString:aRes set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value) set bRes to aJsonDict as list of string or string return bRes end downloadAndParseJSON on downloadDataFromWeb(aURL, timeOutSec) set aURL to current application’s |NSURL|’s alloc()’s initWithString:aURL set aReq to current application’s NSURLRequest’s alloc()’s initWithURL:aURL cachePolicy:(current application’s NSURLRequestReloadIgnoringLocalCacheData) timeoutInterval:timeOutSec set urlRes to (current application’s NSURLConnection’s sendSynchronousRequest:aReq returningResponse:(missing value) |error|:(missing value)) if urlRes = missing value then return false –Download Error else set aVal to (current application’s NSString’s alloc()’s initWithData:urlRes encoding:(current application’s NSUTF8StringEncoding)) return aVal end if end downloadDataFromWeb |
NSRangeの拡張、隣接検出
NSRangeの隣接検出を行うAppleScriptです。
NSRangeやNSRectの重なり検出機能はとても強力で、OLD Style AppleScriptの時代では考えられなかったほどの処理の柔軟性を得られています。
強力ではあるものの、機能が素朴であることもまた事実であります。AとBの2つのNSRangeが重なっていることしか検出できないのはつくづく残念です。
不満な点の筆頭に挙げられるのが、「隣接検出」機能がないことです。
たとえば、NSAttributedStringに対して書式を取得する処理を行うと、3点リーダー文字(「…」)や感嘆符(「!」)の箇所で、書式情報が変わっていないのに分割して取得されてしまいます。バグではないものの、あまり好ましくない挙動です。
こうした箇所は、Rangeとしては「隣接」しているわけで、同一書式のデータが「隣接」している場合には、続きのデータとしてまとめられた方がいいに決まっています。
そこで冒頭のNSRangeの隣接検出という話になるわけですが……NSRangeが1次元座標上の始点と終点の2つの情報で構成されているために、これらの情報を「拡張」します。
set aRange to current application’s NSMakeRange(10, 80)
というNSRangeを作ると、
–> {location:10, |length|:80}
始点(10)と、始点からの長さが80で、終点が90になります。
これを「拡張」すると、
–> {location:9, |length|:82}
となります。NSRangeが「隣接」は検出できなくても、重なり合いは検出できるため、「拡張」すれば、隣接時には「重なっている」と判定できることになります。
あとは、リストに入れたNSRangeのうち重なり合っているものをループで検出するルーチンを書けば、大量のNSRange同士の隣接を処理できることでしょう。
AppleScript名:NSRangeの拡張、隣接検出 |
— Created 2018-1-12 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aRange to current application’s NSMakeRange(10, 80) –original range –> {location:10, |length|:80} set bRange to extendRange(aRange) of me –Extended range –> {location:9, |length|:81} set cRange to current application’s NSMakeRange(90, 30) –compare target range –> {location:90, |length|:30} set aRes to current application’s NSIntersectionRange(aRange, cRange) –> {location:0, |length|:0}–Not adjacent set bRes to current application’s NSIntersectionRange(bRange, cRange) –> {location:90, |length|:1}–Adjacent –NSRangeの開始点とサイズを拡張 on extendRange(aRange) set aLoc to location of aRange set aLen to |length| of aRange if aLoc > 0 then set aLoc to aLoc – 1 end if set aLen to aLen + 2 set bRange to current application’s NSMakeRange(aLoc, aLen) return bRange end extendRange |
MaxRangeを取得する
AppleScript名:MaxRangeを取得する |
use AppleScript version "2.4" use scripting additions use framework "Foundation" set aRange to current application’s NSMakeRange(10, 80) –original range set aMaxX to current application’s NSMaxRange(aRange) –> 90 –set aMinX to current application’s NSMinRange(aRange)–最小はない |
NSRangeの基礎的な処理
AppleScript名:NSRangeの基礎的な処理 |
— Created 2017-12-12 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aRange to current application’s NSMakeRange(0, 100) –> {location:0, length:100} set maxRange to current application’s NSMaxRange(aRange) –最大値 –> 100 set rangeStr to (current application’s NSStringFromRange(aRange)) as string –> "{0, 100}" set bRange to current application’s NSRangeFromString(rangeStr) –> {location:0, length:100} set cRange to current application’s NSMakeRange(50, 80) set cRes to current application’s NSEqualRanges(aRange, cRange) –> false set dRes to current application’s NSEqualRanges(aRange, bRange) –> true set eRes to current application’s NSIntersectionRange(aRange, cRange) –> {location:50, length:50} set fRes to current application’s NSLocationInRange(50, aRange) –> true set gRes to current application’s NSLocationInRange(120, aRange) –> false set hRes to current application’s NSUnionRange(aRange, cRange) –> {location:0, length:130} |
RTFを読み込んで書式をDictionary化 v3.0
指定のRTF書類の内容を読み取って、書式情報をNSDictionaryに変換するAppleScriptです。
stringVal:文字列データ
colorStr:RGBの色データを文字列化したもの
colorVal:RGBの色データの数値list
colorDomainName:おおまかな色名称
fontName:フォント名
fontSize:フォントサイズ
書式情報で抽出しやすくしてあります。複数要素(例:フォント名+色)を一緒にまとめて格納しておくことで、検索パフォーマンスを稼げるはずです。
AppleScript名:RTFを読み込んで書式をDictionary化 v3.0 |
— Created 2017-12-10 by Takaaki Naganoya — Modified 2017-12-11 by Shane Stanley — Modified 2017-12-11 by Nigel Garvey — Modified 2017-12-12 by Takaaki Naganoya use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "AppKit" property NSData : a reference to current application’s NSData property NSString : a reference to current application’s NSString property NSAttributedString : a reference to current application’s NSAttributedString set fRes to choose file of type {"public.rtf"} set aFilePath to NSString’s stringWithString:(POSIX path of fRes) set aData to NSData’s dataWithContentsOfFile:aFilePath options:0 |error|:(missing value) set theStyledText to NSAttributedString’s alloc()’s initWithData:aData options:(missing value) documentAttributes:(missing value) |error|:(missing value) set attrRes to getAttributeRunsFromAttrString(theStyledText) of me (* –> {{stringVal:"■■■■■■■", colorStr:"0 0 0", colorVal:{0, 0, 0}, colorDomainName:"black", fontName:"ヒラギノ角ゴ ProN W6", fontSize:12.0}, {stringVal:"Xxxxxxx", colorStr:"217 11 0", colorVal:{217, 11, 0}, colorDomainName:"red", fontName:"ヒラギノ角ゴ ProN W6", fontSize:12.0}, … *) on getAttributeRunsFromAttrString(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 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 –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 –Color domain name set cdnStr to retColorDomainNameFromNSColor(aColor) of me –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 set the end of (styleList of aSpd) to {stringVal:aText, colorStr:colStrForFind, colorVal:colList, colorDomainName:cdnStr, fontName:aDFontName as string, fontSize:aDFontSize} set startIndex to current application’s NSMaxRange(theRange) end repeat return (styleList of aSpd) end getAttributeRunsFromAttrString on retColorDomainNameFromNSColor(aCol) set hueVal to aCol’s hueComponent() set satVal to aCol’s saturationComponent() set brightVal to aCol’s brightnessComponent() if satVal ≤ 0.01 then set satVal to 0.0 set colName to "" if satVal = 0.0 then if brightVal ≤ 0.2 then set colName to "black" else if (brightVal > 0.95) then set colName to "white" else set colName to "gray" end if else if hueVal ≤ (15.0 / 360) or hueVal ≥ (330 / 360) then set colName to "red" else if hueVal ≤ (45.0 / 360) then set colName to "orange" else if hueVal < (70.0 / 360) then set colName to "yellow" else if hueVal < (150.0 / 360) then set colName to "green" else if hueVal < (190.0 / 360) then set colName to "cyan" else if (hueVal < 250.0 / 360.0) then set colName to "blue" else if (hueVal < 290.0 / 360.0) then set colName to "purple" else set colName to "magenta" end if end if return colName end retColorDomainNameFromNSColor |
base64エンコード、デコード v3
テキストのBase64エンコード/デコードを行うAppleScriptです。
このような基本的なデータ変換機能についてはAppleScript標準で持っていないため、Classic MacOS時代にはOSAX(Scripting Additions)で、Mac OS X時代になってからは他の言語処理系の機能を借りたり、Mac OS X用のOSAXを利用していたりしましたが、現在のmacOSではCocoaの機能を呼び出すのが一番手頃になってきました。
# サードパーティ製のOSAX(Scripting Additions)サポートはmacOS 10.14で廃止になりました。macOS標準搭載のStandard Additionsのみ利用可能です
AppleScript名:base64エンコード、デコード v3 |
— Created 2015-07-27 by Takaaki Naganoya — Updated 2015-07-28 by Shane Stanley use AppleScript version "2.4" use scripting additions use framework "Foundation" set aStr to "ぴよまるソフトウェアPiyomaru Software" set theNSString to current application’s NSString’s stringWithString:aStr set theNSData to theNSString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set bStr to base64StringFromFileString(aStr) of me return bStr –> "44G044KI44G+44KL44K944OV44OI44Km44Kn44KiUGl5b21hcnUgU29mdHdhcmU=" –set aFilePath to POSIX path of (choose file) –base64StringFromFileAtPath(aFilePath) of me –Base 64 Decode on detaFromBase64String(aStr) set dataFrom64 to current application’s NSData’s alloc()’s initWithBase64EncodedString:aStr options:(current application’s NSDataBase64DecodingIgnoreUnknownCharacters) set aStr to current application’s NSString’s alloc()’s initWithData:dataFrom64 encoding:(current application’s NSUTF8StringEncoding) return aStr as text –stringではなくtext end detaFromBase64String –Base64 Encode on base64StringFromFileAtPath(aFilePath) set aDataFromFile to current application’s NSData’s dataWithContentsOfFile:aFilePath set aBase64EncStr to aDataFromFile’s base64EncodedStringWithOptions:(current application’s NSDataBase64Encoding64CharacterLineLength) return aBase64EncStr as text end base64StringFromFileAtPath –Base64 Encode on base64StringFromFileString(aString) set bString to current application’s NSString’s stringWithString:aString set aData to bString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set aBase64EncStr to aData’s base64EncodedStringWithOptions:(current application’s NSDataBase64Encoding64CharacterLineLength) return aBase64EncStr as text end base64StringFromFileString |
デコードしたQRコードのメールデータの各フィールドを取り出す v2.2
AppleScript名:デコードしたQRコードのメールデータの各フィールドを取り出す v2.2 |
— Created 2016-12-12 by Shane Stanley — Modified 2016-12-14 by edama2 — Modified 2017-01-12 by Takaaki Naganoya use AppleScript version "2.4" use scripting additions use framework "Foundation" set aStr to "こんにちは、ぴよまるです MATMSG:TO:hiyoko@piyocast.com;SUB:たいとる;BODY:ほんぶん;; Takaaki Naganoya iPhoneから送信" set aDict to (parseStrByParamlabelAndTail(aStr, "MATMSG:", ":", ";") of me) set eMailAddrs to (aDict’s valueForKey:"TO") as string–> "hiyoko@piyocast.com" set aSubject to (aDict’s valueForKey:"SUB") as string –> "たいとる" set aBody to (aDict’s valueForKey:"BODY") as string –> "ほんぶん" on parseStrByParamlabelAndTail(aParamStr, aDataHeader, aParamLabel, aParamTail) set theScanner to current application’s NSScanner’s scannerWithString:aParamStr set aDict to current application’s NSMutableDictionary’s |dictionary|() —Skip over the data header set {theResult, theKey} to theScanner’s scanUpToString:aDataHeader intoString:(reference) if theResult as boolean = false then return false –Error: Data header is not present theScanner’s scanString:aDataHeader intoString:(missing value) repeat until (theScanner’s isAtEnd as boolean) — terminate check, return the result (aDict) to caller set {theResult, theKey} to theScanner’s scanUpToString:aParamLabel intoString:(reference) — skip over separator theScanner’s scanString:aParamLabel intoString:(missing value) set {theResult, theValue} to theScanner’s scanUpToString:aParamTail intoString:(reference) if theValue is missing value then set theValue to "" — skip over separator theScanner’s scanString:aParamTail intoString:(missing value) aDict’s setObject:theValue forKey:theKey end repeat return aDict end parseStrByParamlabelAndTail |
RSSをダウンロードしてparseする(XmlToDictKit)
AppleScript名:RSSをダウンロードしてparseする(XmlToDictKit) |
— Created 2016-11-05 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "XmlToDictKit" –https://github.com/nicklockwood/XMLDictionary set aURL to current application’s |NSURL|’s alloc()’s initWithString:"http://piyocast.com/as/feed/" set xmlString to current application’s NSString’s alloc()’s initWithContentsOfURL:aURL encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value) if xmlString = missing value then return false set xmlDoc to (current application’s NSDictionary’s dictionaryWithXMLString:xmlString) set blogTitle to (xmlDoc’s valueForKeyPath:"channel.title") as string –> "AppleScirpt Hole" –タイトル一覧を取得する set titleList to (xmlDoc’s valueForKeyPath:"channel.item.title") as list –> {"XmlToDictKitでBlogのRSS情報を解析", "listのrecordをplistにserializeして、plistをde-serializeする", "Listのrecordをエンコーディングしてplist文字列にする", "serializeされたlistのrecordからKeynoteで新規ドキュメントを作成してグラフを作成", "system_profilerの結果のstringのplistをdictionaryにのコピー2", "XPathQuery4ObjCのじっけん2", "recordをXMLに v2", "XmlToDictKitでXMLをDictionaryに(remote file)", "XmlToDictKitでXMLをDictionaryに(local file)", "XMLをrecordにv2"} –URL一覧を返す set urlList to (xmlDoc’s valueForKeyPath:"channel.item.link") as list –> {"http://piyocast.com/as/archives/814", "http://piyocast.com/as/archives/812", "http://piyocast.com/as/archives/810", "http://piyocast.com/as/archives/805", "http://piyocast.com/as/archives/803", "http://piyocast.com/as/archives/799", "http://piyocast.com/as/archives/797", "http://piyocast.com/as/archives/792", "http://piyocast.com/as/archives/790", "http://piyocast.com/as/archives/788"} –本文のプレビュー一覧 set descList to (xmlDoc’s valueForKeyPath:"channel.item.description") as list (* {"AppleScript名:XmlToDictKitでBlogのRSS情報を解析 — Created 2016-11-05 by Takaaki Naganoya— 2016 Piyomaru S … <a href=\"http://piyocast.com/as/archives/814\" class=\"more-link\"><span class=\"screen-reader-text\">\"XmlToDictKitでBlogのRSS情報を解析\"の</span>続きを読む</a>", …. *) –更新日時の一覧 set descList to (xmlDoc’s valueForKeyPath:"channel.item.pubDate") as list –> {"Wed, 07 Feb 2018 08:00:53 +0000", "Wed, 07 Feb 2018 07:58:06 +0000", "Wed, 07 Feb 2018 07:55:12 +0000", "Wed, 07 Feb 2018 07:50:07 +0000", "Wed, 07 Feb 2018 07:28:10 +0000", "Wed, 07 Feb 2018 07:23:45 +0000", "Wed, 07 Feb 2018 07:23:04 +0000", "Wed, 07 Feb 2018 07:20:21 +0000", "Wed, 07 Feb 2018 07:20:13 +0000", "Wed, 07 Feb 2018 07:11:33 +0000"} |
XmlToDictKitでBlogのRSS情報を解析
AppleScript名:XmlToDictKitでBlogのRSS情報を解析 |
— Created 2016-11-05 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "XmlToDictKit" –https://github.com/nicklockwood/XMLDictionary set aURL to "http://piyocast.com/as/feed/" set xRes to getLatestBlogInfo(aURL) of me on getLatestBlogInfo(aURLstring) set aURL to current application’s |NSURL|’s alloc()’s initWithString:aURLstring set xmlString to current application’s NSString’s alloc()’s initWithContentsOfURL:aURL encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value) if xmlString = missing value then return false set xmlDoc to (current application’s NSDictionary’s dictionaryWithXMLString:xmlString) set blogTitle to (xmlDoc’s valueForKeyPath:"channel.title") as string –> "AS Hole(AppleScriptの穴) By Piyomaru Software" set titleList to (xmlDoc’s valueForKeyPath:"channel.item.title") as list –タイトル一覧 set urlList to (xmlDoc’s valueForKeyPath:"channel.item.link") as list –URL一覧 set descList to (xmlDoc’s valueForKeyPath:"channel.item.description") as list –本文のプレビュー一覧 set updateList to (xmlDoc’s valueForKeyPath:"channel.item.pubDate") as list –更新日時の一覧 return {first item of titleList, first item of urlList, first item of descList} end getLatestBlogInfo |
listのrecordをplistにserializeして、plistをde-serializeする
AppleScript名:listのrecordをplistにserializeして、plistをde-serializeする |
— Created 2016-10-30 by Takaaki Naganoya — Modified 2016-10-31 by Shane Stanley — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aList to {{theName:"サウンドトラック", numberOfTimes:1721}, {theName:"ロック", numberOfTimes:942}, {theName:"クラシック", numberOfTimes:539}, {theName:"ポップ", numberOfTimes:492}, {theName:"J-Pop", numberOfTimes:352}, {theName:"アニメ", numberOfTimes:330}, {theName:"Pop", numberOfTimes:279}, {theName:"World", numberOfTimes:218}, {theName:"Soundtrack", numberOfTimes:188}, {theName:"ジャズ", numberOfTimes:187}, {theName:"エレクトロニック", numberOfTimes:166}, {theName:"Classical", numberOfTimes:165}, {theName:"Rock", numberOfTimes:148}, {theName:"R&B", numberOfTimes:125}, {theName:"ニューエイジ", numberOfTimes:104}, {theName:"Unclassifiable", numberOfTimes:81}, {theName:"Children’s", numberOfTimes:57}, {theName:"歌謡曲", numberOfTimes:47}, {theName:"Holiday", numberOfTimes:38}, {theName:"オルタナティブ", numberOfTimes:34}, {theName:"Data", numberOfTimes:32}, {theName:"イージーリスニング", numberOfTimes:31}, {theName:"ヴォーカル", numberOfTimes:28}, {theName:"ワールド", numberOfTimes:28}, {theName:"soundtrack", numberOfTimes:19}, {theName:"ディズニー", numberOfTimes:15}, {theName:"シンガーソングライター", numberOfTimes:15}, {theName:"ブルース", numberOfTimes:15}, {theName:"Easy Listening", numberOfTimes:14}, {theName:"ラテン", numberOfTimes:14}, {theName:"Electronica/Dance", numberOfTimes:14}, {theName:"Anime", numberOfTimes:13}, {theName:"フォーク", numberOfTimes:10}, {theName:"J-POP", numberOfTimes:9}, {theName:"New Age", numberOfTimes:9}, {theName:"ダンス", numberOfTimes:5}, {theName:"ホリデー", numberOfTimes:5}, {theName:"カントリー", numberOfTimes:4}, {theName:"演歌", numberOfTimes:4}, {theName:"Latin", numberOfTimes:3}, {theName:"ヒップホップ/ラップ", numberOfTimes:3}, {theName:"Vocal", numberOfTimes:2}, {theName:"R&B/ソウル", numberOfTimes:2}, {theName:"R&B/ソウル", numberOfTimes:2}, {theName:"#NIPPONSEI @ IRC.MIRCX.COM", numberOfTimes:2}, {theName:"148", numberOfTimes:1}, {theName:"Electronic", numberOfTimes:1}, {theName:"Folk", numberOfTimes:1}, {theName:"NHK FM(東京)", numberOfTimes:1}, {theName:"その他", numberOfTimes:1}, {theName:"チルドレン・ミュージック", numberOfTimes:1}, {theName:"Seattle Pacific University – Latin", numberOfTimes:1}, {theName:"Kayokyoku", numberOfTimes:1}, {theName:"ヒップホップ/ ラップ", numberOfTimes:1}, {theName:"Dance", numberOfTimes:1}, {theName:"インストゥルメンタル", numberOfTimes:1}, {theName:"146", numberOfTimes:1}} set aRes to serializeToPlistString(aList) of me –>"<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"><plist version=\"1.0\"><array><dict><key>numberOfTimes</key><integer>1721</integer><key>theName</key><string>サウンドトラック</string></dict>…. set bRes to (deserializeToPlistString(aRes) of me) as list –> {{numberOfTimes:1721, theName:"Sound Track"}, {numberOfTimes:942, theName:"Rock"}} –list or record –> XML-format plist string on serializeToPlistString(aList as {list, record}) set pListData to current application’s NSPropertyListSerialization’s dataWithPropertyList:aList |format|:(current application’s NSPropertyListXMLFormat_v1_0) options:0 |error|:(missing value) set bStr to (current application’s NSString’s alloc()’s initWithData:pListData encoding:(current application’s NSUTF8StringEncoding)) as string return bStr end serializeToPlistString –XML-format plist string–> list or record on deserializeToPlistString(aStr as string) set deStr to current application’s NSString’s stringWithString:aStr set theData to deStr’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set aList to current application’s NSPropertyListSerialization’s propertyListWithData:theData options:(current application’s NSPropertyListMutableContainersAndLeaves) |format|:(missing value) |error|:(missing value) return aList end deserializeToPlistString |