Now, we have e-mail attack by somebody. We don’t have an intention to attack. I think the attacker use mail address spoofing.
Webmail UI might be cracked.
Now, we have e-mail attack by somebody. We don’t have an intention to attack. I think the attacker use mail address spoofing.
Webmail UI might be cracked.
与えられたテキスト(おそらく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 |
アラートダイアログ上に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 |
CotEditorの最前面のドキュメントで選択中の、JavaScriptのrecord in listをAppleScriptのオブジェクトに変換するAppleScriptです。
こんな風にJavaScriptのプログラム中のrecord in listを選択しておいてScriptを実行すると、
AppleScriptのオブジェクトに変換します。
AppleScript名:CotEditor上で選択中のJavaScriptのrecord in listをASのオブジェクトに変換.scpt |
— Created 2015-07-20 by Takaaki Naganoya — 2015 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" tell application "CotEditor" tell front document set jsonText to contents of selection end tell end tell set a to repChar(jsonText, "[", "{") of me set b to repChar(a, "]", "}") of me set c to repChar(b, string id 10, "") of me set d to repChar(c, tab, "") of me try set e to run script d set f to convToStr(e) of textKit tell application "CotEditor" make new document tell front document set contents to f end tell end tell on error erM display dialog erM end try –文字置換 on repChar(origText as string, targChar as string, repChar as string) set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to targChar set tmpList to text items of origText set AppleScript’s text item delimiters to repChar set retText to tmpList as string set AppleScript’s text item delimiters to curDelim return retText end repChar –リストでもレコードでもなんでも文字列化して返すキット script textKit on convToStr(aRec) set aClass to (class of aRec) as string if (aClass = "integer") or (aClass = "number") or (aClass = "real") or (aClass = "string") or (aClass = "text") or (aClass = "Unicode text") or (aClass = "boolean") then set aRes to aRec as string else if aClass is "list" then set aRes to listToString(aRec) else if aClass is "record" then set aRes to recToString(aRec) else try set aRes to aRec as string on error –アプリケーションのオブジェクトとかはエラーで返す return false end try end if return aRes end convToStr –レコードをStringに変換 –エラートラップを使って、わざとエラーを発生させ、エラーメッセージからレコードをstringに変換する on recToString(aRec) –レコードを無理矢理stringにcastして、エラーメッセージを取得する try set a to aRec as string –ここでエラー発生 on error aMes set a to aMes end try –エラーメッセージ文字列から、元のレコードの情報を組み立てる set b to trimStrFromTo(a, "{", "}") set b to "{" & b & "}" return b end recToString on trimStrFromTo(aStr, fromStr, toStr) –fromStrは前から探す if fromStr is not equal to "" then set sPos to (offset of fromStr in aStr) + 1 else set sPos to 1 end if –toStrは後ろから探す if toStr is not equal to "" then set b to (reverse of characters of aStr) as string set ePos to (offset of toStr in b) set ePos to ((length of aStr) – ePos) else set ePos to length of aStr end if set aRes to text sPos thru ePos of aStr return aRes end trimStrFromTo –リストおよびリストに入ったレコードをStringに変換 on listToString(aList) set listText to {"{"} set quotChar to ASCII character 34 set firstFlag to true repeat with i in aList set j to contents of i set aClass to (class of i) as string if (aClass = "integer") or (aClass = "number") or (aClass = "real") or (aClass = "boolean") then set the end of listText to (getFirst(firstFlag) of me & j as text) set firstFlag to false else if (aClass = "string") or (aClass = "text") or (aClass = "Unicode text") then set the end of listText to ((getFirst(firstFlag) of me & quotChar & j as text) & quotChar) set firstFlag to false else if aClass is "list" then set the end of listText to (getFirst(firstFlag) & listToString(j)) –ちょっと再帰処理 set firstFlag to false else if aClass is "record" then set the end of listText to (getFirst(firstFlag) & recToString(j)) set firstFlag to false end if end repeat set the end of listText to "}" set listText to listText as text return listText end listToString on getFirst(aFlag) if aFlag = true then return "" if aFlag = false then return ", " end getFirst end script |
アラートダイアログ上に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) |
アラートダイアログ上にWkWebViewを作成し、その上でAMChartsによるWord Cloudを表示するAppleScriptです。
–> Download am_wordcloud.zip(AppleScript Bundle with Library and HTML)
AMChartsのワードクラウドの表示ロジックがちょっと「?」な仕様でした。英文のテキスト(単語がスペースで区切られている)をそのまま渡すとJavaScript側でParseして度数集計を行なって表示するようになっています。
集計済みのデータを渡して表示させる仕様ではなかったので、集計したデータをわざとテキストに展開して渡しています。非効率的な仕組みですが、スピードは遅くないので使っています。
ただし、その仕様の影響で「Script Editor」といった半角スペースを含む単語についてはスペースをハイフンに置換して「Script-Editor」のようにして処理しています。
→ と、自分で書いておいて「そんなバカな」と感じたので、再度AMChartsのドキュメントを読んでみたら、ちゃんとstructured dataを使うという項目があり、集計済みデータを処理できるとのこと。
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" script tagStorage property aList : {} end script set aRecArray to {{|word|:"NSString", |count|:97}, {|word|:"NSURL", |count|:78}, {|word|:"Keynote", |count|:52}, {|word|:"NSMutableArray", |count|:51}, {|word|:"NSAlert", |count|:50}, {|word|:"NSRunningApplication", |count|:49}, {|word|:"NSArray", |count|:48}, {|word|:"CotEditor", |count|:44}, {|word|:"NSColor", |count|:44}, {|word|:"Finder", |count|:41}, {|word|:"NSImage", |count|:39}, {|word|:"Numbers", |count|:38}, {|word|:"NSPredicate", |count|:34}, {|word|:"NSView", |count|:32}, {|word|:"NSButton", |count|:28}, {|word|:"Safari", |count|:28}, {|word|:"NSScreen", |count|:27}, {|word|:"iTunes", |count|:25}, {|word|:"NSUTF8StringEncoding", |count|:24}, {|word|:"NSDictionary", |count|:22}, {|word|:"NSScrollView", |count|:21}, {|word|:"NSBitmapImageRep", |count|:20}, {|word|:"NSFileManager", |count|:20}, {|word|:"NSMutableDictionary", |count|:19}, {|word|:"NSURLRequest", |count|:18}, {|word|:"NSUUID", |count|:18}, {|word|:"NSWindow", |count|:17}, {|word|:"NSBezierPath", |count|:16}, {|word|:"NSFont", |count|:16}, {|word|:"WKWebView", |count|:16}, {|word|:"WKWebViewConfiguration", |count|:16}, {|word|:"NSWorkspace", |count|:15}, {|word|:"Pages", |count|:15}, {|word|:"Script Editor", |count|:15}, {|word|:"System Events", |count|:15}, {|word|:"WKUserContentController", |count|:15}, {|word|:"WKUserScript", |count|:15}, {|word|:"NSAlertSecondButtonReturn", |count|:14}, {|word|:"NSJSONSerialization", |count|:14}, {|word|:"NSSortDescriptor", |count|:14}} set (aList of tagStorage) to {} repeat with i in aRecArray set aW to |word| of i set aCount to |count| of i set bW to repChar(aW, " ", "-") of me repeat aCount times set the end of (aList of tagStorage) to bW end repeat end repeat set tRes to retDelimedText((aList of tagStorage), " ") of me –https://www.amcharts.com/demos/word-cloud/ 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, tRes) as string set paramObj to {myMessage:"Word Cloud", mySubMessage:"This is a AMCharts test", htmlStr:aString, jsDelimiters:{"<script>", "</script>"}, viewSize:{800, 520}} webD’s displayWebDialog(paramObj) on retDelimedText(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 retDelimedText –文字置換 on repChar(origText as string, targChar as string, repChar as string) set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to targChar set tmpList to text items of origText set AppleScript’s text item delimiters to repChar set retText to tmpList as string set AppleScript’s text item delimiters to curDelim return retText end repChar |
アラートダイアログ上に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 |
アラートダイアログ上に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 |
アラートダイアログ上にWkWebViewを作成し、その上でAMChartsによる点滅ポイントつき世界地図を表示するAppleScriptです。
このアラートダイアログによる「箱庭UI」シリーズも、なかなか実用性のあるソリューションにつながる例が少なくて、インパクトとかウケ狙いのものが多いですが、これにはけっこうな実用性を感じました。
世界地図上にプロットする必要のあるデータというのはなかなかありませんが、必要がある場合にはこのように部品として使えるところまで飼い慣らしてあるので、有用性は高いと思われます。
–> Download displayAMChart (Script Bundle with Library and HTML)
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 |
アラートダイアログ上にWkWebViewを貼り付けて、その上でZingChartによるヒートマップを表示するAppleScriptです。
–> Download zingchartDisp (Script Bundle with AppleScript library and html)
さすがにHTMLのコードが長々と掲載されるのはいかがなものかと考え、htmlを外部ファイルに追い出してみました。
ZingChartは商用のJavaScriptライブラリですが、フリーでも利用できます。フリーで利用する場合にはチャート中に「Powered by ZingChart」の表示が入るようです。
index.html中からデータを外部に追い出せていませんが、データを外部から供給するようにすれば、AppleScriptで処理した結果を表示する部品として活用できることでしょう。
▲ほかにもいろいろありますが、ZingChartはセンスがいい上にサンプルにフルHTMLが掲載されていて分かりやすいですね。ただ、自分が表示させたいデータを突っ込んで表示を試みるとうまく行かないケースが多い
AppleScript名:ZingChart.jsでヒートマップをダイアログ上に表示.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 scripting additions use webD : script "webDialogLib" –https://www.zingchart.com/gallery/grouped-heatmap-of-united-states 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 paramObj to {myMessage:"Grouped Heatmap Map of the US", mySubMessage:"This is a zingchart test", htmlStr:myStr, jsDelimiters:{"<script>", "</script>"}, viewSize:{900, 600}} webD’s displayWebDialog(paramObj) |
アラートダイアログ上にWkWebViewを配置し、その上にvis.jsによるDOT言語をGraphViz同様に表示するAppleScriptです。
GraphVizは、知る人ぞ知るフロー図やマインドマップ風の図を比較的わかりやすい記述言語(DOT)で行ったものをレンダリング表示するフリーのソフトウェアです。もともと、IC上の部品配置を最適化するためのアルゴリズムが活用されているのだとか。
ノード間を線でつないだ図(マインドマップみたいなもの)を、ノードの関連情報を記述するだけでレンダリングできるため、いろいろ便利に使ってきました。MindjetMindManagerなどのアプリケーションをAppleScriptからコントロールして表示してきたものを、GraphVizに置き換えています(MindjetMindManagerが高価な割に不甲斐ないので)。AppleScript書類内のルーチンの呼び出し関係をマインドマップで表示するAppleScriptなども使っており、こちらはまだGraphViz版を作っていませんが、いろいろ便利に使えるだろうかといったところです。
▲同じデータをGraphVizでレンダリング&表示させた実行画面
–> Download gviz_data(Script bundle with AppleScript Libraries & DOT Data)
DOTファイルをレンダリングして表示するのに、GraphvizのObjective-C版をひろってきて、その内容を適宜呼び出すようなことも検討していたのですが、これでいいじゃないですか。
GraphvizのObjective-C版をAppleScriptObjC版のアプリケーションに組み込むのが大変(プログラムがFrameworkになっているとか、表示用のビューをWindowに乗せればそれでおしまい、という風にはなっていない)。
WkWebViewを1枚ウィンドウ上に貼り付けて、JavaScriptを実行。PDFに書き出すことさえ考えなければ、これで問題ないでしょう。そう、PDF出力することを考えなければ…………。あとは、Mac App Storeに出すときにこうした構造のアプリケーションで大丈夫なのかが疑問です。ただ、iOSでこうしたWebView+JavaScriptの「ガワアプリ」と言われるものが多数存在するという状況を鑑みますと、そんなにうるさいことを言われないのでは? という気もします。
本Scriptについては、あとはマウスのスクロールで拡大縮小するように改良できるとよいでしょう。
AppleScript名:DOT.jsでGraphvizをダイアログ上に表示 v2.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 scripting additions use webD : script "webDialogLib" property NSString : a reference to current application’s NSString set aDot to choose file of type {"com.omnigroup.foreign-types.graphviz-dot"} set aData to read aDot as «class utf8» –https://visjs.github.io/vis-graph3d/docs/graph3d/index.html set myStr to "<!DOCTYPE html> <html lang=\"ja\"> <head> <meta charset=\"utf-8\"> <title>Vue.js-Viz.js</title> <script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js\"></script> <script type=\"text/javascript\" src=\"https://unpkg.com/viz.js@1.8.0\"></script> <style> </style> </head> <body> <div class=\"container\"> <div id=\"graph\"> <div class=\"write\"> </div> <div class=\"out\"> <div class=\"graph\" v-html=\"svg\"></div> </div> </div> </div> </body> <script> new Vue({ el: ’#graph’, data: { input: `%@`, }, computed: { svg: function() { return Viz(this.input, { format: ’svg’ }); }, }, }); </script> </html>" set aString to current application’s NSString’s stringWithFormat_(myStr, aData) as string set paramObj to {myMessage:"viz.js Test", mySubMessage:"This is a viz.js test", htmlStr:aString, jsDelimiters:{"<script>", "</script>"}, viewSize:{1700, 400}} webD’s displayWebDialog(paramObj) |
WWDC20にて、MacのARM(Apple Silicon)移行と、次期macOS 11「Big Sur」が発表されました。
Apple Silicon(A12z Bionic)搭載の開発者向けマシン「Developer Transition Kit」(Mac mini筐体、A12Z Bionic 2.6GHz 8Core, RAM 16GB, SSD 512GB)も500ドルで提供されることが発表されました。
Big Surの出来については「iOSっぽいデザイン」としか言いようがありませんし、中身についてはBeta版を見て判断するほかありません。
→ AppleがMacでも独自開発のプロセッサに移行する「Apple Silicon」を発表、iPhone&iPadのアプリがMacでも利用可能に
▲Xcode 12betaでAppleScriptObjCアプリケーションを作ってビルド(初期β版のものです)
▲スクリプトエディタ上でAppleScript v2.7が動作。見た目はちょっと……随分変わります(初期β版のものです)
アラートダイアログ上に作成したWkWebViewでvis.jsのGraph3dを用いて3Dグラフを表示するAppleScriptです。
本Scriptは単に三角関数の計算値をプロットするものなので、そのまま実用レベルというわけではありませんが、vis.jsがこのように利用できることを示す実証コードにはなっていると思います。
実行すると、グラフの表示タイプを聞いてくるので、
選択すると、グラフを表示します。ドラッグで回転、マウスのスクロールホイールでズーム制御を行います。
まいどまいど、代わり映えしないWkWebViewの表示コードを掲載するのもどうかと思い、その部分はライブラリとしてまとめておきました。きちんとAppleScript側のオブジェクトでパラメータを指定できるレベルまで落とし込めば、JavaScript部分もライブラリに押し込んで「display chart」のようなsdefつきライブラリに仕立ててもいいのかもしれません。
–> Download 3dGraphDialog.zip (Script Bundle with AppleScript Libraries)
AppleScript名:アラートダイアログ上にWebViewでvis.jsを用いて3Dグラフを表示.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 scripting additions use webD : script "webDialogLib" property NSString : a reference to current application’s NSString set aSel to choose from list {"bar", "bar-color", "bar-size", "dot", "dot-line", "dot-color", "dot-size", "grid", "line", "surface"} if aSel = false then return set aaSel to contents of first item of aSel –https://visjs.github.io/vis-graph3d/docs/graph3d/index.html set myStr to "<!DOCTYPE HTML> <html> <head> <title>Graph 3D demo</title> <style> body {font: 16pt arial;} </style> <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.js\"></script> <script type=\"text/javascript\"> var data = null; var graph = null; function custom(x, y) { return (Math.sin(x/50) * Math.cos(y/50) * 50 + 50); } // Called when the Visualization API is loaded. function drawVisualization() { // Create and populate a data table. var data = new vis.DataSet(); // create some nice looking data with sin/cos var steps = 30; // number of datapoints will be steps*steps var axisMax = 314; var axisStep = axisMax / steps; for (var x = 0; x < axisMax; x+=axisStep) { for (var y = 0; y < axisMax; y+=axisStep) { var value = custom(x, y); data.add({ x: x, y: y, z: value, style: value }); } } // specify options var options = { width: ’900px’, height: ’600px’, style: ’%@’, showPerspective: true, showGrid: true, showShadow: false, keepAspectRatio: true, verticalRatio: 0.6 }; // create a graph3d var container = document.getElementById(’mygraph’); graph3d = new vis.Graph3d(container, data, options); } </script> </head> <body onload=\"drawVisualization();\"> </body> </html>" set aString to NSString’s stringWithFormat_(myStr, aaSel) as string set paramObj to {myMessage:"Vis.js Test", mySubMessage:"This is a Vis.js test", htmlStr:aString, jsDelimiters:{"<script type=", "</script>"}, viewSize:{920, 620}} webD’s displayWebDialog(paramObj) |
アラートダイアログ上に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> 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 |
アラートダイアログ上に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> //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を設定する controller.addData( data ); </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 |
Pixelmator Proがv1.8でAppleScriptに対応するとPixelmator Blogで発表しました。
Pixelmatorの登場当初からAppleScript対応の意見を出していましたが、そこから……何年たったのでしょうか。
サンプルScriptをながめたかぎりでは、オブジェクトを作って属性情報を書き換える操作はできるようです。
selectionが扱えるかどうか(選択中のオブジェクトを取れるかどうか)が1つの判断基準になりそうです。
いくらCocoaの機能が使える、NSBezierPathが使えるといっても、こういうローレベルなAPIを相手に高度なグラフィックを描かせるのはつらいので、GUIアプリケーション側の機能が使えるとたすかります。
→ Beta Programに登録して、Betaを落としてきたものの、これMac App Store版のPixelmator Proが入っていないとBetaが起動しないんですね(うまい! このやり方は知っておきたい)。とりあえず、AppleScript用語辞書だけ見られればよかったので、sdef取り出して眺めてみたところ、けっこう気合いが入っていてビビりました。
近年、こんなに気合いの入ったAppleScript用語辞書を装備したアプリケーションは見ていません。「あー、この機能たしかに入れたいよねー、実用性はさておきとして」「なるほどーこういう単位でselectionできるのかー」などなど、詳細は書けませんが、これが全部まともに動くのならすごいです。
ただ、サンプルのScriptが掲載されているのに、スクリプトリンクが埋め込まれていないので、サンプルをすぐに使えるというレベルには達していません。また、画面のスナップショットやムービーなどが入っているわけでもありません。
指定の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 |
Q&Aサイトでいろいろ答えた内容(自分自身のみ)をまとめて本にしてみました。ぴよまるソフトウェアBooks初の雑文系縦書き新書!(500円)
ぴよまるソフトウェア創設者である筆者は、元雑誌編集者。あふれるバイタリティと文章の力、そして新開発のアイデアを練るアプリケーション「Kamenoko」の威力でQ&Aサイトで1か月5万ビューの回答を繰り出した! 筆者による回答を再編集し、読みやすく縦書きの新書っぽい形にまとめた本書。全257ページ、38の珍問答。Macとガンダムに極端に強い筆者の、幅広そうで偏った知識がうなる渾身の一冊!
Kamenokoの事例集(作例集)、と見ることもできます。とにかく、毎日Kamenoko上でいろいろあーだこーだとアイデアを練って、こねて、まるめているので(本人向けに作ったので、本人にはめちゃくちゃ合っています)。
→ 製品版
→ お試し版
■航空機は一発食らってもやばいのに、どうしてガンダムは攻撃を耐えしのぐのか?
■AppleのCEO、Tim Cook氏は辞任すべきではないか?
■ファーストガンダムって何が凄いの?
■ソフトバンクの後継者問題について
■ガンダムのような巨大人型ロボットは兵器として有効か?
■いつもPCのディスク容量が足りないと嘆いているプログラマーがいます。プログラミングってそんなに多くの容量を使うのでしょうか?
■iMacは吊るしで買って数年で入れ替えるのとフルスペックで長く使うとどちらが理想的?
■コーディングを速くするには?
■勉強になるオススメのアニメや漫画はありますか?
■Macintoshで一番悩み苦しんだ出来事は?
■パソコンのディスク容量を圧迫すると実感するものの、なくてはならないツールやソフトは何ですか?
■AppleはMac Proがチーズグレーターに見えると人々が指摘することを予想していたか?
■楽しさを思いっきり表現してください
■テクノロジーが色彩(カラー)を決定している例は?
■自動車のワイパーを再発明してもらえませんか?
■MacとWindows、どちらの方が生産性が高いですか?
■どこでもドアは実現可能ですか?
■五分でめっちゃ成長する方法は?
■MacBookのアプリの閉じ方は、左上の赤い×ボタンを押すのであってますか?
■近年、サザエさんやドラえもんのような国民的長寿アニメが生まれていないのはなぜ?
■一切プログラミングの学習・経験を積まずに情報工学科の大学に進学した場合、将来エンジニアとして働けるでしょうか?
■1970年の人々にとってSFのように見える2020年のテクノロジーは何でしょう?
■ガンダムに出てくるもので一番実用的なものは何ですか?
■四十歳を超えたド素人のサラリーマンが、資料作りやホームページ作りでのデザインスキルを付けるにはどうするのが効率的でしょうか?
■エクセルの達人が複雑なマクロを作り大幅な業務効率化を達成したのですが、その人が転勤してしまい誰もエクセルのメンテナンスが出来ず元のやり方に戻りました。この事態に名前をつけるならどんなのが良いですか?
■MacのJISキーボードを使っています。Shift+0にアンダースコア(_)を割り当てるにはどうすればいいですか?
■なんで、スマホにストラップがつけられないようになったのでしょうか?
■プログラミングって賢くないと無理ですか?
■プログラミングでマウスや矢印キー以外でカーソルを移動させる方法はありますか?
■ARグラスでどのようなことができるようになると思いますか?
■パソコンがすぐ使えるようになる人とそうでない人との違いは何ですか?
■MacのことえりはAI学習機能ではないのですか? 繰り返し入力する単語でも、最初のいくつかの文字でさくっと候補に上がらないため、イライラしますが解消法はあるでしょうか?
■石に刺さった剣があります。どうにかして剣を取り出してくれませんか?
■もしガンダムでジオンがゲルググではなくギャンを次期量産モビルスーツとして採用していた場合、その後どうなっていましたか?
■子どもに「インターネットください」と言われたら、何て返事をしますか?
■アマゾンキンドルのテキストを、Macのスピーチ機能で読み上げることは出来ますか?
■なぜガンダムにはほとんど格闘戦だけのGガンダムはあるのに、逆に殆ど射撃、狙撃、砲撃だけのガンダム作品はなく、射撃+ビームサーベルなどを用いた格闘戦なのでしょうか?
Chart.jsを用いてアラートダイアログ上に円グラフを表示するAppleScriptです。
サンプルの円グラフの色使いがいまひとつだったので、Keynoteのグラフの色設定を読み取って利用しています。
ネットワーク接続チェックなど、必要な処理はひととおり行なっている、実戦レベルに近いものです。
さまざまなJavaScript系のグラフ表示のプログラムを試してみましたが、Chart.jsはとてもいい感じです。
AppleScript名:アラートダイアログ上にWebViewでChart.jsを表示(Pie Chart) v2.scptd |
set aList to {"field1", "field2", "field3", "field4", "field5"} set cList to {38, 31, 21, 10, 1} set dMes1 to "Pie chart Test" set dMes2 to "This is a simple Donut chart using charts.js" displayPieChart(aList, cList, dMes1, dMes2) of pieChartLib script pieChartLib — – Created by: Takaaki Naganoya – Created on: 2020/06/12 — – 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 NSMutableArray : a reference to current application’s NSMutableArray property NSJSONSerialization : a reference to current application’s NSJSONSerialization 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 property parent : AppleScript on displayPieChart(aList, cList, dMes1, dMes2) –Error Check if length of aList is not equal to length of cList then error "Wrong Parameter items" if length of aList > 18 then error "Too much items" set aRes to hasInternetConnection("https://cdnjs.cloudflare.com") of me if aRes = false then error "Internet connection lost" –Data convert to JSON strings set aJsonStr to array2DToJSONArray(aList) of me set cJsonStr to array2DToJSONArray(cList) of me –Pie Chart Template HTML set myStr to "<!DOCTYPE html> <html lang=\"ja\"> <head> <meta charset=\"utf-8\"> <title>Graph</title> </head> <body> <canvas id=\"myPieChart\"></canvas> <script src=\"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js\"></script> <script> var ctx = document.getElementById(\"myPieChart\"); var myPieChart = new Chart(ctx, { type: ’pie’, data: { labels: %@, datasets: [{ backgroundColor: %@, data: %@ }] }, options: { title: { display: false, text: \"\" } } }); </script> </body> </html>" –Color Table From Apple Keynote set bList to {"#118EFE", "#53D529", "#F5AD10", "#FC0007", "#8B2659", "#2A2A2A", "#118EFE", "#53D529", "#F5AD10", "#FC0007", "#8B2659", "#2A2A2A", "#118EFE", "#53D529", "#F5AD10", "#FC0007", "#8B2659", "#2A2A2A"} set bJsonStr to array2DToJSONArray(bList) of me set aString to NSString’s stringWithFormat_(myStr, aJsonStr, bJsonStr, cJsonStr) as string set paramObj to {myMessage:dMes1, mySubMessage:dMes2, htmlStr:aString} –my browseStrWebContents:paramObj–for debug my performSelectorOnMainThread:"browseStrWebContents:" withObject:(paramObj) waitUntilDone:true end displayPieChart on browseStrWebContents:paramObj set aMainMes to myMessage of paramObj set aSubMes to mySubMessage of paramObj set htmlString to (htmlStr of paramObj) set aWidth to 920 set aHeight to 500 –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 array2DToJSONArray(aList) set anArray to NSMutableArray’s arrayWithArray:aList set jsonData to NSJSONSerialization’s dataWithJSONObject:anArray options:(0 as integer) |error|:(missing value) –0 is set resString to NSString’s alloc()’s initWithData:jsonData encoding:(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 on hasInternetConnection(aURL) 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:5.0 set urlRes to (current application’s NSURLConnection’s sendSynchronousRequest:aReq returningResponse:(missing value) |error|:(missing value)) if urlRes = missing value then return false else return true end if end hasInternetConnection end script |
d3-cloudを用いてワードクラウドを表示するAppleScriptです。
本AppleScriptでは、
{|word|:"NSString", |count|:97}
のように、登場単語、登場回数のように集計ずみのデータをJSONに変換してワードクラウド表示させています。この(AppleScriptの予約語にかぶりまくりな)属性ラベルはd3-cloud側の仕様です。
以前に作った「Tag CloudっぽいRTFの作成」のデータを用いて(属性ラベルを置換して)表示させたものがこちら(↑)。
Tag/Word Cloud関連のJavaScriptについては前から気になって調べてはいたのですが、「ローカルにデータを持つスクリプトが多い」「d3-cloud自体をローカルにインストールさせる例が多い」(実行速度などの問題で?)という状況で、ありもののスクリプトをこのアラートダイアログ上にはりつけたWkWebViewの「箱庭環境」で追加スクリプトのインストールなしで動くように書き換えるのに少々手間取りました。
CDNにホスティングされているd3-cloudを呼び出すことで、ローカルにd3-cloudをインストールせずに実行していますが、将来的にこれが変更・廃止された場合には別のWeb上のどこかにホスティングされているd3-cloudを呼び出すことになります。
ローカルにあるテキストコンテンツ(CotEditorで編集中の文章とか、Pagesで作成中のワープロ文章とか、Keynoteで作成中のプレゼン資料の内容とか)を分析して頻出単語を取り出し、タグクラウドといいますかワードクラウドで表示して全体の見通しをつけるというScriptは作りたいと思っていました。
AppleScript名:アラートダイアログ上にd3-cloudを用いてワードクラウドを表示.scptd |
— – Created by: Takaaki Naganoya – Created on: 2020/06/13 — – 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 NSMutableArray : a reference to current application’s NSMutableArray property NSJSONSerialization : a reference to current application’s NSJSONSerialization 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 {{|word|:"NSString", |count|:97}, {|word|:"NSURL", |count|:78}, {|word|:"Keynote", |count|:52}, {|word|:"NSMutableArray", |count|:51}, {|word|:"NSAlert", |count|:50}, {|word|:"NSRunningApplication", |count|:49}, {|word|:"NSArray", |count|:48}, {|word|:"CotEditor", |count|:44}, {|word|:"NSColor", |count|:44}, {|word|:"Finder", |count|:41}, {|word|:"NSImage", |count|:39}, {|word|:"Numbers", |count|:38}, {|word|:"NSPredicate", |count|:34}, {|word|:"NSView", |count|:32}, {|word|:"NSButton", |count|:28}, {|word|:"Safari", |count|:28}, {|word|:"NSScreen", |count|:27}, {|word|:"iTunes", |count|:25}, {|word|:"NSUTF8StringEncoding", |count|:24}, {|word|:"NSDictionary", |count|:22}, {|word|:"NSScrollView", |count|:21}, {|word|:"NSBitmapImageRep", |count|:20}, {|word|:"NSFileManager", |count|:20}, {|word|:"NSMutableDictionary", |count|:19}, {|word|:"NSURLRequest", |count|:18}, {|word|:"NSUUID", |count|:18}, {|word|:"NSWindow", |count|:17}, {|word|:"NSBezierPath", |count|:16}, {|word|:"NSFont", |count|:16}, {|word|:"WKWebView", |count|:16}, {|word|:"WKWebViewConfiguration", |count|:16}, {|word|:"NSWorkspace", |count|:15}, {|word|:"Pages", |count|:15}, {|word|:"Script Editor", |count|:15}, {|word|:"System Events", |count|:15}, {|word|:"WKUserContentController", |count|:15}, {|word|:"WKUserScript", |count|:15}, {|word|:"NSAlertSecondButtonReturn", |count|:14}, {|word|:"NSJSONSerialization", |count|:14}, {|word|:"NSSortDescriptor", |count|:14}} set jsonStr to array2DToJSONArray(aRecArray) of me –https://qiita.com/january108/items/5388799531c1ace8324e set myStr to "<!DOCTYPE HTML> <html lang=\"en\"> <head> <meta charset=\"UTF-8\"> <title>D3 Word Clouds</title> <meta name=\"author\" content=\"d4i\"/> </head> <body> <script src=\"http://d3js.org/d3.v3.min.js\" charset=\"utf-8\"></script> <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3-cloud/1.2.5/d3.layout.cloud.min.js\"></script> <script> var data = %@; var width = 600, height = 400, fill = d3.scale.category20(), maxcount = d3.max(data, function(d){ return d.count; } ), wordcount = data.map(function(d) { return {text: d.word, size: d.count / maxcount * 100}; }); d3.layout.cloud().size([width, height]) .words(wordcount) .padding(5) .rotate(function() { return ~~(Math.random() * 2) * 90; }) .font(\"Impact\") .fontSize(function(d) { return d.size; }) .on(\"end\", draw) .start(); function draw(words) { d3.select(\"body\").append(\"svg\") .attr({ \"width\": width, \"height\": height }) .append(\"g\") .attr(\"transform\", \"translate(\" + [ width >> 1, height >> 1 ] + \")\") .selectAll(\"text\") .data(words) .enter() .append(\"text\") .style({ \"font-size\": function(d) { return d.size + \"px\"; }, \"font-family\": \"Impact\", \"fill\": function(d, i) { return fill(i); } }) .attr({ \"text-anchor\": \"middle\", \"transform\": function(d) { return \"translate(\" + [d.x, d.y] + \")rotate(\" + d.rotate + \")\"; } }) .text(function(d) { return d.text; }); } </script> </body> </html>" set aString to current application’s NSString’s stringWithFormat_(myStr, jsonStr) as string set paramObj to {myMessage:"D3 Test", mySubMessage:"This is a d3-cloud word cloud test", htmlStr:aString} –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 620 set aHeight to 420 –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 NSMutableArray’s arrayWithArray:aList set jsonData to 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 |