Menu

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

AppleScriptの穴

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

カテゴリー: Text

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

Posted on 7月 30, 2020 by Takaaki Naganoya

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

★Click Here to Open This Script 

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

よみがなタグを削除

Posted on 7月 1, 2020 by Takaaki Naganoya

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

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

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


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

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

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

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

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

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

end getData

★Click Here to Open This Script 

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

CotEditor上で選択中のJavaScriptのrecord in listをASのオブジェクトに変換

Posted on 6月 29, 2020 by Takaaki Naganoya

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

★Click Here to Open This Script 

Posted in list Record Text | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy CotEditor | Leave a comment

クリップボード内のテキストをSayコマンドで読み上げて音声ファイル化

Posted on 5月 27, 2020 by Takaaki Naganoya

読み上げ対象のテキストをコピーした状態で実行するAppleScriptです。クリップボード内のテキストをSayコマンドで読み上げて、音声ファイルにレンダリングします。出力後、読み上げ所要時間を出力ファイルから求めてダイアログ表示します。

音声レンダリング処理は実際の音声読み上げ処理よりも短い時間で完了します。

–> Downlad Script With library within its bundle

掲載のリストを実行しても、スライダー入力ライブラリが含まれていないため、そのままでは実行できません。↑のScriptをまるごとダウンロードして展開すると、ライブラリ入りのScriptになります。実行にはダウンロードしたScriptをご利用ください。プログラムリスト掲載は参考のために行なっているものです。


▲ステップ1:念のために、読み上げ対象テキストをダイアログ表示


▲ステップ2:読み上げ時の速度をスライダーで選択


▲ステップ3:読み上げ音声を選択


▲ステップ4:読み上げ所要時間をダイアログ表示


▲ステップ5:音声レンダリングしたファイルをQuickTime Playerでオープン

AppleScript名:クリップボード内のテキストをSayコマンドで読み上げて音声ファイル化.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/05/27
—
–  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 "AVFoundation"
use scripting additions
use slLib : script "sliderLib"

property |NSURL| : a reference to current application’s |NSURL|
property NSDate : a reference to current application’s NSDate
property NSUUID : a reference to current application’s NSUUID
property NSFileManager : a reference to current application’s NSFileManager
property AVAudioPlayer : a reference to current application’s AVAudioPlayer
property NSDateFormatter : a reference to current application’s NSDateFormatter
property NSSpeechSynthesizer : a reference to current application’s NSSpeechSynthesizer

set aInfo to clipboard info
set uCount to (clipboard info for Unicode text)
if uCount = {} then
  display dialog "There is no text information in the clipboard" with title "Terminate information" buttons {"OK"} default button 1 with icon 2
  
return
end if

set totalCount to item 2 of item 1 of uCount

set aStr to the clipboard as text

–読み上げ内容の確認
display dialog aStr with title "Text length:" & (uCount as string) & " chars."

–読み上げ速度をSliderで入力
set rRes to slLib’s chooseBySlider(180, 220, "Select TTS reading pitch (small number:slow)")

–読み上げTTSキャラクタの選択
set aLoc to (current application’s NSLocale’s currentLocale()’s identifier()) as string –>  "ja_JP"
set vList to getTTSVoiceNameWithLanguage(aLoc) of me
set vRes to choose from list vList with prompt ("Select TTS Voice in your language :" & aLoc) without empty selection allowed
if vRes = false then return

set vCharacter to contents of first item of vRes

–音声ファイルの作成先パスを求める
set aUUID to NSUUID’s UUID()’s UUIDString() as string
set aPath to (((path to movies folder) as string) & aUUID & ".aif")
set aPOSIX to POSIX path of aPath

–音声レンダリング
tell current application
  say aStr using vCharacter saving to (aPOSIX) speaking rate rRes without waiting until completion
end tell

–レンダリングした音声の読み上げ所要時間を計算
set aDur to getDuration(aPath as alias) of me

–レンダリングした音声ファイルをオープン
tell application "QuickTime Player"
  open aPath
end tell

–完了報告
display dialog "読み上げ所要時間:" & my formatHMS(aDur)

on getTTSVoiceNameWithLanguage(voiceLang)
  set outArray to current application’s NSMutableArray’s new()
  
  
set aList to NSSpeechSynthesizer’s availableVoices()
  
set bList to aList as list
  
  
repeat with i in bList
    set j to contents of i
    
set aDIc to (NSSpeechSynthesizer’s attributesForVoice:j)
    (
outArray’s addObject:aDIc)
  end repeat
  
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat_("VoiceLocaleIdentifier == %@", voiceLang)
  
set filteredArray to outArray’s filteredArrayUsingPredicate:aPredicate
  
set aResList to (filteredArray’s valueForKey:"VoiceName") as list
  
  
return aResList
end getTTSVoiceNameWithLanguage

on getDuration(aFile)
  set aURL to |NSURL|’s fileURLWithPath:(POSIX path of aFile)
  
  
repeat 1000 times
    set aAudioPlayer to AVAudioPlayer’s alloc()’s initWithContentsOfURL:aURL |error|:(missing value)
    
set aRes to aAudioPlayer’s prepareToPlay()
    
if aRes as boolean = true then exit repeat
    
delay 0.5
  end repeat
  
  
set channelCount to aAudioPlayer’s numberOfChannels()
  
set aDuration to aAudioPlayer’s duration()
  
return aDuration as real
end getDuration

on retAvailableTTSnames()
  set outList to {}
  
  
set aList to NSSpeechSynthesizer’s availableVoices()
  
set bList to aList as list
  
  
repeat with i in bList
    set j to contents of i
    
set aInfo to (NSSpeechSynthesizer’s attributesForVoice:j)
    
set aInfoRec to aInfo as record
    
set aName to VoiceName of aInfoRec
    
set the end of outList to aName
  end repeat
  
  
return outList
end retAvailableTTSnames

on formatHMS(aTime)
  set aDate to NSDate’s dateWithTimeIntervalSince1970:aTime
  
set aFormatter to NSDateFormatter’s alloc()’s init()
  
  
—This formatter text is localized in Japanese.
  
if aTime < hours then
    aFormatter’s setDateFormat:"mm分ss秒"
  else if aTime < days then
    aFormatter’s setDateFormat:"HH時間mm分ss秒"
  else
    aFormatter’s setDateFormat:"DD日HH時間mm分ss秒"
  end if
  
  
set timeStr to (aFormatter’s stringFromDate:aDate) as string
  
return timeStr
end formatHMS

★Click Here to Open This Script 

Posted in dialog file Language Locale Text | Tagged 10.13savvy 10.14savvy 10.15savvy AVAudioPlayer NSDate NSDateFormatter NSFileManager NSMutableArray NSPredicate NSSpeechSynthesizer NSURL NSUUID | Leave a comment

クリップボード内の文字種別を集計して円グラフ表示

Posted on 5月 16, 2020 by Takaaki Naganoya

クリップボード内に文字列が入っていれば、いいかえれば「文字列をコピーした状態であれば」、クリップボード内容をテキストとして取り出して文字種別ごとに集計して構成比を円グラフで表示するAppleScriptです。

# CAUTION: This script process Japanese characters. So, this script make no sense for other language users

グラフ表示部分は手抜きでGoogle Chartsを呼び出しているだけなので、Macがネットワークに接続されていない場合には表示できません。

macOS標準装備のScript Menuに入れて使っています。複数の円グラフを表示させることも可能なので、典型的な例文(新聞、論文、なろう系、技術系文章、文学作品)のグラフを一覧表示して、どの例文の使用比率に近いかといったことを見てわかるようにできそうです(やらないけど)。

ありものをただ引っ張り出してきて、Script文でつないだだけなので、オリジナルで記述した部分はほとんどありません。

とはいえ、技術的にはいろいろなハードルを乗り越えまくって動かしているものでもあります。

・メインスレッドでしか動かせないWkWebView、NSAlertをScriptから呼び出している(実行環境に左右されずに実行)
・Cocoa Scriptingを行うAppleScriptObjCをscript文でscript object化して(カプセル化して)呼び出し、再利用
・WkWebViewをdialog内に表示して、マウスオーバーでデータ内容が見えるようなインタラクティブなグラフを表示

といった、いろいろ無茶なことをやっているScriptです。ただ、すでに見慣れた光景になりつつありますけれども。

AppleScript名:クリップボード内の文字種別を集計して円グラフ表示.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/05/14
—
–  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 NSScreenSaverWindowLevel : a reference to current application’s NSScreenSaverWindowLevel
property WKUserScriptInjectionTimeAtDocumentEnd : a reference to current application’s WKUserScriptInjectionTimeAtDocumentEnd

property returnCode : 0

–Calc Clipboard
set aRes to clipAnaliticsMain() of clipboardInfoKit
if aRes = false then return —クリップボードが空だった(文字列的に)

set totalC to totalC of aRes

set aList to {{"文字種別", "構成比"}} & rating of aRes

set aJsonArrayStr to array2DToJSONArray(aList) of me

–Pie Chart Template HTML
set myStr to "<!DOCTYPE html>
<html lang=\"UTF-8\">
<body>
<div id=\"piechart\"></div>

<script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>

<script type=\"text/javascript\">
// Load google charts
google.charts.load(’current’, {’packages’:[’corechart’]});
google.charts.setOnLoadCallback(drawChart);

// Draw the chart and set the chart values
function drawChart() {
var data = google.visualization.arrayToDataTable(%@);

// Optional; add a title and set the width and height of the chart
var options = {
is3D: true,
   ’width’:600, ’height’:400
};

// Display the chart inside the <div> element with id=\"piechart\"
var chart = new google.visualization.PieChart(document.getElementById(’piechart’));
chart.draw(data, options);
}
</script>

</body>
</html>"

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

set paramObj to {myMessage:"文字種別構成比", mySubMessage:"クリップボードの内容を集計。文字数は" & (totalC as string) & "文字", 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 600
  
set aHeight to 450
  
  
–WebViewをつくる
  
set aConf to WKWebViewConfiguration’s alloc()’s init()
  
  
–指定HTML内のJavaScriptをFetch
  
set jsSource to pickUpFromToStr(htmlString, "<script type=\"text/javascript\">", "</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 – 100)) configuration:aConf
  
aWebView’s setNavigationDelegate:me
  
aWebView’s setUIDelegate:me
  
aWebView’s setTranslatesAutoresizingMaskIntoConstraints:true
  
  
set bURL to |NSURL|’s fileURLWithPath:(POSIX path of (path to me))
  
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
  
  
myWindow’s setLevel:(NSScreenSaverWindowLevel)
  
  
— 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

script clipboardInfoKit
  use scripting additions
  
use framework "Foundation"
  
property parent : AppleScript
  
  
property NSString : a reference to current application’s NSString
  
property NSNumber : a reference to current application’s NSNumber
  
property NSDictionary : a reference to current application’s NSDictionary
  
property NSCountedSet : a reference to current application’s NSCountedSet
  
property NSCharacterSet : a reference to current application’s NSCharacterSet
  
property NSMutableArray : a reference to current application’s NSMutableArray
  
property NSNumberFormatter : a reference to current application’s NSNumberFormatter
  
property NSRegularExpressionSearch : a reference to current application’s NSRegularExpressionSearch
  
property NSNumberFormatterRoundUp : a reference to current application’s NSNumberFormatterRoundUp
  
property NSNumberFormatterRoundDown : a reference to current application’s NSNumberFormatterRoundDown
  
  
  
on clipAnaliticsMain()
    set cCount to 0
    
set hCount to 0
    
set kCount to 0
    
set oCount to 0
    
set tCount to 0
    
    
using terms from scripting additions
      set aStr to (the clipboard as «class utf8»)
      
if aStr = "" then
        display dialog "No text data in clipboard" buttons {"OK"} default button 1
        
return false
      end if
    end using terms from
    
    
set aRec to detectCharKindRating(aStr) of me
    
    
set cCount to cCount + (kanjiNum of aRec)
    
set hCount to hCount + (hiraganaNum of aRec)
    
set kCount to kCount + (katakanaNum of aRec)
    
set oCount to oCount + (otherNum of aRec)
    
set tCount to tCount + (totalCount of aRec)
    
    
return {rating:{{"漢字", cCount}, {"ひらがな", hCount}, {"カタカナ", kCount}, {"その他", oCount}}, totalC:tCount}
  end clipAnaliticsMain
  
  
  
  
on detectCharKindRating(aStr as string)
    set aList to NSMutableArray’s arrayWithArray:(characters of aStr)
    
set theCountedSet to NSCountedSet’s alloc()’s initWithArray:aList
    
set theEnumerator to theCountedSet’s objectEnumerator()
    
    
set cCount to 0
    
set hCount to 0
    
set kCount to 0
    
set oCount to 0
    
set totalC to length of aStr
    
    
repeat
      set aValue to theEnumerator’s nextObject()
      
if aValue is missing value then exit repeat
      
      
set aStr to aValue as string
      
set tmpCount to (theCountedSet’s countForObject:aValue)
      
      
set s1Res to chkKanji(aStr) of me
      
set s2Res to chkKatakana(aStr) of me
      
set s3Res to chkHiragana(aStr) of me
      
      
if s1Res = true then
        set cCount to cCount + tmpCount
      else if s2Res = true then
        set kCount to kCount + tmpCount
      else if s3Res = true then
        set hCount to hCount + tmpCount
      else
        set oCount to oCount + tmpCount
      end if
    end repeat
    
    
set ckRes to roundingUp((cCount / totalC) * 100, 1) of me
    
set kkRes to roundingUp((kCount / totalC) * 100, 1) of me
    
set hgRes to roundingUp((hCount / totalC) * 100, 1) of me
    
set otRes to roundingUp((oCount / totalC) * 100, 1) of me
    
    
return {kanjiNum:cCount, kanjiRating:ckRes, hiraganaNum:hCount, hiraganaRating:hgRes, katakanaNum:kCount, katakanaRating:kkRes, otherNum:oCount, otherRating:otRes, totalCount:totalC}
  end detectCharKindRating
  
  
  
on chkKanji(aChar)
    return detectCharKind(aChar, "[一-龠]") of me
  end chkKanji
  
  
on chkHiragana(aChar)
    return detectCharKind(aChar, "[ぁ-ん]") of me
  end chkHiragana
  
  
on chkKatakana(aChar)
    return detectCharKind(aChar, "[ァ-ヶ]") of me
  end chkKatakana
  
  
on detectCharKind(aChar, aPattern)
    set aChar to NSString’s stringWithString:aChar
    
set searchStr to NSString’s stringWithString:aPattern
    
set matchRes to aChar’s rangeOfString:searchStr options:(NSRegularExpressionSearch)
    
if matchRes’s location() = (current application’s NSNotFound) or (matchRes’s location() as number) > 9.99999999E+8 then
      return false
    else
      return true
    end if
  end detectCharKind
  
  
on roundingUp(aNum, aDigit as integer)
    set a to aNum as real
    
set aFormatter to NSNumberFormatter’s alloc()’s init()
    
aFormatter’s setMaximumFractionDigits:aDigit
    
aFormatter’s setRoundingMode:(NSNumberFormatterRoundUp)
    
set aStr to aFormatter’s stringFromNumber:(NSNumber’s numberWithFloat:a)
    
return (aStr as text) as real
  end roundingUp
end script

★Click Here to Open This Script 

Posted in dialog Internet JavaScript Text | Tagged 10.13savvy 10.14savvy 10.15savvy NSAlert NSButton NSCharacterSet NSCountedSet NSDictionary NSMutableArray NSNumber NSNumberFormatter NSNumberFormatterRoundDown NSNumberFormatterRoundUp NSRegularExpressionSearch NSRunningApplication NSScreenSaverWindowLevel NSString NSURL NSURLRequest NSUTF8StringEncoding WKUserContentController WKUserScript WKUserScriptInjectionTimeAtDocumentEnd WKWebView WKWebViewConfiguration | Leave a comment

Previewで現在表示中のPDFのページ番号を抽出する

Posted on 4月 29, 2020 by Takaaki Naganoya

macOS標準搭載の画像/PDFビューワーの「Preview.app」で表示中のPDFの、現在表示中のページの番号を取得するAppleScriptです。

本来、Preview.appのような超低機能アプリケーションから強引に情報を(GUI Scriptingまで使って)取得する意味はありません。PDFビューワーとしてまっとうな機能を持っているSkimを使って表示中のページ番号を取得するのが筋です。

ただ、どうしてもPreviewでないといけないケースで、仕方なく作ったものですが、英語環境でも日本語環境でも同様に動くために作ってみたらこんな感じに。指定アプリケーション単体で言語環境を指定して起動できると、各言語環境における動作確認が手軽に行えてよいと思うものの、手段がありそうで見つかりません(Xcode上でそういう起動ができるので、不可能ではないと思うのですが)。


▲英語環境で実行したところ(macOS 10.14.6)


▲日本語環境で実行したところ(macOS 10.15.4)

仕方なくGUI Scripting経由でウィンドウのタイトルを取得して、ファイル名とページ情報を文字列処理で分離しています。このあたり、英語環境と日本語環境でセパレータ(括弧)が異なるので、分離したページ情報から数字判定を行なって取得しています。Preview.appのアプリケーションバンドル内にこうしたフォーマットのテキストが存在していれば、そちらを使うべきです(見つかっていないので現状こんな感じで)。

GUI Scripting内でプロセス名を指定する箇所で、ローカライズされたプロセス名をCocoaの機能を用いて取得しています。これで、英語環境と日本語環境については問題なく共通Scriptでカバーできています。

AppleScript名:Previewで現在表示中のPDFのページ番号を抽出する.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/04/29
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

set pNum to retPreviewDispPageNumber() of me

on retPreviewDispPageNumber()
  set aLocName to getLocalizedName("com.apple.Preview") of me
  
  
tell application "Preview"
    if (count every document) = 0 then return false
  end tell
  
  
tell application "System Events"
    tell process aLocName
      tell window 1
        set aTitle to title
      end tell
    end tell
  end tell
  
  
set aPageInfo to pickUpFromToStr(aTitle, "(", ")") of me –English env
  
if aPageInfo = false then
    set aPageInfo to pickUpFromToStr(aTitle, "(", ")") of me –double witdh parenthesis (Japanese env)
  end if
  
set pList to words of aPageInfo
  
set hitF to false
  
repeat with i in pList
    set nRes to chkNumeric(i) of me
    
if nRes = true then
      set hitF to true
      
exit repeat
    end if
  end repeat
  
  
if hitF = false then return
  
return i as integer
end retPreviewDispPageNumber

on getLocalizedName(aBundleID as string)
  set pRes to getProcessByBUndleID(aBundleID) of me
  
if pRes = false then return ""
  
set pName to pRes’s localizedName()
  
return pName as string
end getLocalizedName

–指定プロセスを取得する
on getProcessByBUndleID(aBundleID)
  set appArray to current application’s NSRunningApplication’s runningApplicationsWithBundleIdentifier:aBundleID
  
if appArray’s |count|() > 0 then
    set appItem to appArray’s objectAtIndex:0
    
return appItem
  else
    return false
  end if
end getProcessByBUndleID

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 chkNumeric(checkString)
  set digitCharSet to current application’s NSCharacterSet’s characterSetWithCharactersInString:"0123456789"
  
set ret to my chkCompareString:checkString baseString:digitCharSet
  
return ret as boolean
end chkNumeric

on chkCompareString:checkString baseString:baseString
  set aScanner to current application’s NSScanner’s localizedScannerWithString:checkString
  
aScanner’s setCharactersToBeSkipped:(missing value)
  
aScanner’s scanCharactersFromSet:baseString intoString:(missing value)
  
return (aScanner’s isAtEnd()) as boolean
end chkCompareString:baseString:

★Click Here to Open This Script 

Posted in GUI Scripting PDF Text | Tagged 10.13savvy 10.14savvy 10.15savvy NSCharacterSet NSRunningApplication NSScanner Preview | Leave a comment

指定Bundle IDのstringsファイル中における指定タイトルの指定言語のローカライズ版を求める

Posted on 2月 24, 2020 by Takaaki Naganoya

/Applicationsフォルダ以下のすべてのアプリケーションのバンドル中のstringsファイル中を走査して、指定の言語における指定キーワード(”Quit”など)の指定言語におけるローカライズした文字列を取得するAppleScriptです。

自分でアプリケーションのローカライズを行う際に、既存のmacOS用のアプリケーションのバンドル内にあるstringsファイルを参考にするためのツールです。

もともとは、Shane StanleyがLate Night Softwareのフォーラムに投稿したプログラムですが、自分もいろいろ試していたように、アプリケーション側のローカライズのされ方(言語別のフォルダ名の名称指定)に「ゆらぎ」があるため、そのあたりは総当たりでテストしているようです。

オリジナルではデータが存在しない場合にはエラーにしていましたが、このようにすべてのアプリケーションに対してループで処理を行うような場合にはエラーで止まっては困るので、そのあたりを書き換えています。

/Applicationsフォルダ以下のSpotlight検索によるアプリケーションの取得についてはMetadata Libを用いています。自分の開発環境で1キーワード(x バンドル内のすべてのstringsファイル x すべてのアプリケーション)の問い合わせに3.6〜5秒程度かかっています。HDDの環境ではこれより大幅に長くかかるはずなので、ちょっと考えたくありません。

また、Stringsファイルで供給されるローカライズ情報については探すことができますが、OS側が強制的に供給するWindowメニューなどの内容については本Scriptで調査することはできません。ねんのため。

AppleScript名:指定Bundle IDのstringsファイル中における指定タイトルの指定言語のローカライズ版を求める.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/02/24
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.5" — El Capitan (10.11) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions
use mdLib : script "Metadata Lib" version "2.0.0" –https://macosxautomation.com/applescript/apps/Script_Libs.html

property NSWorkspace : a reference to current application’s NSWorkspace

set targStr to "Performance"
set origLang to "en" –From
set targLang to "hu" –To

set tList to {}

set origPath to POSIX path of (path to applications folder)
set aResList to mdLib’s searchFolders:{origPath} searchString:("kMDItemContentType == %@") searchArgs:{"com.apple.application-bundle"}
repeat with i in aResList
  set aTitleRes to getAppGUITitleWithCurrentLocale(i, targStr, origLang, targLang) of me
  
if aTitleRes is not equal to missing value and aTitleRes is not in tList then
    set the end of tList to aTitleRes
  end if
end repeat

return tList
–> {"Előadás", "Teljesítmény"}

–指定Bundle IDのstringsファイル中における指定タイトルの現在実行中のロケールのローカライズ版を求める
on getAppGUITitleWithCurrentLocale(aPath, aTargetTitle, origLang, targLang)
  return my localizedStringFor:aTargetTitle inBundle:aPath destLang:targLang sourceLang:origLang
end getAppGUITitleWithCurrentLocale

–Bundle IDからアプリケーションのPathを返す
on retAppAbusolutePathFromBundleID(aBundleID)
  set appPath to NSWorkspace’s sharedWorkspace()’s absolutePathForAppBundleWithIdentifier:aBundleID
  
if appPath = missing value then return false
  
return appPath as string
end retAppAbusolutePathFromBundleID

–Original By Shane Stanley@Late Night Software
–Modified By Takaaki Naganoya
–https://forum.latenightsw.com/t/localizing-gui-scripts/2246
on localizedStringFor:baseString inBundle:aPOSIX destLang:destLangCode sourceLang:sourceLangCode
  set anURL to current application’s |NSURL|’s fileURLWithPath:aPOSIX
  
set theBundle to current application’s NSBundle’s bundleWithURL:anURL
  
if theBundle = missing value then return missing value
  
  
set sourceLangString to current application’s NSString’s stringWithString:sourceLangCode
  
set destLangString to current application’s NSString’s stringWithString:destLangCode
  
  
— get source strings values
  
set theURLs to theBundle’s URLsForResourcesWithExtension:"strings" subdirectory:"" localization:sourceLangString
  
if theURLs = missing value then return missing value
  
if theURLs’s |count|() < 2 and (sourceLangString’s containsString:"_") as boolean then
    — try stripping off country-specific part
    
set sourceLangString to sourceLangString’s substringToIndex:2
    
set theURLs to theBundle’s URLsForResourcesWithExtension:"strings" subdirectory:"" localization:sourceLangString
  end if
  
  
if theURLs’s |count|() < 2 then
    — try long name for localization
    
set sourceLangString to (current application’s NSLocale’s localeWithLocaleIdentifier:"en")’s localizedStringForLocaleIdentifier:sourceLangString
    
set theURLs to theBundle’s URLsForResourcesWithExtension:"strings" subdirectory:"" localization:sourceLangString
  end if
  
  
if theURLs’s |count|() < 2 then return missing value –error "No " & sourceLangCode & " localization found"
  
  
repeat with sourceURL in theURLs
    — skip unlocalized file
    
if not (sourceURL’s URLByDeletingLastPathComponent()’s lastPathComponent()’s isEqualToString:"Resources") as boolean then
      set theData to (current application’s NSData’s alloc()’s initWithContentsOfURL:sourceURL)
      
      
if theData is missing value then return — error "No " & sourceLangCode & " localization found"
      
set sourceDict to (current application’s NSPropertyListSerialization’s propertyListWithData:theData options:0 format:0 |error|:(missing value))
      
if sourceDict = missing value then return missing value
      
      
set theKey to (sourceDict’s allKeysForObject:baseString)’s firstObject()
      
      
if theKey is not missing value then
        set stringsFileName to sourceURL’s lastPathComponent()’s stringByDeletingPathExtension()
        
set localURL to (theBundle’s URLForResource:stringsFileName withExtension:"strings" subdirectory:"" localization:destLangString)
        
        
if localURL is missing value and (destLangString’s containsString:"_") as boolean then
          — try stripping off country-specific part
          
set destLangString to (destLangString’s substringToIndex:2)
          
set localURL to (theBundle’s URLForResource:stringsFileName withExtension:"strings" subdirectory:"" localization:destLangString)
        end if
        
        
if localURL is missing value then
          — try long name for localization
          
set destLangString to ((current application’s NSLocale’s localeWithLocaleIdentifier:"en")’s localizedStringForLocaleIdentifier:destLangString)
          
set localURL to (theBundle’s URLForResource:stringsFileName withExtension:"strings" subdirectory:"" localization:destLangString)
        end if
        
        
if localURL is missing value then return missing value — "No " & destLangCode & " localization found"
        
        
set theData to (current application’s NSData’s alloc()’s initWithContentsOfURL:localURL)
        
if theData is missing value then missing value — "No " & destLangCode & " localization found"
        
set destDict to (current application’s NSPropertyListSerialization’s propertyListWithData:theData options:0 format:0 |error|:(missing value))
        
set destValue to (destDict’s objectForKey:theKey)
        
        
–if destValue is not missing value then return {destValue as text, stringsFileName as text}
        
if destValue is not missing value then return destValue as text
        
return missing value
      end if
    end if
  end repeat
  
return missing value
end localizedStringFor:inBundle:destLang:sourceLang:

★Click Here to Open This Script 

Posted in file File path Language Locale Text | Tagged 10.14savvy 10.15savvy NSBundle NSData NSLocale NSPropertyListSerialization NSString NSURL NSWorkspace | Leave a comment

BlogアーカイブのMarkdown書類をリネーム。親、親+1階層フォルダをMM, YYYYとみなして反映

Posted on 1月 19, 2020 by Takaaki Naganoya

Finderで選択中のファイルすべてに対して、親フォルダ名、親+1階層のフォルダ名を反映させたファイル名をつけるAppleScriptです。

Blogアーカイブ本を作るのに、こうした道具を作って使っています。一度書いておけば、2度目からは大幅に時間を短縮できます。最初のファイルから拡張子を取得してそれを後続のファイルすべてに適用するため、同一種類のファイルである必要があります。自分用のツールならではの手抜きといったところでしょうか。

AppleScript名:BlogアーカイブのMarkdown書類をリネーム。親、親+1階層フォルダをMM, YYYYとみなして反映 .scptd
— Created 2020-01-18 by Takaaki Naganoya
— 2020 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

–選択ファイルを取得
tell application "Finder"
  set aSel to selection as alias list –Select documents to Rename
end tell

set aCount to 10 –start
set aStep to 10
set aDigit to 3

–パス情報を取得
set aFirst to first item of aSel
set aPOSIX to POSIX path of aFirst
set aPathStr to (current application’s NSString’s stringWithString:aPOSIX)
set aDateComList to aPathStr’s pathComponents() –ディレクトリごとにパス情報を分割してリスト化
set aExt to aPathStr’s pathExtension() –拡張子

set aYear to (item -3 of aDateComList) as string –親の親フォルダ名
set aMonth to (item -2 of aDateComList) as string –親フォルダ名

–リネーム(数百項目を超える場合にはFinderでは遅すぎるのでNSFileManagerで処理)
tell application "Finder"
  repeat with i in aSel
    set aTEXT to numToZeroPaddingStr(aCount, aDigit, "0") of me –3 digit
    
set aName to aYear & aMonth & aTEXT & "." & aExt
    
set name of i to aName
    
set aCount to aCount + aStep
  end repeat
end tell

–整数の値に指定桁数ゼロパディングして文字列で返す
on numToZeroPaddingStr(aNum as integer, aDigit as integer, paddingChar as text)
  set aNumForm to current application’s NSNumberFormatter’s alloc()’s init()
  
aNumForm’s setPaddingPosition:(current application’s NSNumberFormatterPadBeforePrefix)
  
aNumForm’s setPaddingCharacter:paddingChar
  
aNumForm’s setMinimumIntegerDigits:aDigit
  
  
set bNum to current application’s NSNumber’s numberWithInt:aNum
  
set aStr to aNumForm’s stringFromNumber:bNum
  
  
return aStr as text
end numToZeroPaddingStr

★Click Here to Open This Script 

Posted in file File path list Markdown Text | Tagged 10.12savvy 10.13savvy 10.14savvy 10.15savvy Finder NSNumber NSNumberFormatter NSNumberFormatterPadBeforePrefix NSString | Leave a comment

Numbersで各シート名称を置換

Posted on 1月 15, 2020 by Takaaki Naganoya

Numbersでオープン中の最前面の書類中にあるすべてのシートの名前を置換するAppleScriptです。

内容は簡単ですが、Numbersにそうした機能が存在しないので、作っておくと便利です。アーカイブ本を作るのに、こうした(↓)資料を作る必要があるわけですが、そのためにこうしたこまごまとしたScriptをその場で作って作業の効率化を図っています。


▲上の画像あくまでは処理イメージなので、厳密に同一データの処理前・処理後の画面スナップショットではありません。各シートの名称の一部の文字列(YYYY部分)のみ置換されていることをご確認ください

AppleScript名:Numbersで各シート名称を置換
tell application "Numbers"
  tell front document
    set tList to every sheet
    
repeat with i in tList
      tell i
        set aName to name
        
set bName to replaceText(aName, "2011_", "2013_") of me
        
set name to bName
      end tell
    end repeat
  end tell
end tell

–任意のデータから特定の文字列を置換
on replaceText(origData, origText, repText)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to {origText}
  
set origData to text items of origData
  
set AppleScript’s text item delimiters to {repText}
  
set origData to origData as text
  
set AppleScript’s text item delimiters to curDelim
  
return origData
end replaceText

★Click Here to Open This Script 

Posted in Text | Tagged 10.12savvy 10.13savvy 10.14savvy 10.15savvy Numbers | Leave a comment

SVGのPath指定をParseしてx,y座標の最小値、最大値を求める

Posted on 12月 30, 2019 by Takaaki Naganoya

SVGのPath指定(相対座標指定)をparseして、x,y座標の最小値、最大値を求めるAppleScriptです。

SVGで作られた世界地図を表示し、指定の国を赤く塗るというAppleScriptを試作したことがありました(choose countryといった命令を作る野望が)。しかし、メルカトル図法の世界地図で塗った箇所がわからないぐらいの規模の国が世界中にはたくさんあることを再認識しただけでした。つまり、アメリカ合衆国とかロシアとか中華人民共和国ぐらい国土が広ければ赤く塗っておけば視認できますが、赤く塗っても面積が小さければ視認できません。

そこで、地図上では「点」にしか見えないような国の位置を明示するためには、色を変えて塗る以外の表現方法が必要になってきます。

SVG世界地図上では、それぞれの国データがpathで表現されていました。このpathはすべてを絶対座標で表現するタイプと相対座標で表現するタイプがあり、部品として使いまわしたりデータサイズを抑えることを考えれば、相対座標でデータ表現したくなることでしょう。実際、自分が見つけたSVG世界地図データは相対座標でデータが作られていました。

そこで、指定のPath内の座標値をすべて絶対座標に計算し直しつつ、x,y座標の最小値、最大値を求め、その値を元に塗りつぶすことで、面積の小さな国の所在位置を赤い線の交点として表現できそうだと考えました。

そうした実証実験のために作成したのが本AppleScriptです。

テストデータは日本列島のもので、このサイズのデータからx,yの最小値、最大値を計算するのに0.06秒ぐらいで処理できています(自分の開発環境での計測値です)。プログラムの作りやすさを優先して、あとで全データから最大値/最小値を求めていますが、座標計算しながら最大値/最小値を求めれば、0.05秒ぐらいにはなると思います。
→ 同時に計算したら0.039秒で済みました

座標データ数がそれほど多くないので、Cocoaの機能を利用しても大幅な速度向上は見込めません。


▲アンドラ公国


▲バチカン市国


▲米領サモア

本Scriptで取得したPathの最小値、最大値をもとに塗りつぶしを行なってみたところ、地図上で1ドットにも満たないような面積の国でも所在位置がわかるように表現できました。

面積に応じて、塗りつぶし時のアルファ値を変更するような処理もためしていますが、面積が広いのに点にも見えない国(島で構成される国)だと、対象が見えないのに塗りつぶし色が薄くて見にくいなど、まだいろいろ試行錯誤が必要なようです。

AppleScript名:parseSVGPath.scptd
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

script spd
  property dStr : ""
  
property dList : {}
  
property d2List : {}
  
property d3List : {}
  
property absX : {}
  
property absY : {}
end script

–Initialize
set (dStr of spd) to retData() of me
set (dList of spd) to parseByDelim((dStr of spd), {"m ", " z"}) of me
set (d2List of spd) to {}

–Parse into each stroke
repeat with i in (dList of spd)
  set j to contents of i
  
if j is not equal to "" then
    set d3 to parseByDelim(j, " ") of me
    
if d3 is not equal to "" then
      set the end of (d2List of spd) to d3
    end if
  end if
end repeat

set (d3List of spd) to FlattenList((d2List of spd)) of me
set origPos to first item of (d3List of spd)
set (d3List of spd) to rest of (d3List of spd)
set {origX, origY} to parseByDelim(origPos, ",") of me

set origX to origX as real
set origY to origY as real

set (absX of spd) to {}
set (absY of spd) to {}

set the end of (absX of spd) to origX
set the end of (absY of spd) to origY

–絶対座標のリストに変換する
repeat with i in (d3List of spd)
  set j to contents of i
  
if j is not equal to "" then
    set {curX, curY} to parseByDelim(j, ",") of me
    
    
set origX to origX + (curX as real)
    
set origY to origY + (curY as real)
    
    
set the end of (absX of spd) to origX
    
set the end of (absY of spd) to origY
  end if
end repeat

set minX to minimumFromList((absX of spd)) of me
set maxX to maximumFromList((absX of spd)) of me
set minY to minimumFromList((absY of spd)) of me
set maxY to maximumFromList((absY of spd)) of me

return {{minX, minY}, {maxX, maxY}}

–最大値を取得する
on maximumFromList(nList)
  script o
    property NL : nList
  end script
  
  
set max to item 1 of o’s NL
  
repeat with i from 2 to (count nList)
    set n to item i of o’s NL
    
if n > max then set max to n
  end repeat
  
return max
  
end maximumFromList

–最小値を取得する
on minimumFromList(nList)
  script o
    property NL : nList
  end script
  
  
set min to item 1 of o’s NL
  
repeat with i from 2 to (count nList)
    set n to item i of o’s NL
    
if n < min then set min to n
  end repeat
  
return min
  
end minimumFromList

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 FlattenList(aList)
  set oldDelims to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to {"????"}
  
set aString to aList as text
  
set aList to text items of aString
  
set AppleScript’s text item delimiters to oldDelims
  
return aList
end FlattenList

on retData()
  return "m 878.53675,325.4254 0.352,0.02 0.157,-0.018 0.269,0.059 1.067,0.591 0.322,0.075 0.333,0.009 0.234,-0.048 0.206,-0.162 0.644,-0.717 0.678,-0.655 0.075,0.025 0,0.181 -0.05,0.201 -0.3,0.599 -0.333,0.804 -0.071,0.406 0.108,0.395 0.209,0.326 0.165,0.445 0.19,0.617 0.268,0.078 0.146,0.009 0.268,-0.185 0.253,-0.235 0.218,-0.029 0.229,0.04 -0.301,0.164 -0.284,0.2 -0.244,0.378 -0.091,0.071 -0.281,-0.023 -0.161,0.014 -0.329,0.158 -0.289,0.179 -0.276,0.219 -0.301,0.117 -0.321,0.028 -0.495,0.179 -0.321,0.013 -0.603,-0.156 -0.293,0.042 -0.639,0.352 -0.582,0.508 -0.509,0.569 -0.425,0.682 -0.171,0.354 -0.103,0.396 -0.014,0.262 -0.038,0.251 -0.098,0.175 -0.118,0.142 -0.351,-0.083 -0.576,-0.362 -1.117,-0.527 -1.18,-0.809 -0.664,-0.407 -1.248,0.122 -1.181,0.776 -0.105,-0.066 -0.451,-0.532 -0.219,-0.211 -0.261,-0.06 -0.194,0.007 -0.188,0.039 -0.267,0.274 -0.098,0.197 -0.076,0.224 -0.023,0.158 0.032,0.155 0.253,0.35 0.312,0.26 0.141,0.049 0.299,-0.018 0.139,0.027 0.501,0.521 0.549,0.488 0.121,0.161 -0.203,0.169 -0.222,0.084 -0.259,-0.021 -0.256,-0.064 -0.438,-0.207 -0.188,0.176 -0.292,0.361 -0.161,0.392 -0.131,0.179 -0.322,0.236 -0.341,0.122 -0.179,-0.04 -0.136,-0.148 -0.077,-0.177 -0.039,-0.206 0.072,-0.446 0.177,-0.403 0.068,-0.412 -0.145,-0.581 -0.092,-0.122 -0.362,-0.341 -0.168,-0.333 -0.04,-0.415 0.021,-0.229 0.088,-0.507 0.088,-0.256 0.166,-0.084 0.182,-0.051 0.279,-0.184 0.307,-0.238 0.294,-0.272 0.291,-0.333 0.151,-0.366 -0.249,-0.45 -0.052,-0.268 0.037,-0.253 0.266,-0.135 0.273,0.102 0.551,0.372 0.107,0.037 0.378,0.017 0.518,0.081 0.3,-0.02 0.145,-0.056 0.218,-0.307 0.107,-0.392 -0.039,-0.505 -0.002,-0.502 0.138,-0.41 0.432,-0.661 0.124,-0.39 0.045,-0.952 0.156,-0.42 0.125,-0.437 0.06,-0.918 -0.177,-0.886 -0.178,-0.436 -0.204,-0.415 0.03,-0.397 0.165,-0.369 0.004,-0.111 0.039,-0.099 0.309,-0.07 0.145,-0.079 0.139,-0.178 0.165,-0.104 0.121,0.104 0.1,0.182 0.436,0.447 0.687,0.796 0.809,1.209 0.507,0.587 0.534,0.531 0.599,0.542 0.627,0.465 0.4,0.22 0.293,0.35 0.181,0.057 z m -7.723,-4.787 -0.108,0.252 -0.146,-0.375 -0.029,-0.405 0.084,0.002 0.154,0.061 0.037,0.197 0.008,0.268 z m 0.625,0.848 -0.194,0.028 -0.227,-0.166 -0.028,-0.208 0.164,-0.166 0.163,0.061 0.163,0.214 0.054,0.112 -0.095,0.125 z m -5.091,11.738 -0.064,0.02 -0.066,-0.032 -0.065,-0.285 0.056,-0.15 0.181,-0.105 0.176,-0.029 -0.149,0.524 -0.069,0.057 z m 4.906,2.653 0.11,0.07 0.524,-0.189 -0.1,0.571 -0.056,0.575 0.038,0.952 0.047,0.428 0.091,0.414 0.224,0.296 0.292,0.21 0.423,0.669 0.227,0.82 0.16,0.397 0.12,0.416 0.037,0.19 0.003,0.19 -0.036,0.26 0.04,0.21 -0.046,0.658 -0.189,0.759 -0.024,0.387 -0.165,0.077 -0.1,0.179 -0.085,0.083 -0.095,0.064 -0.137,0.016 -0.099,0.073 -0.039,0.205 -0.063,0.189 -0.12,0.175 -0.094,0.192 -0.077,0.468 -0.028,0.479 -0.115,0.334 -0.279,0.087 -0.319,-0.005 -0.409,0.154 -0.088,0.091 -0.323,0.582 -0.093,0.341 -0.003,0.366 0.09,0.45 0.122,0.439 0.092,0.815 -0.097,1.238 -0.094,0.395 -0.205,0.267 -0.156,0.124 -0.134,0.152 -0.174,0.401 -0.288,0.798 -0.023,0.2 10e-4,0.207 -0.078,0.27 -0.05,0.265 0.047,0.308 0.089,0.288 0.386,0.737 0.151,0.218 0.17,0.198 -0.659,0.219 -0.118,0.101 -0.392,0.418 -0.125,0.396 0.01,0.438 -0.065,0.157 -0.107,0.136 -0.112,0.09 -0.438,0.2 -0.28,0.199 -0.278,0.311 -0.11,0.162 -0.215,-0.052 -0.126,-0.144 0.124,-0.18 -0.038,-0.213 0.061,-0.547 -0.069,-0.22 0.224,-0.167 0.106,-0.266 0.232,-0.213 0.167,-0.189 0.029,-0.154 -0.149,-0.166 -0.158,-0.12 -0.218,0 -0.21,0.035 -0.137,0.158 -0.045,0.215 0.011,0.1 -0.018,0.087 -0.33,0.294 0.043,0.307 0.097,0.156 0.124,0.074 -0.037,0.105 -0.157,0.247 -0.109,0.024 -0.201,-0.346 -0.252,-0.189 -0.312,10e-4 -0.32,0.069 -0.243,0.23 -0.08,0.191 -0.052,0.197 0.018,0.479 -0.101,0.4 -0.198,0.351 -0.092,0.128 -0.241,0.238 -0.167,0.031 -0.118,-0.108 -0.096,-0.164 0.122,-0.6 -0.005,-0.338 0.282,-0.172 -0.231,-0.24 -0.284,-0.097 -0.399,0.128 -0.113,0.145 -0.077,0.194 -0.215,0.246 -0.236,0.229 -0.269,0.392 -0.18,0.463 -0.59,-0.151 -0.321,-0.034 -0.325,0.012 -0.576,-0.057 -0.632,0.095 -0.72,0.182 0.043,-0.131 0.592,-0.279 0.021,-0.082 -0.057,-0.153 -0.147,-0.007 -0.354,0.053 -0.181,-0.023 -0.073,-0.164 -0.12,-0.07 -0.08,0.067 0.026,0.318 -0.087,0.042 -0.117,-0.082 0.037,-0.248 -0.079,-0.363 -0.01,-0.226 0.124,-0.194 -0.127,-0.082 -0.134,0.031 -0.17,0.093 -0.15,0.132 -0.317,0.663 -0.123,0.378 0.232,0.303 0.634,0.423 0.108,0.104 0.002,0.18 -0.077,0.191 -0.172,0.083 -0.695,0.141 -0.603,0.273 -0.174,0.276 -0.548,1.066 -0.439,0.727 -0.62,0.25 -0.68,-0.223 -0.165,-0.253 -0.133,-0.313 -0.253,-0.283 -0.229,-0.309 -0.133,-0.367 0.021,-0.592 -0.099,-0.357 0.089,-0.095 0.375,-0.218 0.123,-0.122 0.212,-0.284 0.076,-0.158 0.011,-0.239 -0.17,-0.125 -0.44,0.004 -0.439,0.075 -0.313,-0.104 -0.407,-0.29 -0.126,-0.062 -0.438,-0.018 -0.313,0.054 -0.307,0.105 -0.325,0.034 -0.108,0.055 -0.375,0.355 -0.299,0.223 -0.258,0.111 -0.557,0.029 -0.279,0.072 -0.292,0.117 -0.082,-0.01 -0.308,0.162 -0.354,0.14 -0.188,0.14 -0.347,-0.092 -0.686,0.251 -0.332,0.031 -0.342,-0.139 -0.318,-0.225 -0.305,0.097 -0.209,0.331 -0.102,0.658 -0.119,0.296 -0.036,0.355 -0.158,-0.056 -0.918,-0.639 -0.063,-0.023 -0.742,0.11 -0.191,0.053 -0.239,0.129 -0.253,0.058 -0.23,-0.093 -0.221,-0.151 -0.212,0.045 -0.217,0.106 -0.084,-0.966 0.043,-0.127 0.133,-0.169 0.147,-0.145 0.359,-0.05 0.363,0.047 0.26,-0.066 0.22,-0.192 0.231,-0.272 0.261,-0.222 0.354,-0.175 0.342,-0.201 0.301,-0.282 0.285,-0.309 0.262,-0.227 0.285,-0.19 0.434,-0.458 0.575,-0.515 0.221,-0.382 0.137,-0.105 0.495,-0.213 0.657,-0.164 0.31,0.008 0.306,0.335 0.165,-0.046 0.168,-0.087 0.338,-0.048 0.348,0.056 0.34,0.001 0.34,-0.042 0.652,-0.11 0.344,-0.133 0.336,-0.172 1.196,-0.121 0.819,-0.289 0.13,0.021 0.126,0.066 0.01,0.214 -0.104,0.233 0.101,0.141 0.166,0.087 0.771,0.027 0.22,0.05 0.322,-0.159 0.304,-0.197 0.317,-0.26 0.222,-0.293 -0.205,-0.367 -0.045,-0.402 0.172,-0.437 0.249,-0.368 0.296,-0.223 0.273,-0.257 0.552,-0.73 0.399,-0.592 0.144,-0.73 -0.084,-0.866 0.349,-0.646 0.334,-0.111 0.663,-0.295 0.348,-0.086 0.052,0.129 -0.01,0.169 -0.521,0.542 -0.299,0.223 -0.178,0.069 -0.164,0.098 -0.067,0.191 0.266,0.318 0.067,0.235 -0.017,0.225 0.012,0.203 0.3,0.22 0.345,0.073 0.144,-0.002 0.126,-0.058 0.394,-0.539 0.088,-0.094 1.12,-0.396 0.551,-0.303 0.305,-0.079 0.286,-0.158 0.642,-0.61 0.236,-0.282 0.215,-0.312 0.172,-0.363 0.136,-0.393 0.186,-0.245 1.017,-0.585 0.327,-0.319 0.104,-0.155 0.126,-0.449 0.087,-0.467 0.123,-0.367 0.167,-0.344 0.223,-0.351 0.251,-0.327 0.148,-0.335 0.216,-0.803 0.094,-0.446 0.074,-0.161 0.108,-0.135 0.094,-0.172 0.072,-0.192 0.033,-0.19 0.046,-0.582 -0.028,-0.454 -0.168,-0.385 -0.139,-0.109 -0.151,-0.006 -0.228,0.033 -0.193,-0.157 0.04,-0.139 0.197,-0.026 0.134,-0.072 0.097,-0.131 0.181,-0.421 0.108,-0.452 0.01,-0.2 -0.142,-0.365 -0.112,-0.439 -0.003,-0.237 0.123,-0.274 0.176,-0.223 0.157,-0.052 0.17,-0.016 0.155,-0.086 0.144,-0.125 0.081,-0.138 0.126,-0.376 0.049,-0.214 -0.08,-0.576 0.082,-0.158 0.116,-0.098 0.155,0.074 0.16,0.015 0.186,-0.023 0.178,0.061 0.033,0.148 0.112,0.972 0.064,0.131 0.13,0.102 0.146,-0.015 0.126,-0.151 0.085,-0.201 0.168,-0.042 0.513,0.216 0.182,-0.154 0.118,-0.239 0.103,-0.423 -0.05,-0.382 -0.123,-0.142 -0.127,0.025 -0.112,0.105 -0.126,0.057 -0.757,0.201 0.004,-0.426 0.162,-0.64 0.089,-0.203 0.128,-0.096 0.318,0.112 0.155,0.074 0.339,0.318 z m -8.098,12.885 -0.267,0.009 -0.066,-0.035 0.161,-0.088 0.015,-0.147 0.097,-0.262 -0.002,-0.075 -0.212,-0.014 0.011,-0.297 0.158,-0.294 0.435,-0.463 0.119,-0.087 0.018,0.203 -0.132,0.479 -0.026,0.173 0.342,0.036 -0.22,0.573 -0.431,0.289 z m -13.958,5.664 -0.128,0.129 -0.24,-0.042 -0.139,-0.187 0.046,-0.211 0.251,-0.162 0.24,0.325 -0.03,0.148 z m 17.08,5.069 -0.03,0.16 -0.149,-0.035 -0.071,-0.104 0.009,-0.187 0.157,-0.001 0.084,0.167 z m -28.264,1.264 -0.057,0.163 -0.19,-0.115 -0.087,-0.104 0.177,-0.513 -0.021,-0.195 0.011,-0.095 0.351,-0.269 0.061,0.051 0.021,0.075 -0.031,0.115 0.018,0.254 -0.264,0.42 0.011,0.213 z m 15.569,0.221 -0.304,0.288 -0.264,-0.02 -0.132,-0.129 -0.044,-0.159 0.251,-0.25 0.216,-0.354 0.196,-0.157 0.158,-0.088 0.124,0.003 -0.278,0.494 0.077,0.372 z m -1.631,-0.661 -0.052,0.067 -0.05,-0.018 -0.179,0.155 -0.038,-0.149 -0.141,-0.099 -0.017,-0.078 0.403,-0.051 0.13,0.041 -0.056,0.132 z m 0.015,0.769 0.389,0.141 0.397,-0.04 -0.006,0.617 0.057,0.207 0.111,0.185 -0.057,0.269 0.18,0.092 -0.534,0.306 -0.481,0.406 -0.198,0.273 -0.179,0.293 -0.104,0.31 -0.067,0.333 -0.161,-0.132 -0.464,-0.541 -0.294,-0.148 -0.473,-0.079 -0.15,0.018 -0.972,0.505 -0.129,0.369 -0.265,0.555 -0.126,0.183 -0.14,0.053 -0.099,0.095 -0.108,0.472 -0.301,0.29 -0.185,0.009 -0.314,-0.08 -0.142,0.045 0.188,-0.465 -0.3,-0.057 -0.301,0.01 -0.007,-0.303 -0.182,-0.172 0.135,-0.224 0.004,-0.183 0.079,-0.101 0.027,-0.147 -0.011,-0.126 -0.185,-0.038 -0.113,-0.089 0.021,-0.332 -0.106,-0.012 -0.264,0.058 -0.548,0.256 -0.149,0 0.229,-0.183 0.487,-0.25 0.219,-0.144 0.478,-0.404 0.301,-0.191 0.156,-0.339 0.049,-0.206 0.102,-0.182 0.09,-0.291 0.154,-0.097 0.269,-0.25 0.154,0.024 0.172,0.307 0.231,0.235 0.166,-0.02 0.297,-0.121 0.144,-0.027 0.343,0.015 0.309,-0.149 0.126,-0.176 0.047,-0.22 -0.115,-0.369 0.148,0.037 0.143,-0.015 0.335,-0.235 0.345,-0.14 0.357,-0.035 0.402,0.133 0.389,0.212 z m -14.25,0.449 -0.183,0.137 -0.078,-0.209 0.08,-0.594 0.343,0.122 -0.006,0.182 -0.156,0.362 z m 9.258,0.028 -0.081,0.135 -0.249,-0.041 0.1,-0.117 0.076,-0.142 0.056,-0.029 0.047,0.154 0.051,0.04 z m -0.877,0.573 0.137,0.124 0.325,-0.05 0.04,0.035 -0.095,0.112 -0.144,0.111 -0.26,-0.083 -0.164,-0.004 -0.023,-0.185 0.021,-0.067 0.163,0.007 z m -3.062,1.151 0.377,0.1 0.16,0.006 0.147,-0.045 0.226,-0.131 0.235,-0.097 0.169,0.049 0.149,0.117 0.078,0.165 -0.038,0.172 -0.267,0.37 -0.22,0.394 0.504,0.074 0.504,-0.008 -0.117,0.243 -0.02,0.212 0.154,0.101 0.131,0.136 -0.034,0.123 -0.075,0.121 0.275,0.182 -0.018,0.122 -0.071,0.128 -0.687,0.834 -0.202,0.421 -0.14,0.463 -0.129,0.338 -0.094,0.351 -0.071,0.378 -0.128,0.39 0.043,0.345 -0.043,0.354 -0.345,0.872 -0.246,-0.016 -0.309,-0.105 -0.193,0.016 -0.1,0.193 0.177,0.397 -0.55,0.471 -0.608,0.316 -0.004,-0.144 0.058,-0.113 0.087,-0.091 0.063,-0.11 0.089,-0.37 -0.044,-0.373 -0.184,-0.468 -0.013,-0.168 0.127,-0.068 0.085,-0.02 0.046,-0.065 0.002,-0.155 -0.058,-0.115 -0.174,-0.037 -0.166,-0.002 -0.117,0.174 -0.161,0.335 -0.078,0.339 0.034,0.185 0.071,0.166 0.221,0.277 -0.064,0.164 -0.092,0.127 -0.78,-0.289 -0.169,-0.021 -0.14,-0.061 -0.15,-0.381 0.318,-0.092 0.094,-0.046 0.035,-0.122 0.043,-0.372 -0.148,-0.312 -0.126,-0.111 -0.102,-0.127 0.064,-0.263 -0.042,-0.332 -0.004,-0.464 0.055,-0.08 0.295,-0.094 0.213,-0.249 0.188,-0.284 0.275,-0.5 0.226,-0.541 -0.217,-0.023 -0.184,-0.102 0.2,-0.256 -0.062,-0.324 -0.3,-0.398 -0.165,-0.47 -0.265,-0.208 -0.14,-0.076 -0.171,0.11 -0.14,0.132 0.13,0.306 -0.016,0.271 0.021,0.268 0.132,0.015 0.163,-0.067 0.13,0.047 0.076,0.141 0.021,0.181 -0.058,0.179 -0.119,0.089 -0.146,-0.007 -0.147,-0.097 -0.115,-0.138 -0.275,-0.076 -0.29,0.163 -0.275,0.332 -0.235,0.168 0.11,-0.246 0.053,-0.266 -0.114,-0.187 -0.27,-0.311 -0.063,-0.18 -0.016,-0.218 0.048,-0.216 0.276,0.248 0.142,0.309 0.204,0.136 0.255,0.001 -0.196,-0.454 -0.07,-0.115 -0.274,-0.204 -0.376,-0.343 -0.238,-0.166 0.084,-0.359 0.141,-0.071 0.118,0.017 0.398,0.127 0.037,-0.179 -0.059,-0.096 -0.03,-0.111 0.263,-0.155 0.429,-0.128 0.088,-0.06 0.076,-0.129 0.105,-0.067 0.3,0.002 0.253,-0.124 0.209,-0.335 0.05,-0.184 0.074,-0.154 0.521,-0.272 0.129,-0.042 0.349,0.034 0.318,0.154 0.157,0.324 0.138,0.346 0.331,0.235 z m -3.87,-0.491 -0.194,0.139 -0.146,-0.108 0.071,-0.3 0.048,-0.1 0.166,0.099 0.055,0.27 z m -0.854,1.762 -0.197,0.157 -0.143,0 0.13,-0.184 0.018,-0.087 0.109,-0.247 0.213,-0.088 0.09,-0.011 -0.174,0.256 -0.046,0.204 z m -1.164,1.274 -0.07,0.036 -0.09,-0.3 -0.063,-0.107 0.105,-0.057 0.211,-0.545 0.038,0.216 0.082,0.214 0.082,0.034 -0.08,0.156 -0.117,0.058 -0.098,0.295 z m 30.21,-0.718 -0.049,0.035 -0.135,-0.109 -0.02,-0.097 0.024,-0.06 0.088,-0.013 0.182,0.119 -0.09,0.125 z m -31.365,0.906 0.109,0.09 0.159,-0.051 0.127,-0.012 0.091,0.043 0.115,0.231 0.042,0.137 -0.205,0.019 -0.087,0.032 -0.112,0.167 -0.161,-0.062 -0.101,-0.079 -0.022,-0.111 0.045,-0.404 z m 3.977,1.835 -0.222,0.118 -0.028,-0.113 -0.094,-0.052 0.161,-0.159 -0.006,-0.072 -0.102,-0.107 0.118,-0.406 -0.032,-0.175 0.443,-0.065 0.081,0.165 0.008,0.5 -0.327,0.366 z m 0.838,-0.641 -0.248,0.015 -0.103,-0.039 -0.041,-0.105 0.348,-0.213 0.27,0.038 -0.12,0.192 -0.106,0.112 z m -1.86,2.526 -0.088,0.057 0.056,-0.258 0.226,-0.226 0.019,0.146 -0.213,0.281 z m 3.484,4.107 -0.246,0.034 -0.005,-0.188 0.195,-0.424 0.021,-0.312 0.182,-0.394 0.077,-0.086 0.058,-0.031 0.063,0.123 -0.07,0.482 -0.183,0.365 -0.092,0.431 z m -0.945,0.433 -0.321,0.07 -0.176,-0.075 -0.162,-0.399 0.307,-0.25 0.41,0.248 0.084,0.071 -0.142,0.335 z m -3.284,6.573 -0.242,0.257 -0.257,-0.232 -0.31,-0.155 0.147,-0.042 0.086,-0.063 0.009,-0.098 0.201,-0.146 0.398,-0.113 0.127,-0.007 0.143,-0.106 0.047,-0.096 0.059,-0.046 0.257,-0.132 0.07,0.152 -0.012,0.119 -0.193,0.066 -0.188,0.159 -0.175,0.198 -0.156,0.084 -0.05,0.056 0.039,0.145 z m -0.361,0.33 0.019,0.074 -0.275,-0.062 -0.112,-0.289 0.183,0.052 0.056,0.099 0.129,0.126 z m -0.915,1.213 -0.118,0.058 -0.157,-0.08 -0.049,-0.362 0.07,-0.176 0.123,-0.039 0.107,0.313 0.074,0.129 -0.05,0.157 z m -2.075,3.352 -0.271,0.144 -0.1,0.171 -0.25,0.058 -0.243,0.24 -0.236,0.043 0.006,0.193 0.101,0.163 -0.157,0.029 -0.165,0.199 -0.013,0.145 0.059,0.116 -0.008,0.059 -0.208,0.172 -0.215,0.008 -0.009,-0.186 0.014,-0.139 0.203,-0.338 0.005,-0.393 0.188,-0.045 0.068,-0.055 0.297,-0.28 0.055,-0.119 -0.154,-0.116 0.012,-0.137 0.035,-0.058 0.244,0.044 0.099,0.102 0.049,0.011 0.143,-0.076 0.067,-0.136 0.266,-0.268 0.108,-0.266 0.215,0.218 -0.058,0.286 -0.147,0.211 z m 39.093,0.114 -0.052,0.002 -0.176,-0.331 0.051,-0.016 0.103,0.052 0.113,0.191 -0.039,0.102 z m -46.992,5.802 -0.237,0.08 -0.254,-0.047 0.041,-0.429 0.088,0.06 0.055,0.146 0.189,0.086 0.118,0.104 z m -3.231,0.698 -0.165,0.484 -0.137,0.07 -0.14,-0.039 -0.144,-0.27 0.101,-0.104 0.14,0.055 0.113,-0.021 0.257,-0.394 0.062,0.064 -0.087,0.155 z m -1.134,0.722 -0.177,0.043 -0.213,-0.053 -0.194,-0.015 -0.002,-0.091 0.203,-0.094 0.004,-0.131 0.05,-0.071 0.459,0.161 -0.02,0.118 -0.11,0.133 z"
  
end retData

★Click Here to Open This Script 

Posted in list Text | Tagged 10.12savvy 10.13savvy 10.14savvy 10.15savvy | Leave a comment

URLエンコードずみ文字列チェック

Posted on 11月 29, 2019 by Takaaki Naganoya

与えられた文字列がURLエンコードずみ文字列かどうかをチェックするAppleScriptです。

なんでそんなものが必要になったかといえば、macOS 10.15のPDFView上で発生した(”applescript://” schemeの)URL EventがデコードされずにOSデフォルト指定のスクリプトエディタに転送される、URLデコード不良バグが発生。これに対処した簡易PDFビューワーも用意しましたが、macOS 10.15.2 Beta3でこのバグが修正されているように見えます。

# 一度発生したバグは、今後もAppleが再発しないよう継続して監視する必要があります

すると、今度は簡易PDFビューワー側でURLイベントをデコードしてからScript Editorに転送している処理が「余計」になってしまいます。再デコードした文字列は途中で途切れてしまうので、処理対象の文字列がURLエンコードされたものかどうかをチェックする必要が出てきました。

このままOSにURLデコード不良バグが残存するよりは、こうしたプログラムでチェックしてから処理するほうがよいでしょう。

AppleScript名:URLエンコードずみ文字列チェック.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/11/29
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

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

set aStr to "applescript://com.apple.scripteditor?action=new&script=display%20dialog%20%22TEST%22"
set aRes to chkEncodedURLorNot(aStr) of me
–> true –URL Encoded

set bStr to "display dialog \"TEST\""
set bRes to chkEncodedURLorNot(bStr) of me
–> false –Not URL encoded

on chkEncodedURLorNot(aStr)
  set nsStr to NSString’s stringWithString:aStr
  
set decodedStr to nsStr’s stringByRemovingPercentEncoding()
  
  
if (nsStr’s isEqualToString:decodedStr) then
    return false –encoded URL
  else
    return true –Not encoded URL
  end if
end chkEncodedURLorNot

★Click Here to Open This Script 

Posted in Text URL | Tagged 10.13savvy 10.14savvy 10.15savvy NSString NSURL | Leave a comment

テキストエディットで指定のフォントとサイズに該当するテキストを抽出する

Posted on 11月 22, 2019 by Takaaki Naganoya

macOS標準搭載のテキストエディタ、「テキストエディット」(TextEdit)をコントロールして、最前面のウィンドウの書類から、指定のフォント名とサイズに該当するテキストを抽出するAppleScriptです。

テキストエディットはApple純正のアプリケーションの割にはAppleScriptサポート機能がよくできていて、選択範囲(selection)を取得できないことをのぞけば、けっこう使えます。

テキストエディットのAppleScript系の機能で最も重要なものは、書類からの書式取得機能(attribute run)です。


▲最前面の書類がリッチテキストフォーマットになっている必要があります


▲Github上のGPUImageのフィルタ紹介文からコピペしてきた文章


▲この書類のこのレベルの見出しだけを抽出したい場合にはHelvetica Neue Bold 20pointを指定


▲この書類のこのレベルの見出しだけを抽出したい場合にはHelvetica Neue Bold 16pointを指定

Webブラウザなどからコピペしてきたスタイル付きテキストから、特定のフォントや文字サイズの箇所を抽出したい場合に使います。

実行すると、リッチテキストで使用されているフォント名とサイズの一覧を生成し、ダイアログでフォント名の選択、

そして、文字サイズの選択を実行。

すると、該当箇所のみ抽出して返します。さらに改行で区切ったテキストに変換するとかいった処理を行なってもよいでしょう。

RTFのファイルを処理するのであれば、テキストエディットを使わなくてもCocoaの機能を用いて同様の処理を行えますが、割と書き捨てレベルの瑣末なScriptなのでテキストエディット経由で書式情報を取得するように組んでみました。

AppleScript名:指定のフォントとサイズに該当するテキストを抽出する
— Created 2019-11-22 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

script spd
  property fontList : {}
  
property fontSizes : {}
  
property textList : {}
  
property outList : {}
end script

set (outList of spd) to {}
set (fontList of spd) to {}
set (fontSizes of spd) to {}
set (textList of spd) to {}

–TextEdit書類から書式情報を根こそぎ取得
tell application "TextEdit"
  tell text of front document
    set (fontList of spd) to font of every attribute run –フォント名
    
set (fontSizes of spd) to size of every attribute run –文字サイズ
    
set (textList of spd) to character of every attribute run –文字
  end tell
end tell

–取得したフォント名一覧から重複部分を除去してどれを対象にするかユーザーに問い合わせ
set fRes to uniquify1DList((fontList of spd), true) of me
set targFont to choose from list fRes
set aFont to contents of first item of targFont

–取得したフォントサイズ一覧から重複部分を除去してどれを対象にするかユーザーに問い合わせ
set sRes to uniquify1DList((fontSizes of spd), true) of me
set targSize to choose from list sRes
set aSize to contents of first item of targSize

–取得した条件にもとづいて、根こそぎ取得した書式と照合を行いつつループ
repeat with i from 1 to length of (fontList of spd)
  set tmpFont to contents of item i of (fontList of spd)
  
set tmpSize to contents of item i of (fontSizes of spd)
  
  
–文字サイズをざっくり判定することで「大、中、小」といったおおまかな切り分けも可能
  
if {tmpFont, tmpSize} = {aFont, aSize} then
    set tmpCon to (contents of item i of (textList of spd)) as string
    
if tmpCon does not contain "•" then –ごみ取り
      set the end of (outList of spd) to tmpCon
    end if
  end if
end repeat

return (outList of spd)

–1D/2D Listをユニーク化
on uniquify1DList(theList as list, aBool as boolean)
  set aArray to current application’s NSArray’s arrayWithArray:theList
  
set bArray to aArray’s valueForKeyPath:"@distinctUnionOfObjects.self"
  
if aBool = true then
    return bArray as list
  else
    return bArray
  end if
end uniquify1DList

★Click Here to Open This Script 

Posted in Font list RTF Text | Tagged 10.13savvy 10.14savvy 10.15savvy NSArray TextEdit | Leave a comment

SVGの要素を走査するじっけん v2

Posted on 11月 19, 2019 by Takaaki Naganoya

世界地図のSVGをHTMLReader.frameworkでparseして、目的のノードに塗り色の指定を行い、WkWebView上で表示するAppleScriptです。

–> Download countrySel(Code-Signed AppleScript applet executable. Its icon is customized version by Script Debbuger)


▲いかにもなメルカトル図法の世界地図。極地に行くほど巨大に表現される。国によっては国土が小さいために色を変えてもこの縮尺だとわからないことも

SVGをparseするのにXML Parser系のFrameworkを軒並み試してみたのですが、所定の要素を掘り進んでいくまでは楽にできるものの、検索先のnodeまで行って属性値を書き換えたあとでrootまで戻り、属性値を書き換えたXML全体を文字列化するような機能を備えたものは見つかりませんでした。

この手の処理で圧倒的に便利なのがHTMLReader.framework。書き換え要素を検索して、書き換えたあとにrootまで戻り、Document全体を文字列化して返すような処理が楽勝です。この手の処理が楽にできるプログラムは、自分が知っているかぎりではこれだけです。

本ScriptはmacOS 10.15.1上で作って試してみましたが、驚いたことに、アプリケーション書き出ししたときに、Apple純正のランタイムだとAppleScriptアプレット内にバンドルしたフレームワークにアクセスできなくなっていました。

セキュリティを強化したいのは理解できますが、いささかやりすぎではないでしょうか。この先、Script Debuggerを用いて書き出したランタイムまで実行できなくなったとしたらXcode上で作らないと実行できなくなってしまうことでしょう。いささかやりすぎのようにも思えます。

Script Debuggerから「Application(Apple)」で書き出すと、Frameworkにアクセスできないんだか、WkWebViewにアクセスできないんだか不明ですが、macOS 10.15上では地図が表示できません。


▲Script Debugger上でアプレット書き出しするさいに、Applicaion(Enhanced)で書き出さないとバンドル内のフレームワーク呼び出しができなかった。Script Debuggerがないと手も足も出ない


▲ISO国コードから選択。「JP」を選ぶと日本が、「AU」を選ぶとオーストラリアが赤く表示される


▲SVGの世界地図をテキストエディタでオープンしたところ

AppleScript名:SVGの要素を走査するじっけん v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/11/19
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "HTMLReader" –https://github.com/nolanw/HTMLReader
use webDialog : script "webViewLib"

property NSString : a reference to current application’s NSString
property HTMLDocument : a reference to current application’s HTMLDocument

property textArray : missing value
property anError : missing value

–Choose Target Country
set isoCountry to (current application’s NSLocale’s ISOCountryCodes()) as list
set cRes to choose from list isoCountry with prompt "Select Target Country"

set targetCountry to contents of first item of cRes

–Load SVG World map in this bundle
set mePath to ((path to me) as string) & "Contents:Resources:world-2.svg"
set aData to read (mePath as alias)
set aHTML to current application’s HTMLDocument’s documentWithString:(aData as string)

set eList to (aHTML’s nodesMatchingSelector:"path") as list
set fList to (aHTML’s nodesMatchingSelector:"path")’s valueForKeyPath:"attributes.id"

–Search Target Country
set aRes to (fList)’s indexOfObject:(targetCountry)
if (aRes = current application’s NSNotFound) or (aRes > 9.99999999E+8) then
  error "Target country not found"
end if
set aRes to aRes + 1 — (Cocoa array index begins from 0, AppleScript is 1)

–Rewrite target country’s fill color on SVG
set tmpNode to contents of item aRes of (eList)
(
tmpNode’s setObject:"Red" forKeyedSubscript:"fill") –Change Target Country’s fill color

set svgCon to (tmpNode’s |document|()’s serializedFragment()) as string –HTMLReaderはこういう処理ができるところが好き

–Alert Dialog上でSVGを表示
dispWebViewByString(svgCon, "This is " & targetCountry, "This is your indicated country by 2 character country code") of webDialog

★Click Here to Open This Script 

Posted in dialog Image SVG Text XML | Tagged 10.13savvy 10.14savvy 10.15savvy HTMLDocument NSString | 1 Comment

指定アプリケーション内の現在のLocaleの指定stringsファイル内の指定キーの値を取得する

Posted on 11月 16, 2019 by Takaaki Naganoya

Bundle IDで指定したアプリケーションのバンドル中(/Contents/Resources/)の現在のLocalizationに存在する指定のstringsファイル内で、指定キーの値を取得するAppleScriptです。

アプリケーションバンドル内の各ローカライズフォルダの名称は一意に決定されているものでもなく、ある程度の「ゆらぎ」が生じています。

/Contents/Resources/Japanese.lproj/
/Contents/Resources/ja.lproj/

NSLocaleからcurrentLocale()を取得すると、「ja-JP」のような識別子が得られます。これと上記のパターンのフォルダとの付け合わせのためのメソッドがどこかに存在しているはずなのですが、現状では見つけられていません(ないと各アプリケーションが正しくメニュー表示できていないので)。

まだいまひとつ、しっくりきていません。

AppleScript名:指定アプリケーション内の現在のLocaleの指定stringsファイル内の指定キーの値を取得する.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/11/15
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property |NSURL| : a reference to current application’s |NSURL|
property NSBundle : a reference to current application’s NSBundle
property NSDictionary : a reference to current application’s NSDictionary
property NSWorkspace : a reference to current application’s NSWorkspace
property NSFileManager : a reference to current application’s NSFileManager
property NSLocaleCountryCode : a reference to current application’s NSLocaleCountryCode
property NSLocaleLanguageCode : a reference to current application’s NSLocaleLanguageCode
property NSLocaleCollatorIdentifier : a reference to current application’s NSLocaleCollatorIdentifier

set targID to "com.apple.iWork.Keynote"
set targFile to "Keynote" –"Keynote.strings" file
set targKey to "Arrange"
set vStr to getAValInASpecifiedStringFileOfAllLocaleInABundle(targID, targFile, targKey) of me
–> "配置"

on getAValInASpecifiedStringFileOfAllLocaleInABundle(targID, targFile, targKey)
  set aPath to retPathFromBundleID(targID) of me
  
  
set aURL to (|NSURL|’s fileURLWithPath:aPath)
  
set aBundle to NSBundle’s bundleWithURL:aURL
  
  
set aLocale to (current application’s NSLocale’s preferredLanguages()’s firstObject()) as string
  
  
set curLocale to current application’s NSLocale’s currentLocale()
  
set aDS11 to (curLocale’s objectForKey:(NSLocaleLanguageCode)) as string
  
set aDS12 to (curLocale’s objectForKey:(NSLocaleCountryCode)) as string
  
set aDS5 to (curLocale’s objectForKey:(NSLocaleCollatorIdentifier)) as string
  
–set bID to (current application’s NSBundle’s mainBundle()’s preferredLocalizations()’s firstObject()) as string
  
  
set langIDList to {aDS11, aLocale, aDS12, aDS5} –> {"ja", "ja-JP", "JP", "ja-JP"}
  
  
repeat with i in langIDList
    set j to contents of i
    
set aRes to (aBundle’s pathForResource:targFile ofType:"strings" inDirectory:"" forLocalization:(j))
    
set aDict to (NSDictionary’s alloc()’s initWithContentsOfFile:aRes)
    
if aDict is not equal to missing value then
      set aVal to (aDict’s valueForKeyPath:(targKey))
      
if aVal is not equal to missing value then
        return aVal as string
      end if
    end if
  end repeat
  
  
return false
end getAValInASpecifiedStringFileOfAllLocaleInABundle

on getLocalizationsFromBundleID(aBundleID)
  set aRes to retPathFromBundleID(aBundleID) of me
  
if aRes = false then error "Wrong Bundle ID."
  
return getSpecifiedAppFilesLocalizationListWithDuplication(aRes) of me
end getLocalizationsFromBundleID

–指定アプリケーションファイルの、指定Localeにおけるローカライズ言語リストを求める。重複を許容
on getSpecifiedAppFilesLocalizationListWithDuplication(appPOSIXpath)
  set aURL to (|NSURL|’s fileURLWithPath:appPOSIXpath)
  
set aBundle to NSBundle’s bundleWithURL:aURL
  
set locList to aBundle’s localizations()
  
return locList as list
end getSpecifiedAppFilesLocalizationListWithDuplication

on retPathFromBundleID(aBundleID)
  set aURL to NSWorkspace’s sharedWorkspace()’s URLForApplicationWithBundleIdentifier:aBundleID
  
if aURL = missing value then return false –Error
  
return aURL’s |path|() as string
end retPathFromBundleID

★Click Here to Open This Script 

Posted in list System Text URL | Tagged 10.12savvy 10.13savvy 10.14savvy 10.15savvy NSBundle NSDictionary NSFileManager NSLocaleCollatorIdentifier NSLocaleCountryCode NSLocaleLanguageCode NSURL NSWorkspace | 2 Comments

指定アプリケーション内の全Localeの指定stringsファイル内の指定キーの値を取得する

Posted on 11月 13, 2019 by Takaaki Naganoya

Bundle IDで指定したアプリケーションのバンドル中(/Contents/Resources/)のすべてのLocalizationに存在する指定のstringsファイル内で、指定キーの値を取得するAppleScriptです。

macOSの日本語環境では、Finder上でコピーしたファイルのファイル名の後方に「のコピー」といった文字列が追記されますが、他のLocaleでどのような文字列が使用されているか調査するために作成したものです。

AppleScript名:指定アプリケーション内の全Localeの指定stringsファイル内の指定キーの値を取得する.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/11/12
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"

property |NSURL| : a reference to current application’s |NSURL|
property NSArray : a reference to current application’s NSArray
property NSBundle : a reference to current application’s NSBundle
property NSPredicate : a reference to current application’s NSPredicate
property NSDictionary : a reference to current application’s NSDictionary
property NSWorkspace : a reference to current application’s NSWorkspace
property NSFileManager : a reference to current application’s NSFileManager
property NSMutableDictionary : a reference to current application’s NSMutableDictionary
property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey

set targID to "com.apple.Finder"
set targFile to "Localizable.strings"
set targKey to "N4_V2"
set vList to getAValInASpecifiedStringFileOfAllLocaleInABundle(targID, targFile, targKey) of me
–> {{"he", "עותק של ^=1 ^=0"}, {"en_AU", "^=1 copy ^=0"}, {"ar", "نسخة ^=0 من ^=1"}, {"el", "^=1 αντίγραφο ^=0"}, {"uk", "^=1 копія ^=0"}, {"English", "^=1 copy ^=0"}, {"es_419", "Copia de ^=1 ^=0"}, {"zh_CN", "^=1的副本 ^=0"}, {"Dutch", "^=1 kopie ^=0"}, {"da", "^=1-kopi ^=0"}, {"sk", "^=1 – kópia ^=0"}, {"pt_PT", "^=1 – cópia ^=0"}, {"German", "^=1 Kopie ^=0"}, {"ms", "salinan ^=0 ^=1"}, {"sv", "^=1 (kopia ^=0)"}, {"cs", "^=1 (kopie ^=0)"}, {"ko", "^=1 복사본 ^=0"}, {"no", "^=1-kopi ^=0"}, {"hu", "^=1 másolat ^=0"}, {"zh_HK", "^=1 副本 ^=0"}, {"Spanish", "^=1 copia ^=0"}, {"tr", "^=1 kopyası ^=0"}, {"pl", "^=1-kopia ^=0"}, {"zh_TW", "^=1 拷貝 ^=0"}, {"en_GB", "^=1 copy ^=0"}, {"French", "^=1 copie ^=0"}, {"vi", "Bản sao ^=1 ^=0"}, {"ru", "^=1 — копия ^=0"}, {"fr_CA", "^=1 copie ^=0"}, {"fi", "^=1 kopio ^=0"}, {"id", "Salinan ^=1 ^=0"}, {"th", "^=1 สำเนา ^=0"}, {"pt", "^=1 – cópia ^=0"}, {"ro", "^=1 – copie ^=0"}, {"Japanese", "^=1のコピー^=0"}, {"hr", "^=1 kopija ^=0"}, {"hi", "^=1 कॉपी ^=0"}, {"Italian", "^=1 copia ^=0"}, {"ca", "^=1 còpia ^=0"}}

on getAValInASpecifiedStringFileOfAllLocaleInABundle(targID, targFile, targKey)
  –Get App Path
  
set aPath to retPathFromBundleID(targID) of me
  
  
–Get all Localizations
  
set bRes to getLocalizationsFromBundleID(targID) of me
  
  
set hitList to {}
  
  
–Loop with Localizations in an application bundle
  
repeat with iii in bRes
    set jjj to contents of iii
    
set allPath to aPath & "/Contents/Resources/" & jjj & ".lproj/" & targFile
    
set aDict to (NSDictionary’s alloc()’s initWithContentsOfFile:allPath)
    
if aDict is not equal to missing value then
      set aVal to (aDict’s valueForKeyPath:(targKey))
      
if aVal is not equal to missing value then
        set the end of hitList to {jjj, aVal as string}
      end if
    end if
  end repeat
  
  
return hitList
end getAValInASpecifiedStringFileOfAllLocaleInABundle

on getLocalizationsFromBundleID(aBundleID)
  set aRes to retPathFromBundleID(aBundleID) of me
  
if aRes = false then error "Wrong Bundle ID."
  
return getSpecifiedAppFilesLocalizationListWithDuplication(aRes) of me
end getLocalizationsFromBundleID

–指定アプリケーションファイルの、指定Localeにおけるローカライズ言語リストを求める。重複を許容
on getSpecifiedAppFilesLocalizationListWithDuplication(appPOSIXpath)
  set aURL to (|NSURL|’s fileURLWithPath:appPOSIXpath)
  
set aBundle to NSBundle’s bundleWithURL:aURL
  
set locList to aBundle’s localizations()
  
return locList as list
end getSpecifiedAppFilesLocalizationListWithDuplication

on retPathFromBundleID(aBundleID)
  set aURL to NSWorkspace’s sharedWorkspace()’s URLForApplicationWithBundleIdentifier:aBundleID
  
if aURL = missing value then return false –Error
  
return aURL’s |path|() as string
end retPathFromBundleID

★Click Here to Open This Script 

Posted in System Text | Tagged 10.12savvy 10.13savvy 10.14savvy 10.15savvy Finder NSArray NSBundle NSDictionary NSFileManager NSMutableDictionary NSPredicate NSURL NSURLTypeIdentifierKey NSWorkspace | Leave a comment

数値に3桁セパレータを付加、外して数値に戻す v2

Posted on 11月 12, 2019 by Takaaki Naganoya

10進数の数字文字列に3桁セパレータを付加、外して数字文字列に戻すAppleScriptです。

めんどくさい上にCocoaに機能があり、かつそれほど大量のデータ処理を行うわけでもない(スピードを要求されない)処理のはずなので、手抜きでCocoaの機能を呼び出しています。

AppleScript名:数値に3桁セパレータを付加、外して数値に戻す v2
— Created 2016-10-12 by Takaaki Naganoya
— 2016 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
–3桁セパレータ文字「,」をNSLocaleのcurrentLocaleから取得するように変更

property NSString : a reference to current application’s NSString
property NSLocale : a reference to current application’s NSLocale
property NSCharacterSet : a reference to current application’s NSCharacterSet
property NSNumberFormatter : a reference to current application’s NSNumberFormatter
property NSLocaleGroupingSeparator : a reference to current application’s NSLocaleGroupingSeparator
property NSNumberFormatterDecimalStyle : a reference to current application’s NSNumberFormatterDecimalStyle

set aNum to 100000000
set aStr to formatNum(aNum) of me
–> "100,000,000"

set bNum to deFromatNumStr(aStr) of me
–>  "100000000"

on formatNum(theNumber as number)
  set theResult to NSNumberFormatter’s localizedStringFromNumber:theNumber numberStyle:(NSNumberFormatterDecimalStyle)
  
return theResult as text
end formatNum

on deFromatNumStrAndRetNumber(theNumericString as string)
  set aThousandSep to NSLocale’s currentLocale()’s objectForKey:(NSLocaleGroupingSeparator)
  
set notWantChars to NSCharacterSet’s characterSetWithCharactersInString:aThousandSep
  
set targStr to NSString’s stringWithString:theNumericString
  
set newStr to (targStr’s componentsSeparatedByCharactersInSet:notWantChars)’s componentsJoinedByString:""
  
return ((newStr as string) as number) –Danger in OS X 10.10 (floating point casting bug)
end deFromatNumStrAndRetNumber

on deFromatNumStr(theNumericString as string)
  set aThousandSep to NSLocale’s currentLocale()’s objectForKey:(NSLocaleGroupingSeparator)
  
set notWantChars to NSCharacterSet’s characterSetWithCharactersInString:aThousandSep
  
set targStr to NSString’s stringWithString:theNumericString
  
set newStr to (targStr’s componentsSeparatedByCharactersInSet:notWantChars)’s componentsJoinedByString:""
  
return (newStr as string)
end deFromatNumStr

★Click Here to Open This Script 

Posted in Number Text | Tagged 10.12savvy 10.13savvy 10.14savvy 10.15savvy NSCharacterSet NSLocale NSLocaleGroupingSeparator NSNumberFormatter NSNumberFormatterDecimalStyle NSString | Leave a comment

10進数とn進数文字列の相互変換

Posted on 11月 12, 2019 by Takaaki Naganoya

10進数の数値とn進数の文字列を相互変換するAppleScriptです。

もともと、AppleScriptの言語仕様上、10進数とn進数文字列との相互変換機能は存在しないのですが、サードパーティから機能拡張書類(OSAX)でそのような機能が提供され、さらにClassic MacOSからMac OS Xへの移行時にそれらの機能拡張書類が使えなくなって(一部は移行)、個別にそれらの機能をスクリプター側で実装してMailing ListやBBS上、Blogなどで共有してきたという経緯があります。

AppleScript Users MLに流れていたもののような気がしますが、自分で作ったものかもしれません。出どころ不明です。

ただ、2進数変換や16進数変換などの各種変換ルーチンが乱立していたところに、「これ、全部1つで済むんじゃね?」と思ってまとめたような気がしないでもありません。自分で作っても簡単なので。

Cocoaの機能を一切使っていません。たしかにCocoaの機能を用いての変換も行えるのですが、データのサイズがとても小さい(桁数が少ない)ので、Cocoaの機能を呼び出さないほうが高速です。

もしも、AppleScriptの予約語のようにこれらの機能を呼び出したい場合には、これらのScriptをAppleScript Librariesにして、AppleScript用語辞書をつけて書き出せば(辞書はなくても大丈夫ですが)、

use nthLib: script "nThConvLib"

のように呼び出すことができるようになっています(macOS 10.9以降)。

AppleScript名:10進数をn進数文字列に変換する
set a to 100

–10進→16進数変換
set b to aNumToNthDecimal(a, 16, 4, {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}, true) of me
–> "64"

–10進→8進数変換
set c to aNumToNthDecimal(a, 8, 4, {"0", "1", "2", "3", "4", "5", "6", "7"}, true) of me
–> "144"

–10進→2進数変換
set d to aNumToNthDecimal(a, 2, 8, {"0", "1"}, false) of me
–> "01100100"

–10進数をn進数文字列に変換する

–origNum:変換対象の数字
–nTh: n進数のn
–stringLength: 出力指定桁(上位桁のアキはゼロパディングされる)
–zeroSuppress: 上位桁がゼロになった場合に評価を打ち切るかのフラグ、ゼロパディングを行わない(ゼロサプレスする)場合に指定
on aNumToNthDecimal(origNum, nTh, stringLength, stringSetList, zeroSuppress)
  set resString to {}
  
repeat with i from stringLength to 1 by -1
    if {origNum, zeroSuppress} = {0, true} then exit repeat
    
set resNum to (origNum mod nTh)
    
set resText to contents of item (resNum + 1) of stringSetList
    
set resString to resText & resString
    
set origNum to origNum div nTh
  end repeat
  
return (resString as string)
end aNumToNthDecimal

★Click Here to Open This Script 

AppleScript名:n進数文字列を10進数に変換する v2a
–2進数文字列→10進数数値変換
set a to "11"
set b to aNthToDecimal(a, {"0", "1"}) of me
–> 3

–8進数文字列→10進数数値変換
set a to "144"
set c to aNthToDecimal(a, {"0", "1", "2", "3", "4", "5", "6", "7"}) of me
–> 100

–16進数文字列→10進数数値変換
set a to "64"
set b to aNthToDecimal(a, {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}) of me
–> 100

–n進数文字列を10進数に変換する
on aNthToDecimal(origStr as string, nTh as list)
  set resNumber to 0
  
set sList to reverse of (characters of origStr)
  
set aLen to length of nTh
  
set digitCount to 0
  
  
repeat with i in sList
    set j to contents of i
    
set aRes to (offsetInList(j, nTh) of me)
    
    
set resNumber to resNumber + (aLen ^ digitCount) * (aRes – 1)
    
set digitCount to digitCount + 1
  end repeat
  
  
return resNumber as integer
end aNthToDecimal

–元はCocoaの機能を利用していたが、処理対象のデータが小さいのでOld Style AppleScriptで書き直した
on offsetInList(aChar as string, aList as list)
  set aCount to 1
  
repeat with i in aList
    set j to contents of i
    
if aChar is equal to j then
      return aCount
    end if
    
set aCount to aCount + 1
  end repeat
  
return 0
end offsetInList

★Click Here to Open This Script 

Posted in Number Text | Tagged 10.12savvy 10.13savvy 10.14savvy 10.15savvy | Leave a comment

指定フォルダ以下のすべてのファイルとフォルダ名から絵文字を除去する v2

Posted on 11月 5, 2019 by Takaaki Naganoya

指定フォルダ以下のすべてのファイル名とフォルダ名から絵文字を除去するAppleScriptです。Shane StanleyのremoveEmojiルーチンを使っています。

macOS 10.14.1で絵文字が大幅に追加されたため、これらの絵文字をファイル名に用いていた場合には10.14.1以下のバージョンのOS環境にそのままファイルを持っていくことができません。

 Zipアーカイブ → 展開時にエラー
 DiskImageにコピーするファイルを格納し、古いOSに持って行ってドライブとしてマウントしてファイルコピー → コピーできない(エラー)

という状態になります。絵文字自体に害はないのですが、規格がコロコロ変わる(追加される)ことで、ファイル名に用いるのには問題があるということでしょう。


▲もともとのファイル名、フォルダ名。絵文字を大量に使用している(普段はファイル名に絵文字は使っていません)


▲本Scriptで一括で処理したファイル名、フォルダ名。害のない1️⃣2️⃣3️⃣などの文字だけは残る

実際に作ってみたら、aliasに対するリネームはしょっちゅう行ってきたものの、POSIX pathを用いて指定フォルダ以下すべてをリネームするようなScriptは組んでいなかったので、ちょっと考えさせられました。


▲本Scriptでリネームして、CotEditorのScript PackをmacOS 10.13.6の環境に持っていけました。ただ、絵文字がないと寂しい感じがします

指定フォルダ以下のファイル/フォルダを一括取得するのに、今回はあえてSpotlightを使っていません。ファイルサーバー上のファイル/フォルダを処理する可能性がありそうなのと、外部ライブラリを使わないほうがよいと考え、このような構成になっています。

AppleScript名:指定フォルダ以下のすべてのファイルとフォルダ名から絵文字を除去する v2.scptd
—
—  Created by: Takaaki Naganoya
—  Created on: 2019/11/04
—
—  Copyright © 2019 Piyomaru Software, All Rights Reserved
—

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

property |NSURL| : a reference to current application’s |NSURL|
property NSString : a reference to current application’s NSString
property NSPredicate : a reference to current application’s NSPredicate
property NSFileManager : a reference to current application’s NSFileManager
property NSMutableArray : a reference to current application’s NSMutableArray
property NSRegularExpressionSearch : a reference to current application’s NSRegularExpressionSearch
property NSURLBookmarkResolutionWithoutUI : a reference to current application’s NSURLBookmarkResolutionWithoutUI

set aFol to POSIX path of (choose folder)

set anArray to NSMutableArray’s array()
set erArray to NSMutableArray’s array()
set aPath to NSString’s stringWithString:aFol
set dirEnum to NSFileManager’s defaultManager()’s enumeratorAtPath:aPath

repeat
  set aName to (dirEnum’s nextObject())
  
if aName = missing value then exit repeat
  
set aFullPath to aPath’s stringByAppendingPathComponent:aName
  
  
anArray’s addObject:aFullPath
end repeat

—逆順に(フォルダの深い場所&ファイル名から先に処理)
set revArray to (anArray’s reverseObjectEnumerator()’s allObjects()) as list

—リネーム
repeat with i in revArray
  set j to (NSString’s stringWithString:(contents of i))
  
set curName to j’s lastPathComponent() as string
  
set newName to removeEmoji(curName) of me
  
  
if curName is not equal to newName then
    set fRes to renameFileItem(j as string, newName) of me
    
if fRes = false then
      (erArray’s addObject:{j, newName})
    end if
  end if
end repeat

return erArray as list —リネームできなかったパス(フルパス、リネームするはずだった名称)

—絵文字除去
on removeEmoji(aStr)
  set aNSString to NSString’s stringWithString:aStr
  
return (aNSString’s stringByReplacingOccurrencesOfString:"[\\U0001F600-\\U0001F64F\\U0001F300-\\U0001F5FF\\U0001F680-\\U0001F6FF\\U00002600-\\U000026FF\\U00002700-\\U000027BF\\U0000FE00-\\U0000fE0F\\U0001F900-\\U0001F9FF\\U0001F1E6-\\U0001F1FF\\U00002B50-\\U00002B50\\U0000231A-\\U0000231B\\U00002328-\\U000023FA\\U000024C2-\\U000024C2\\U0001F194-\\U0001F194\\U0001F170-\\U0001F251\\U000025AB-\\U000025FE\\U00003297-\\U00003299\\U00002B55-\\U00002B55\\U00002139-\\U00002139\\U00002B1B-\\U00002B1C\\U000025AA-\\U000025AA\\U0001F004-\\U0001F004\\U0001F0CF-\\U0001F0CF]" withString:"" options:(NSRegularExpressionSearch) range:{0, aNSString’s |length|()}) as text
end removeEmoji

—ファイル/フォルダのリネーム
on renameFileItem(aPOSIXPath, newName)
  set theNSFileManager to NSFileManager’s defaultManager()
  
set POSIXPathNSString to NSString’s stringWithString:(aPOSIXPath)
  
  
–Make New File Path
  
set anExtension to POSIXPathNSString’s pathExtension()
  
set newPath to (POSIXPathNSString’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:newName) –’s stringByAppendingPathExtension:anExtension
  
  
–Rename
  
if theNSFileManager’s fileExistsAtPath:newPath then
    return true
  else
    set theResult to theNSFileManager’s moveItemAtPath:POSIXPathNSString toPath:newPath |error|:(missing value)
    
if (theResult as integer = 1) then
      return (newPath as string)
    else
      return false
    end if
  end if
end renameFileItem

★Click Here to Open This Script 

Posted in file File path regexp Text | Tagged 10.14savvy 10.15savvy NSFileManager NSMutableArray NSPredicate NSRegularExpressionSearch NSString NSURL | Leave a comment

文字列から絵文字を削除

Posted on 11月 4, 2019 by Takaaki Naganoya

Shane Stanleyから投稿してもらった(いただいた)実用レベルの絵文字削除ルーチンです。

いろんな方面からツッコミが入って、徐々に実用レベルに到達するのではないかと予想していた絵文字削除ルーチン、いきなり最終兵器的なルーチンの登場により、「これでいいでしょ?」と思えるレベルに到達しました。

AppleScript名:remove emoji v0
—
—  Created by: Shane Stanley
—  Created on: 2019/11/04
—
use AppleScript version "2.7" — High Sierra (10.13) or later
use framework "Foundation"
use scripting additions

removeEmoji("2203)🔄❎⚙️🇯🇵簡易日本語形態素解析📚してそれっぽく❌伏せ字に(□に置き換え).scptd") of me
–> "2203)簡易日本語形態素解析してそれっぽく伏せ字に(□に置き換え).scptd"

on removeEmoji(aStr)
  set aNSString to current application’s NSString’s stringWithString:aStr
  
— Emoticons, Misc Symbols and Pictographs, Transport and Map, Misc symbols, Dingbats, Variation Selectors, Supplemental Symbols and Pictographs, Flags
  
return (aNSString’s stringByReplacingOccurrencesOfString:"[\\U0001F600-\\U0001F64F\\U0001F300-\\U0001F5FF\\U0001F680-\\U0001F6FF\\U00002600-\\U000026FF\\U00002700-\\U000027BF\\U0000FE00-\\U0000fE0F\\U0001F900-\\U0001F9FF\\U0001F1E6-\\U0001F1FF]" withString:"" options:(current application’s NSRegularExpressionSearch) range:{0, aNSString’s |length|()}) as text
end removeEmoji

★Click Here to Open This Script 

ただ、そこは一応「すべての絵文字」を入力して試しておく必要を感じるところ。手作業でぽちぽちキーボードから(絵文字バレットから)絵文字を入力しまくって本ルーチンで処理してみたところ、どうも文字コード上の「飛び地」にあるとおぼしき絵文字が消えません。

なので、削除テーブル部分に「消えなかった絵文字のコード」をこれでもかと追加しまくり、削除対象文字テーブルを強化してみました。一部、対象文字よりもひろめに削除範囲が指定されている箇所もありますが、本ルーチンは主にファイル名に対して使用された絵文字を除去してファイルの後方互換性を確保すること(最新のOSよりも古いバージョンのOSとファイルを安全に交換すること)が目的なので、そんなマイナー記号類が削除されても気にしないことにします。

すべての絵文字が削除されたわけではないといいますか、絵文字っぽい文字でなくなっただけで残っていたりもするのですが、今度はこれらの文字を消すと実害もありそうなので、現状ではこのぐらいでよいかと思われます。

もちろん、すぐにCotEditorのメニューに突っ込んで、選択範囲の絵文字を削除できるようにしておきました。

AppleScript名:remove emoji.scptd
—
—  Created by: Shane Stanley
—  Created on: 2019/11/04
—  Modified by: Takaaki Naganoya (Emoji Table Data)

use AppleScript version "2.7" — High Sierra (10.13) or later
use framework "Foundation"
use scripting additions

set allEmoji to "☺️☹️☠️✌️☝️🖐✍️1️⃣2️⃣3️⃣⚙️😀😃😄😁😆😅😂🤣☺️😊😇🙂🙃😉😌😍🥰😘😗😙😚😋😛😝😜🤪🤨🧐🤓😎🤩🥳😏😒😞😔😟😕🙁☹️😣😖😫😩🥺😢😭😤😡🤬🤯😳🥵🥶😱😨😨😰😥😓🤗🤔🤭🤫🤥😶😐😑😬🙄😯😦😧😮😲😴🤤😪😵🤐🥴🤢🤮🤧😷🤒🤕🤑🤠😈👿👹👺🤡💩👻💀☠️👽👾🤖🎃😺😸😹😻😼😽🙀😿😾🤲👐🙌👏🤝👍👎👊✊🤛🤜🤞✌️🤟🤘👌👈👉👆👇☝️✋🤚🖐🖖👋🤙💪🖕✍️🙏🦶🦵🐶🐱🐭🐰🦊🐻🐼🐨🐯🦁🐮🐷🐽🐸🐵🙈🙉🙊🐒🐔🐧🐦🐤🐣🐥🦆🦅🦉🦇🐗🐴🦄🐝🐛🦋🐌🐞🐜🦟🦗🕷🕸🦂🐍🦎🦖🐙🦑🦐🦞🦀🐡🐟🐬🐳🦈🐊🐅🐆🦓🦍🐘🦛🦏🐪🐫🦘🐃🐂🐄🐎🐏🐑🦙🐐🦌🐕🐩🐈🐓🦃🦚🦜🦢🕊🐇🦝🦡🐁🐀🐿🐲🌵🎄🌲🌳🌴🌱🌿🍀🍃🍂🍁🍄🌾🌹🥀🌺🌼🌻🌚🌕🌖🌗🌘🌒🌎💫⭐️🌟⚡️☄️💥🔥🌪🌈🌤⛅️🌥☁️🌦🌧⛈🌩❄️☃️🌬💨💧💦☔️🌫🍏🍎🍐🍊🍋🍌🍇🍓🍈🍒🍑🍍🥥🥝🍅🍆🥑🌶🌽🥕🥔🍠🥐🥯🍞🥖🥨🧀🥚🍳🥞🥓🥩🍗🍖🦴🦴🌭🍕🥪🥙🌮🌯🥗🥘🥫🍝🍜🍛🍣🍱🍤🍙🍚🍘🍥🥠🥮🍢🍦🍰🎂🍭🍬🍫🍿🍩🍪🌰🥜🍯🥛🍼☕️🍵🥤🍶🍺🍻🥂🍷🥃🍸🍹🍾🥄🍴🍽🥣🥡🥢🧂🏀⚾️🥎🎾🏐🏉🥏🎱🏓🏸🏒🏏⛳️🏹🎣🥊🥋🎽🛹🛷⛸🥌🎿⛷🏂🏋️‍♂️🤼‍♀️🤼‍♂️🤺🤾‍♀️🤾‍♂️🏌️‍♀️🏌️‍♂️🏇🧘‍♀️🧘‍♂️🏄‍♀️🏄‍♂️🏊‍♀️🏊‍♂️🤽‍♀️🤽‍♂️🚣‍♀️🚣‍♂️🧗‍♀️🧗‍♂️🚵‍♀️🚵‍♂️🚴‍♀️🚴‍♂️🏆🥇🥈🥉🏅🎖🏵🎗🎫🎟🎪🤹‍♀️🤹‍♂️🎭🎨🎬🎤🎧🎼🎹🥁🎷🎺🎸🎻🎲♟🎯🎳🎮🎰🧩🚗🚙🚌🚎🏎🚓🚑🚒🚐🚛🚜🛴🚲🏍🚨🚔🚍🚘🚖🚡🚠🚟🚃🚋🚞🚝🚄🚅🚈🚂🚆🚇🚊✈️🛫🛬🛩💺🛰🚀🛸🚁🛶⛵️🚤🛳⛴🚢⚓️⛽️🚧🚦🚥🚏🗺🗿🗽🗼🏰🏯🏟🎡🎢🎠⛲️⛱🏖🏝🏜🌋⛰🏔🗻🏕🏠🏡🏘🏚🏗🏭🏢🏬🏣🏤🏥🏦🏨🏪🏫🏩💒🏛⛪️🕌🕍🕋⛩🛤🗾🎑🏞🌅🌄🌠🎇🎆🌇🌆🏙🌃🌌🌉🌁⌚️📱📲💻⌨️🖥🖨🖱🖲🕹🗜💽💾💿📀📼📷📸📹🎥📽🎞📞☎️📟📠📺📻🎙🎚🎛🧭⏱⏲⏰🕰⌛️⏳📡🔋🔌💡🔦🕯🧯🛢💸💵💴💰💳💎⚖️🧰🔧🔨⚒🛠⛏🔩🧱⛓🧲💣🧨🔪🗡⚔️🛡🚬⚰️⚱️🏺🔮📿🧿💈🔭🔬🕳💊💉🧬🦠🧫🧪🌡🧹🧺🧻🚽🚰🚿🛁🛀🧼🧽🧴🛎🔑🗝🚪🛋🛌🧸🖼🛒🎁🎈🎏🎀🎊🎉🎎🏮🎐✉️📩📨📧💌📥📤📦🏷📪📫📬📭📮📯📜📃📄📑🧾📊📈📉🗒🗓📆📅🗑📇🗳🗄📋📁📂🗂🗞📰📓📔📒📕📗📘📙📚📖🔖🧷🔗📎🖇📐📏🧮📌📍✂️🖊🖋✒️🖌🖍📝✏️🔍🔎🔏🔐🔒🔓🔓❤️🧡💛💚💙💜🖤💔❣️💕💞💗💖💘💝💟☮️✝️☪️🕉☸️✡️🔯🕎☯️☦️🛐⛎♈️♉️♊️♋️♌️♍️♎️♏️♐️♑️♒️♓️🆔⚛️🉑☣️📴📳🈶🈚️🈸🈺🈷️✴️🆚💮🉐㊙️㊗️🈴🈵🈲🅰️🅱️🆎🆑🅾️🆘❌⭕️🛑⛔️📛🚫💯💢♨️🚷🚯🚱🔞📵🚭❗️❕❓❓❔‼️⁉️🔅🔆〽️⚠️🚸🔱⚜️🔰✅🈯️💹❇️✳️❎🌐💠Ⓜ️🌀💤🏧♿️🅿️🈳🈂️🛂🛃🛄🛅🚹🚺🚼🚻🚮🎦📶🈁🔣ℹ️🔤🔡🔠🆖🆗🆙🆙🆒🆕🆓0️⃣1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣8️⃣9️⃣🔟🔢#️⃣*️⃣▶️⏸⏯⏹⏺⏭⏮⏩⏪⏫⏬🔼🔽⬅️⬇️↘️↖️↕️↙️↗️⬆️➡️◀️⏏️↪️↩️↔️⤵️🔀🔁🔄🔃⤵️⤴️🎵🎶➕➖➗♾💲💱©️👁‍🗨🔚🔙🔛🔝🔜➰➿➿☑️🔘🔴🔵🔺🔻🔸🔹🔶🔷🔳🔲▫️◽️◻️⬜️🔈🔇🔉🔊🔔🔔🔔🔕📣📢💬💭🗯♣️♦️🃏🎴🕐🕑🕒🕓🕔🕕🕖🕗🕘🕙🕚🕛🕜🕝🕞🕟🕠🕡🕢🕣🕤🕥🕥🕦🕧🀄️♥️♠️⬛️◼️◾️▪️⚪️✔️〰️®️™️✖️⭐️🏴🏁🏴‍☠️🏳️🚩🏳️‍🌈🇺🇳🇮🇸🇮🇪🇦🇿🇦🇫🇺🇸🇦🇪🇩🇿🇦🇷🇦🇼🇦🇱🇦🇲🇦🇮🇦🇴🇦🇬🇦🇩🇾🇪🇬🇧🏴󠁧󠁢󠁳󠁣󠁴󠁿🏴󠁧󠁢󠁷󠁬󠁳󠁿🇮🇱🇮🇹🇮🇶🇮🇷🇮🇳🇮🇩🇼🇫🇺🇬🇺🇦🇺🇿🇺🇾🇪🇨🇪🇬🇪🇪🇪🇹🇪🇷🇸🇻🇦🇺🇦🇹🇦🇽🇴🇲🇳🇱🇧🇶🇬🇭🇨🇻🇬🇬🇬🇾🇰🇿🇶🇦🇨🇦🇮🇨🇬🇦🇨🇲🇬🇲🇰🇭🇬🇳🇬🇼🇨🇾🇨🇺🇨🇺🇨🇼🇬🇷🇰🇮🇰🇬🇬🇹🇬🇵🇬🇺🇰🇼🇨🇰🇬🇱🇨🇽🇬🇩🇭🇷🇰🇾🇰🇪🇨🇮🇨🇨🇨🇨🇨🇷🇽🇰🇰🇲🇨🇴🇨🇬🇨🇩🇸🇦🇬🇸🇼🇸🇧🇱🇸🇹🇿🇲🇵🇲🇸🇲🇸🇱🇩🇯🇬🇮🇯🇪🇯🇲🇬🇪🇸🇾🇸🇬🇸🇽🇿🇼🇨🇭🇸🇪🇸🇩🇪🇸🇸🇷🇱🇰🇸🇰🇸🇮🇸🇿🇸🇨🇸🇳🇷🇸🇰🇳🇻🇨🇸🇭🇸🇴🇸🇧🇹🇨🇹🇭🇹🇯🇹🇿🇨🇿🇹🇩🇹🇳🇨🇱🇹🇻🇩🇰🇩🇪🇹🇬🇹🇰🇩🇴🇩🇲🇹🇹🇹🇲🇹🇷🇹🇴🇳🇬🇳🇷🇳🇦🇳🇺🇳🇮🇳🇮🇳🇪🇳🇨🇳🇿🇳🇵🇳🇫🇳🇫🇳🇴🇧🇭🇭🇹🇵🇰🇻🇦🇵🇦🇻🇺🇧🇸🇵🇬🇧🇲🇵🇼🇵🇾🇧🇧🇭🇺🇧🇩🇵🇳🇫🇯🇵🇭🇫🇮🇧🇹🇵🇷🇫🇴🇫🇰🇧🇷🇫🇷🇧🇬🇧🇫🇧🇳🇧🇮🇻🇳🇧🇯🇻🇪🇧🇾🇧🇿🇵🇪🇧🇪🇵🇱🇧🇦🇧🇼🇧🇴🇵🇹🇭🇳🇲🇭🇲🇴🇲🇰🇲🇬🇾🇹🇲🇼🇲🇱🇲🇹🇲🇶🇲🇾🇮🇲🇫🇲🇲🇲🇲🇽🇲🇺🇲🇷🇲🇿🇲🇨🇲🇻🇲🇩🇲🇦🇲🇳🇲🇪🇲🇸🇯🇴🇱🇦🇱🇻🇱🇹🇱🇾🇱🇮🇱🇷🇷🇴🇱🇺🇷🇼🇱🇸🇱🇧🇷🇪🇷🇺🇮🇴🇻🇬🇰🇷🇪🇺🇰🇷🇭🇰🇪🇭🇬🇶🇨🇫🇨🇳🇹🇱🇿🇦🇸🇸🇦🇶🇯🇵🎌🇬🇫🇵🇫🇹🇫🇻🇮🇦🇸🇲🇵🇰🇵"
removeEmoji(allEmoji) of me
–> "1⃣2⃣3⃣‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‼⁉〽0⃣1⃣2⃣3⃣4⃣5⃣6⃣7⃣8⃣9⃣#⃣*⃣⬅⬇↘↖↕↙↗⬆↪↩↔⤵⤵⤴©‍〰®™‍‍󠁧󠁢󠁳󠁣󠁴󠁿󠁧󠁢󠁷󠁬󠁳󠁿"

on removeEmoji(aStr)
  set aNSString to current application’s NSString’s stringWithString:aStr
  
  
— Emoticons, Misc Symbols and Pictographs, Transport and Map, Misc symbols, Dingbats, Variation Selectors, Supplemental Symbols and Pictographs, Flags
  
return (aNSString’s stringByReplacingOccurrencesOfString:"[\\U0001F600-\\U0001F64F\\U0001F300-\\U0001F5FF\\U0001F680-\\U0001F6FF\\U00002600-\\U000026FF\\U00002700-\\U000027BF\\U0000FE00-\\U0000fE0F\\U0001F900-\\U0001F9FF\\U0001F1E6-\\U0001F1FF\\U00002B50-\\U00002B50\\U0000231A-\\U0000231B\\U00002328-\\U000023FA\\U000024C2-\\U000024C2\\U0001F194-\\U0001F194\\U0001F170-\\U0001F251\\U000025AB-\\U000025FE\\U00003297-\\U00003299\\U00002B55-\\U00002B55\\U00002139-\\U00002139\\U00002B1B-\\U00002B1C\\U000025AA-\\U000025AA\\U0001F004-\\U0001F004\\U0001F0CF-\\U0001F0CF]" withString:"" options:(current application’s NSRegularExpressionSearch) range:{0, aNSString’s |length|()}) as text
end removeEmoji

★Click Here to Open This Script 

Posted in regexp Text | Tagged 10.14savvy 10.15savvy NSRegularExpressionSearch NSString | 2 Comments

文字列から絵文字のみ削除するじっけん

Posted on 11月 3, 2019 by Takaaki Naganoya

文字列から絵文字だけを削除する実験です(まだ、完全にはうまく削除しきれていないので)。

→ きちんと動くバージョン 文字列から絵文字を削除

CotEditorのScript PackをmacOS 10.13環境にインストールしようとして、Zipアーカイブが展開できないとか、ファイル名に絵文字が入っているためにファイルコピー自体が行えないという現象に直面しました。

macOS 10.14.1で絵文字が70個ほど追加になったという記録があるので、

macOS Mojave 10.14.1
アップデートこのアップデートの内容は以下の通りです。グループ FaceTime のビデオ通話とオーディオ通話に対応しました。最大 32 人の参加者が同時に通話することができ、会話の内容はエンドツーエンドで暗号化されるため、プライバシーも守られます。グループ FaceTime は、メッセージ App のグループチャットから始めることができ、通話に途中から参加することもできます。赤毛、白髪、巻き毛の新しいキャラクター、スキンヘッドの新しい絵文字、より感情豊かな笑顔のほか、動物、スポーツ、食べ物を表す絵文字など、70 種類以上の絵文字が新たに追加されました。

これらの絵文字ファイル名に用いたファイルをmacOS 10.14.1以降のOS上で作成し、それ以前のバージョンのOSに持って行こうとするとトラブルが発生するのは当然のことでしょう。

ファイル名が原因であることは明らかなので(ふだんはScriptのファイル名に絵文字を使うことはありません)、自動で指定フォルダ以下の書類やフォルダをすべてスキャンして絵文字キャラクターを削除するという処理を書こうとして、その前段階として指定文字列中の絵文字を削除するAppleScriptを書いてみました。

いい感じに削除できていると思えば、削除できない文字もあったりで、まだ完全ではない印象です。p{Emoji_Presentation}で検出しているのですが、検出できない絵文字があるようで、、、、

もともと、NSString上で完結するように処理しようと試みていたものの、matchesInStringで絵文字を検出したあとの消し込みにてこずって、「じゃあ、1文字ずつ分解してチェックルーチンを通せばいいや」と、トーンダウンした経緯があります。

特定の絵文字だけ検出できないというのは納得できません。本Scriptはまだ実戦配備できないレベルだと思います。

下手をすると、全絵文字の全パターンを配列(リスト)に入れておいて、存在確認を行うことになるのかも?

AppleScript名:テキストから絵文字抽出(複数)して削除.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/11/03
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set a1Str to "where’s 😎the 😎😎emoji 😎?"
set b1Str to removeEmoji(a1Str) of me
–> "where’s the emoji ?"

set a2Str to "2200)🔄❎すべて❌伏せ字に(□に置き換え)"
set b2Str to removeEmoji(a2Str) of me
–> "2200)すべて伏せ字に(□に置き換え)"

set a3Str to "2251)1️⃣2️⃣3️⃣昇順(1–>9)で連番を振る"
set b3Str to removeEmoji(a3Str) of me
–> "2251)1️⃣2️⃣3️⃣昇順(1–>9)で連番を振る"

set a4Str to "2203)🔄❎⚙️🇯🇵簡易日本語形態素解析📚してそれっぽく❌伏せ字に(□に置き換え).scptd"
set b4Str to removeEmoji(a4Str) of me
–> "2203)⚙️簡易日本語形態素解析してそれっぽく伏せ字に(□に置き換え).scptd"

set emojiStr to "😀😃😄😁😆😅😂🤣☺️😊😇🙂🙃😉😌😍🥰😘😗😙😚😋😛😝😜🤪🤨🧐🤓😎🤩🥳😏😒😞😔😟😕🙁☹️😣😖😫😩🥺😢😭😤😡🤬🤯😳🥵🥶😱😨😨😰😥😓🤗🤔🤭🤫🤥😶😐😑😬🙄😯😦😧😮😲😴🤤😪😵🤐🥴🤢🤮🤧😷🤒🤕🤑🤠😈👿👹👺🤡💩👻💀☠️👽👾🤖🎃😺😸😹😻😼😽🙀😿😾🤲👐🙌👏🤝👍👎👊✊🤛🤜🤞✌️🤟🤘👌👈👉👆👇☝️✋🤚🖐🖖👋🤙💪🖕✍️🙏🦶🦵"
set eRes to removeEmoji(emojiStr) of me
–> "☺️☹️☠️✌️☝️🖐✍️"

set emojiStr to "☺️☹️☠️✌️☝️🖐✍️1️⃣2️⃣3️⃣⚙️"
set eRes to removeEmoji(emojiStr) of me
–> "☺️☹️☠️✌️☝️🖐✍️1️⃣2️⃣3️⃣⚙️"

on removeEmoji(aStr)
  script spdC
    property outList : {}
    
property cList : {}
  end script
  
  
set (cList of spdC) to characters of aStr
  
log (cList of spdC)
  
set (outList of spdC) to {}
  
  
repeat with i in (cList of spdC)
    set j to contents of i
    
set eRes to chkEmoji(j) of me
    
if eRes = false then
      set the end of (outList of spdC) to j
    end if
  end repeat
  
return retDelimedText((outList of spdC), "") of me
end removeEmoji

on chkEmoji(aStr)
  set aNSString to current application’s NSString’s stringWithString:aStr
  
set aReg to current application’s NSRegularExpression’s regularExpressionWithPattern:"\\p{Emoji_Presentation}" options:0 |error|:(missing value)
  
set cResList to (aReg’s matchesInString:(aNSString) options:0 range:(current application’s NSMakeRange(0, aNSString’s |length|()))) as list
  
if length of cResList = 0 then return false –指定文字列に絵文字が入っていない場合
  
return true –指定文字列に絵文字が入っている場合
end chkEmoji

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

★Click Here to Open This Script 

Posted in Text | Tagged 10.14savvy 10.15savvy NSMakeRange NSRegularExpression NSString | Leave a comment

Post navigation

  • Older posts
  • Newer posts

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

Google Search

Popular posts

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

Tags

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

カテゴリー

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

アーカイブ

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

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

メタ情報

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

Forum Posts

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

メタ情報

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