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

カテゴリー: XML

choose fileで指定したsdefを読み込み、sdef中のサンプル(用例)を個別にHTML書き出しする

Posted on 12月 30, 2024 by Takaaki Naganoya

スクリプトエディタから書き出したsdefファイルを選択すると、指定の書き出し先フォルダにsdef内のAppleScriptサンプルをHTML形式で書き出すAppleScriptです(最初のバージョンでHTMLの実体参照デコード処理をハードコーディングしていたのを、Cocoaの機能を利用するよう書き換えました)。

スクリプトエディタでAppleScript用語辞書を表示させた状態で、ファイル書き出しすると個別のsdefファイルとして保存できます。この状態のsdefにアプリのバージョン番号を付加して、バージョン履歴として保存しています。

こうして保存しておいたsdef内のサンプルAppleScriptをHTMLとして書き出します。Pixelmator Proに58本のサンプルScriptが入っていたので、けっこうな分量になります。それを手作業で取り出すのは手間なので、Scriptで取り出すことにしました。

それを収集するために作ったのが本Scriptです。

本来、スクリプトエディタで表示(xinclude解消+レンダリング)させたsdefを処理させるAppleScriptで、いちいちxincludeの展開を行わせるのは無意味なのですが、本Scriptはもともと「アプリのBundle IDを指定してsdefのパスを求めて処理する」ようになっていたため、仕様がとがりすぎて汎用性がいまひとつだったので、「スクリプトエディタで書き出したsdefを処理」するように書き換えたという経緯があるためです。説明したら余計にわからなくなったような、、、、

AppleScript名:choose fileで指定したsdefを読み込み、sdef中のサンプル(用例)を個別にHTML書き出しする v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/12/31
—
–  Copyright © 2022-2024 Piyomaru Software, All Rights Reserved
—

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

set sdefAlias to (choose file of type {"com.apple.scripting-definition"} with prompt "書き出したSDEFを選択")
set sdefFullPath to (POSIX path of sdefAlias)

–SDEF読み込み(Xincludeの展開が必要な状態)
tell current application
  set theXML to read sdefAlias as «class utf8»
end tell

–NSXMLDocumentの生成、Xincludeを有効に
set {theXMLDoc, theError} to current application’s NSXMLDocument’s alloc()’s initWithXMLString:theXML options:(current application’s NSXMLDocumentXInclude) |error|:(reference)

set aDocStr to (theXMLDoc’s XMLData)
set aDocStr2 to (current application’s NSString’s alloc()’s initWithData:(aDocStr) encoding:(current application’s NSUTF8StringEncoding)) as string

set sampleList to (extractStrFromTo(aDocStr2, "<html>", "</html>") of me)
set sampleCount to length of sampleList
if sampleCount = 0 then return

set outFol to POSIX path of (choose folder with prompt "Select Output Folder")

set aCount to 1

repeat with i in sampleList
  set j to (contents of i)
  
  
if j is not equal to "" then
    set j1 to decodeCharacterReference(j) of me
    
set j2 to "<!DOCTYPE html><html><meta charset=utf-8><title>" & (aCount as string) & "</title><body>" & j1 & "</body></html>"
    
    
set wPath to outFol & (aCount as string) & ".html"
    
set fRes to writeToFileAsUTF8(j2, wPath) of me
    
if fRes = false then error
    
    
set aCount to aCount + 1
  end if
end repeat

–指定パスからアプリケーションのScriptabilityをbooleanで返す
on retAppSdefNameFromBundleIPath(appPath as string)
  set aDict to (current application’s NSBundle’s bundleWithPath:appPath)’s infoDictionary()
  
set aRes to aDict’s valueForKey:"OSAScriptingDefinition"
  
if aRes = missing value then return false
  
set asRes to aRes as string
  
  
return asRes as string
end retAppSdefNameFromBundleIPath

–指定文字と終了文字に囲まれた内容を抽出
on extractStrFromTo(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
  
  
return (anArray as list)
end extractStrFromTo

on writeToFileAsUTF8(aStr, aPath)
  set cStr to current application’s NSString’s stringWithString:aStr
  
set thePath to POSIX path of aPath
  
set aRes to cStr’s writeToFile:thePath atomically:false encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value)
  
return aRes as boolean
end writeToFileAsUTF8

–文字置換
on repChar(origText as string, targStr as string, repStr as string)
  set {txdl, AppleScript’s text item delimiters} to {AppleScript’s text item delimiters, targStr}
  
set temp to text items of origText
  
set AppleScript’s text item delimiters to repStr
  
set res to temp as text
  
set AppleScript’s text item delimiters to txdl
  
return res
end repChar

–実体参照をデコード
on decodeCharacterReference(aStr)
  set anNSString to current application’s NSString’s stringWithString:aStr
  
set theData to anNSString’s dataUsingEncoding:(current application’s NSUTF16StringEncoding)
  
set styledString to current application’s NSAttributedString’s alloc()’s initWithHTML:theData documentAttributes:(missing value)
  
set plainText to (styledString’s |string|()) as string
  
return plainText
end decodeCharacterReference

★Click Here to Open This Script 

Posted in file File path sdef XML | Tagged 13.0savvy 14.0savvy 15.0savvy | Leave a comment

指定のSDEFファイルからコマンドを抽出

Posted on 10月 17, 2024 by Takaaki Naganoya

アプリからスクリプトエディタを用いて書き出したSDEFファイル(AppleScript用語説明ファイル)から、コマンドを抽出するAppleScriptです。

–> Download sdef command lister.scptd (Including AS Lib in its bundle)

個人的に、SDEFの差分を確認するために極力アプリの各バージョンのSDEFを書き出して保存するようにしており、

用語辞書ベースで機能追加や変更が行われたことを確認しています。


▲Skim v1.0のAppleScript用語辞書


▲Skim v1.7.5のAppleScript用語辞書

こうしたSDEFのままでは比較できないので、FileMerge(XcodeについてくるGUI版diffの傑作)を使ってバージョン間の差分を取って確認するのが「通常営業」なわけです。

これがv1.0から最新版までの経緯をおおまかに把握したい、といったときには細かすぎますし、用途に合っていません。

そこで本Scriptを書いて利用することにしました。各バージョンごとにコマンドを抽出して、存在する/しないといった比較ができれば全体的な傾向を把握できます。

Apple純正アプリのSDEF、Adobe Creative Cloudアプリ、Microsoft OfficeのSDEFなどひととおり処理してみましたが、自分が使った範囲ではとくに問題は見つかっていません。ただ、まだ間違いがあるかもしれないため、処理ミスが見られた場合にはコメントで報告してください。


▲本Scriptを用いて、Skim各バージョンのAppleScript用語辞書からコマンドの分布を表にしたもの

AppleScript名:指定のSDEFファイルからコマンドを抽出.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/10/16
—
–  Copyright © 2022-2024 Piyomaru Software, All Rights Reserved
—

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

script myDict
  property sdefDict : {}
end script

set sdefPath to (POSIX path of (choose file of type {"com.apple.scripting-definition"} with prompt "SDEFファイルを選択"))

set comRes to {}

set (sdefDict of myDict) to {}
set comList to parseSdefAndRetObjects(sdefPath) of me

repeat with i in comList
  set j to contents of i
  
set aRes to parseSdefFileAndRetCommandStructure(sdefPath, j) of me
  
if aRes is not equal to "" then set aRes to "OK"
  
set the end of comRes to j
end repeat

set aStr to listToStringUsingTextItemDelimiter(comRes, return) of me

on parseSdefFileAndRetCommandStructure(targSDEFPath, aTargCom)
  set suitesList to ((sdefDict of myDict)’s valueForKeyPath:"dictionary.suite.command")
  
  
repeat with i in suitesList –SuitesでLoop
    set j to contents of i
    
    
try
      if j is not equal to missing value and j is not equal to current application’s NSNull then
        repeat with ii in j –CommandでLoop
          set jj to contents of ii
          
set tmpName to jj’s attributes’s |name|
          
          
if aTargCom is in (tmpName as list) then return jj
        end repeat
      end if
    on error
      return ""
    end try
    
  end repeat
  
return false
end parseSdefFileAndRetCommandStructure

–指定Bundle IDのコマンド一覧を取得する
on parseSdefAndRetObjects(sdefPath)
  if (sdefDict of myDict) = {} then
    set aRes to parseSDEFfileAndRetXMLStr(sdefPath) of me
    
set (sdefDict of myDict) to (xmlLib’s makeRecordWithXML:aRes)
  end if
  
  
set e1Res to (sdefDict of myDict)’s valueForKeyPath:"dictionary.suite.command.attributes.name"
  
  
set fRes to FlattenList(e1Res as list) of me
  
set bList to cleanUp1DList(fRes, {"missing value"}) of me
  
set gRes to uniquify1DList(bList, true) of me
  
return gRes
end parseSdefAndRetObjects

–SDEFをXincludeを考慮しつつ展開
on parseSDEFfileAndRetXMLStr(sdefFullPath)
  set sdefAlias to (POSIX file sdefFullPath) as alias –sdefのフルパスを求める
  
  
–SDEF読み込み(Xincludeの展開が必要な状態)
  
tell current application
    set theXML to read sdefAlias as «class utf8»
  end tell
  
  
–NSXMLDocumentの生成、Xincludeを有効に
  
set {theXMLDoc, theError} to current application’s NSXMLDocument’s alloc()’s initWithXMLString:theXML options:(current application’s NSXMLDocumentXInclude) |error|:(reference)
  
  
–XMLを文字データ化
  
set aDocStr to (theXMLDoc’s XMLData)
  
set aDocStr2 to (current application’s NSString’s alloc()’s initWithData:(aDocStr) encoding:(current application’s NSUTF8StringEncoding)) as string
  
  
return aDocStr2
end parseSDEFfileAndRetXMLStr

–By Paul Berkowitz
–2009年1月27日 2:24:08:JST
–Re: Flattening Nested Lists
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 cleanUp1DList(aList as list, cleanUpItems as list)
  set bList to {}
  
repeat with i in aList
    set j to contents of i
    
if j is not in cleanUpItems then
      set the end of bList to j
    end if
  end repeat
  
return bList
end cleanUp1DList

–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

–1D Listを指定デリミタをはさんでテキスト化(Shane Stanley)
on listToStringUsingTextItemDelimiter(sourceList, textItemDelimiter)
  set CocoaArray to current application’s NSArray’s arrayWithArray:sourceList
  
set CocoaString to CocoaArray’s componentsJoinedByString:textItemDelimiter
  
return (CocoaString as string)
end listToStringUsingTextItemDelimiter

★Click Here to Open This Script 

Posted in sdef XML | 1 Comment

Bundle IDで指定したアプリケーションのSDEFからコマンドを抽出テスト(指定コマンドのコマンド属性取り出し)

Posted on 8月 13, 2022 by Takaaki Naganoya

アプリケーションのSDEF(AppleScript用語辞書)を解析して情報を取り出すシリーズの本命。指定コマンドの属性値を取り出すテスト用のAppleScriptです。

–> Download script with library

まだ、明確な成果が出ているわけではありませんが、こうしてアクセスして問題がないか、多くのアプリケーションの各コマンドで問題がないかを調査しているところです。

AppleScript名:Bundle IDで指定したアプリケーションのSDEFからコマンドを抽出テスト(指定コマンドのコマンド属性取り出し).scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/08/2
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—

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

script myDict
  property sdefDict : {}
end script

set (sdefDict of myDict) to {}
set aRes to parseSdefAndRetCommandStructure("com.apple.iWork.Keynote", "export") of me

on parseSdefAndRetCommandStructure(targAppBundleID, aTargCom)
  if (sdefDict of myDict) = {} then
    set aRes to parseSDEFandRetXMLStr(targAppBundleID) of me
    
set (sdefDict of myDict) to (xmlLib’s makeRecordWithXML:aRes)
  end if
  
  
set suitesList to ((sdefDict of myDict)’s valueForKeyPath:"dictionary.suite.command")
  
  
repeat with i in suitesList –SuitesでLoop
    set j to contents of i
    
    
try
      repeat with ii in j –CommandでLoop
        set jj to contents of ii
        
set tmpName to jj’s attributes’s |name|
        
        
if aTargCom is in (tmpName as list) then return jj
        
      end repeat
    on error
      return false
    end try
    
  end repeat
  
return false
end parseSdefAndRetCommandStructure

on pickUpFromToStr(aStr as string, s1Str as string, s2Str as string)
  set a1Offset to offset of s1Str in aStr
  
if a1Offset = 0 then return -1
  
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 -2
  
  
set cStr to text 1 thru (a2Offset – (length of s2Str)) of bStr
  
  
return cStr as string
end pickUpFromToStr

–指定文字と終了文字に囲まれた内容を抽出
on extractStrFromTo(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|() is not equal to 1 then return false
  
  
return first item of (anArray as list)
end extractStrFromTo

–SDEFをXincludeを考慮しつつ展開
on parseSDEFandRetXMLStr(targAppBundleID)
  set thePath to POSIX path of (path to application id targAppBundleID)
  
  
set aSDEFname to retAppSdefNameFromBundleIPath(thePath, "OSAScriptingDefinition") of me
  
if aSDEFname = false then return
  
  
if aSDEFname does not end with ".sdef" then set aSDEFname to aSDEFname & ".sdef"
  
set sdefFullPath to thePath & "Contents/Resources/" & aSDEFname
  
set sdefAlias to (POSIX file sdefFullPath) as alias –sdefのフルパスを求める
  
  
–SDEF読み込み(Xincludeの展開が必要な状態)
  
tell current application
    set theXML to read sdefAlias as «class utf8»
  end tell
  
  
–NSXMLDocumentの生成、Xincludeを有効に
  
set {theXMLDoc, theError} to current application’s NSXMLDocument’s alloc()’s initWithXMLString:theXML options:(current application’s NSXMLDocumentXInclude) |error|:(reference)
  
  
–XMLを文字データ化
  
set aDocStr to (theXMLDoc’s XMLData)
  
set aDocStr2 to (current application’s NSString’s alloc()’s initWithData:(aDocStr) encoding:(current application’s NSUTF8StringEncoding)) as string
  
  
return aDocStr2
end parseSDEFandRetXMLStr

–指定パスからアプリケーションのInfo.plist中の属性値を返す
on retAppSdefNameFromBundleIPath(appPath as string, aKey as string)
  set aDict to (current application’s NSBundle’s bundleWithPath:appPath)’s infoDictionary()
  
set aRes to aDict’s valueForKey:(aKey)
  
if aRes = missing value then return false
  
set asRes to aRes as string
  
  
return asRes as string
end retAppSdefNameFromBundleIPath

★Click Here to Open This Script 

Posted in sdef System XML | Tagged 10.14savvy 10.15savvy 11.0savvy 12.0savvy | Leave a comment

Bundle IDで指定したアプリケーションのSDEFからオブジェクトを抽出

Posted on 8月 3, 2022 by Takaaki Naganoya

指定アプリケーションのSDEFを走査して、アプリケーションのAppleScript用語辞書に掲載されているオブジェクトを抽出するAppleScriptです。まだ、実験的な段階のものです。

XMLをパースするためのライブラリ(Shaneがつくったもの)を併用するため、Scriptライブラリ入りのScriptをダウンロードして実行してみてください。

–>Download Bundle Script With Script Library

ここまで試しておいてナニですが、Adobe系のアプリケーションの用語辞書については、アプリケーション上で動的に生成するようなので、Adobe系のアプリケーションに対して正しい結果を取得できることは期待しないでください。

XML的にアクセスすると、「属性値がここで取得できるはずなのだが」といった不思議な現象のオンパレードでした。edama2さんからの助言もあり、XMLをそのままではなくNSDictionaryに変換してアクセスしたのが本Scriptです。

ちょっとした試行錯誤を経て、Keynote.appのオブジェクトについては取得できている印象です。

オブジェクトを取得したら、各オブジェクトの属性値を取れるようにして、オブジェクトが応答するコマンドの一覧を取得し…というところまではいけるんじゃないでしょうか。

AppleScript名:Bundle IDで指定したアプリケーションのSDEFからオブジェクトを抽出.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/08/2
—
–  Copyright © 2022 Piyomaru Software, All Rights Reserved
—

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

set aRes to parseSdefAndRetObjects("com.apple.iWork.Keynote") of me
–> {"column", "text item", "application", "word", "image", "rich text", "iWork item", "window", "group", "movie", "slide layout", "line", "paragraph", "slide", "audio clip", "shape", "table", "range", "row", "cell", "theme", "iWork container", "character", "document", "chart"}

set bRes to parseSdefAndRetObjects("com.apple.iWork.Pages") of me
–> {"column", "text item", "application", "word", "image", "rich text", "iWork item", "template", "window", "group", "movie", "shape", "line", "row", "paragraph", "placeholder text", "range", "audio clip", "table", "cell", "document", "page", "iWork container", "chart", "character", "section"}

set cRes to parseSdefAndRetObjects("com.apple.iWork.Numbers") of me
–> {"column", "text item", "application", "word", "image", "rich text", "iWork item", "template", "window", "group", "movie", "shape", "line", "paragraph", "row", "audio clip", "range", "table", "cell", "iWork container", "document", "character", "chart", "sheet"}

set dRes to parseSdefAndRetObjects("com.apple.Finder") of me
–> {"container", "application", "alias list", "list view options", "alias file", "item", "document file", "preferences", "icon view options", "application process", "trash-object", "internet location file", "process", "Finder window", "desktop window", "window", "application file", "computer-object", "column view options", "clipping window", "desktop-object", "clipping", "file", "icon family", "folder", "desk accessory process", "label", "column", "preferences window", "information window", "package", "disk"}

set eRes to parseSdefAndRetObjects("com.apple.Safari") of me
–> {"document", "contentsProvider", "tab", "application", "sourceProvider", "window"}

set fRes to parseSdefAndRetObjects("com.apple.Mail") of me
–> {"account", "container", "application", "cc recipient", "mailbox", "word", "outgoing message", "rich text", "smtp server", "attachment", "bcc recipient", "pop account", "window", "signature", "to recipient", "OLD message editor", "paragraph", "iCloud account", "ldap server", "recipient", "message", "rule condition", "header", "document", "attribute run", "rule", "imap account", "mail attachment", "message viewer", "character"}

set gRes to parseSdefAndRetObjects("com.coteditor.CotEditor") of me
–> {"window", "paragraph", "word", "character", "attribute run", "document", "text selection", "rich text", "application", "attachment"}

set hRes to parseSdefAndRetObjects("com.pixelmatorteam.pixelmator.x") of me
–> {"vortex effect", "paragraph", "focus effect", "bump effect", "layer", "color adjustments", "box effect", "stripes effect", "window", "circle splash effect", "document info", "word", "text layer", "tilt shift effect", "image fill effect", "disc effect", "gaussian effect", "color fill effect", "effects layer", "ellipse shape layer", "styles", "motion effect", "rich text", "pattern fill effect", "spin effect", "line shape layer", "application", "light tunnel effect", "image layer", "group layer", "character", "rounded rectangle shape layer", "crystallize effect", "shape layer", "star shape layer", "pinch effect", "checkerboard effect", "effect", "rectangle shape layer", "pixelate effect", "pointillize effect", "document", "hole effect", "twirl effect", "polygon shape layer", "zoom effect", "color adjustments layer"}

on parseSdefAndRetObjects(targAppBundleID)
  set aRes to parseSDEFandRetXMLStr(targAppBundleID) of me
  
set cRes to (xmlLib’s makeRecordWithXML:aRes)
  
  
–2つのタイプのオブジェクトがある? まだある???
  
set e1Res to cRes’s valueForKeyPath:"dictionary.suite.class.element.attributes.type"
  
set e2Res to cRes’s valueForKeyPath:"dictionary.suite.class.attributes.name"
  
set eRes to (e1Res as list) & (e2Res as list)
  
  
set fRes to FlattenList(eRes) of me
  
set bList to cleanUp1DList(fRes, {"missing value"}) of me
  
set gRes to uniquify1DList(bList, true) of me
  
set hRes to uniquify1DList(gRes, true) of me
  
return hRes
end parseSdefAndRetObjects

on pickUpFromToStr(aStr as string, s1Str as string, s2Str as string)
  set a1Offset to offset of s1Str in aStr
  
if a1Offset = 0 then return -1
  
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 -2
  
  
set cStr to text 1 thru (a2Offset – (length of s2Str)) of bStr
  
  
return cStr as string
end pickUpFromToStr

–指定文字と終了文字に囲まれた内容を抽出
on extractStrFromTo(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|() is not equal to 1 then return false
  
  
return first item of (anArray as list)
end extractStrFromTo

–SDEFをXincludeを考慮しつつ展開
on parseSDEFandRetXMLStr(targAppBundleID)
  set thePath to POSIX path of (path to application id targAppBundleID)
  
  
set aSDEFname to retAppSdefNameFromBundleIPath(thePath, "OSAScriptingDefinition") of me
  
if aSDEFname = false then return
  
  
if aSDEFname does not end with ".sdef" then set aSDEFname to aSDEFname & ".sdef"
  
set sdefFullPath to thePath & "Contents/Resources/" & aSDEFname
  
set sdefAlias to (POSIX file sdefFullPath) as alias –sdefのフルパスを求める
  
  
–SDEF読み込み(Xincludeの展開が必要な状態)
  
tell current application
    set theXML to read sdefAlias as «class utf8»
  end tell
  
  
–NSXMLDocumentの生成、Xincludeを有効に
  
set {theXMLDoc, theError} to current application’s NSXMLDocument’s alloc()’s initWithXMLString:theXML options:(current application’s NSXMLDocumentXInclude) |error|:(reference)
  
  
–XMLを文字データ化
  
set aDocStr to (theXMLDoc’s XMLData)
  
set aDocStr2 to (current application’s NSString’s alloc()’s initWithData:(aDocStr) encoding:(current application’s NSUTF8StringEncoding)) as string
  
  
return aDocStr2
end parseSDEFandRetXMLStr

–指定パスからアプリケーションのInfo.plist中の属性値を返す
on retAppSdefNameFromBundleIPath(appPath as string, aKey as string)
  set aDict to (current application’s NSBundle’s bundleWithPath:appPath)’s infoDictionary()
  
set aRes to aDict’s valueForKey:(aKey)
  
if aRes = missing value then return false
  
set asRes to aRes as string
  
  
return asRes as string
end retAppSdefNameFromBundleIPath

–By Paul Berkowitz
–2009年1月27日 2:24:08:JST
–Re: Flattening Nested Lists
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 cleanUp1DList(aList as list, cleanUpItems as list)
  set bList to {}
  
repeat with i in aList
    set j to contents of i
    
if j is not in cleanUpItems then
      set the end of bList to j
    end if
  end repeat
  
return bList
end cleanUp1DList

–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 sdef XML | Tagged 11.0savvy 12.0savvy | Leave a comment

Bundle IDで指定したアプリケーションのSDEFからXPathで指定したClassにアクセス v2

Posted on 8月 2, 2022 by Takaaki Naganoya

Bundle IDで指定したアプリケーションのSDEF(AppleScript定義辞書)を、Xincludeを考慮しつつparseして、XPathで指定したクラスにアクセスするAppleScriptです。

KeynoteのAppleScript用語辞書の「open」コマンド、

を指定して本Scriptでデータを取り出すと、

のような出力が得られます。まだちょっと、属性値を取り出すところまで行っていませんが、つまり…指定コマンドのパラメータや、指定クラスがどのようなコマンドに応答するかなど、プログラム側からわかるようになることでしょう(多分)。

AppleScript名:Bundle IDで指定したアプリケーションのSDEFからXPathで指定したClassにアクセス v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/08/2
—
–  Copyright © 2022 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 targAppBundleID to "com.apple.iWork.Keynote" –SDEFを取り出すターゲットのアプリケーションのBundle ID
–set commandXPath to "//class[@name=’application’]/property"
–set commandXPath to "//command[@name=’open’]/direct-parameter"
–set commandXPath to "//class[@name=’document’]/property"
–set commandXPath to "//class[@name=’document’]/responds-to"
–set commandXPath to "//command[@name=’open’]" –Open Command–Open コマンド
set commandXPath to "//command[@name=’open’]/direct-parameter/type" –Open Command–Open コマンド

set aRes to parseSDEFandRetXPathData(targAppBundleID, commandXPath) of me
return aRes

–SDEFをXincludeを考慮しつつ展開
on parseSDEFandRetXPathData(targAppBundleID, commandXPath)
  set thePath to POSIX path of (path to application id targAppBundleID)
  
  
set aSDEFname to retAppSdefNameFromBundleIPath(thePath, "OSAScriptingDefinition") of me
  
if aSDEFname = false then return
  
  
if aSDEFname does not end with ".sdef" then set aSDEFname to aSDEFname & ".sdef"
  
set sdefFullPath to thePath & "Contents/Resources/" & aSDEFname
  
set sdefAlias to (POSIX file sdefFullPath) as alias –sdefのフルパスを求める
  
  
–SDEF読み込み(Xincludeの展開が必要な状態)
  
tell current application
    set theXML to read sdefAlias as «class utf8»
  end tell
  
  
–NSXMLDocumentの生成、Xincludeを有効に
  
set {theXMLDoc, theError} to current application’s NSXMLDocument’s alloc()’s initWithXMLString:theXML options:(current application’s NSXMLDocumentXInclude) |error|:(reference)
  
  
–XMLを文字データ化
  
set aDocStr to (theXMLDoc’s XMLData)
  
set aDocStr2 to (current application’s NSString’s alloc()’s initWithData:(aDocStr) encoding:(current application’s NSUTF8StringEncoding)) as string
  
  
set dRes to my extractFrom:theXMLDoc matchingXPath:commandXPath
  
return dRes
end parseSDEFandRetXPathData

–指定のNSXMLDocumentから、指定のXPathでアクセスして内容を返す
on extractFrom:theNSXMLDocument matchingXPath:theQuery
  set attStrings to {} — where attributes will be stored
  
set theXMLOutput to current application’s NSXMLElement’s alloc()’s initWithName:"output" — found nodes added to this
  
  
set {theResults, theNSError} to (theNSXMLDocument’s nodesForXPath:theQuery |error|:(reference)) — query
  
  
if theResults is not missing value then
    repeat with anNSXMLNode in (theResults as list)
      anNSXMLNode’s detach() — need to detach first
      
if anNSXMLNode’s |kind|() as integer = current application’s NSXMLAttributeKind then — see if it’s an attribute or node
        set end of attStrings to (anNSXMLNode’s stringValue()) as {text, list, record}
      else
        (theXMLOutput’s addChild:anNSXMLNode) — add node
      end if
    end repeat
    
    
return (theXMLOutput’s XMLStringWithOptions:(current application’s NSXMLNodePrettyPrint)) as {text, list, record}
  else
    return missing value
  end if
end extractFrom:matchingXPath:

–指定パスからアプリケーションのInfo.plist中の属性値を返す
on retAppSdefNameFromBundleIPath(appPath as string, aKey as string)
  set aDict to (current application’s NSBundle’s bundleWithPath:appPath)’s infoDictionary()
  
set aRes to aDict’s valueForKey:(aKey)
  
if aRes = missing value then return false
  
set asRes to aRes as string
  
  
return asRes as string
end retAppSdefNameFromBundleIPath

★Click Here to Open This Script 

Posted in sdef System XML | Tagged 10.15savvy 11.0savvy 12.0savvy Keynote | 1 Comment

xincludeを有効にしてXML(sdef)読み込み v2

Posted on 7月 26, 2022 by Takaaki Naganoya

指定のBundle IDのアプリケーションのInfo.plistの値からSDEF(AppleScript命令定義ファイル)のファイル情報を読み取って、実際にSDEFの実ファイルを読み取り、得られた文字列をXMLとして解釈する際にXincludeを展開して、再度文字列に戻すAppleScriptです。

もともと、SDEFを読み取って分析することは、アプリケーションのバージョン間の変更差分を検出する用途で試していました。これは、変化のみを検出することを目的としたもので、内容について仔細に認識することを目的としたものではありませんでした。

そこから1歩進んで、AppleScript側から実行環境情報を取得する試みをいろいろ続けてきました。

実行環境自体が何なのか、という判別はここ数年で一番大きな成果だったと感じます。地球にいながら「銀河系の中の、太陽系の中の第3惑星にいる」ということが観測できるようになったわけです。

さらに、それぞれのランタイム環境の識別が可能になったことにより、各実行環境の「差」を判定しやすくなった、という副産物もありました。

話を戻しましょう。

SDEFを読んで、当該アプリケーションが何を行えるかをAppleScript側からも認識できるはずで、そのための調査も開始していました。

System Eventsの「Scripting Definition Suite」はその名前と用語から、AppleScriptからSDEFの解析を行うための部品であることが推測され、いろいろ調べてきたものの…..Apple側がSystem Eventsそれ自体のチェックを行うために設けた「メンテナンス&デバッグのための機能(ただしSystem Events専用)」だという結論にいたっています。つまり、System Events以外にはまるっきり使えません。

これで、AppleScriptのプログラム側からアプリケーション側の仕様を自動判別&解析するためには、SDEFそのものを解析するしかないという話になりました。

ただ、SDEFの直接解析については1つの「ちょっと困った仕様」がありました。外部ファイルをincludeできる(Xinclude)ようになっており、そのファイルを元のSDEF上に展開するのは、まじめにXML上の情報を分析する必要があります。ファイル・システム上のどこの場所からどのファイルを読み込むのか、という話と……XMLのオブジェクトモデル上のどこに展開するのかという話の両方を処理する必要があります。まじめに組むと、それなりの時間がかかってしまいそうです。

少ない例から推測してScriptを書くことは不可能ではありませんが、「隠れ仕様」が存在していた場合には対処できません。OS側にその機能があれば、そのままそっくり利用できたほうがよいだろうと思われました。

このXincludeの展開を(他力本願で)行うには、どこのレイヤーのどの機能を用いるべきなのか?

matttのOno.frameworkなどもビルドして試してみたものの、Xincludeの展開はソースコードを全文検索しても見つけられず、もうちょっと物理層に近いレイヤーのlibxml2の機能にアクセスする必要があるようでした。

ほかにも、Unix Shell Commandに、「xsltproc」コマンドが存在しており、Xinclude展開を行ってくれるようでした(XSLTを書けば)。スクリプトエディタに任意のアプリケーションをオープンさせればAppleScript用語辞書を表示してくれるわけで、この表示中のSDEFについてはXincludeがすべて解決された状態になっているため、AppleScriptからスクリプトエディタを操作するという手段もないわけではないのですが、もっとスマートに(こっそり)処理したかったので、これは(機能することがわかっていながらも)使えません。

結局、NSXMLDocumentのNSXMLNodeOptionsでNSXMLDocumentXIncludeを指定すると、XMLテキストをオブジェクトに解釈する際に外部ファイルを展開してくれることが判明。

Mail.appのSDEFでいえば、Standard Suiteにinclude指定があり、

元ファイルを読み込んだだけでは完全体のSDEFを取得できません。これを、本AppleScriptを用いて読み込んで解釈すると、

のように、指定パスに存在している「CocoaStandard.sdef」を展開します。ほかにも、Microsoft系のアプリケーションでXincludeを使用しており、本AppleScriptのような処理を経た上でSDEFの分析を行う必要があることでしょう。

これが、今日明日の段階で何か「すごいこと」ができるような存在になることは決してありませんが、この部品が存在していることで異次元の処理ができるようになるような手応えはあります。

AppleScript名:xincludeを有効にしてXML(sdef)読み込み v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2022/07/26
—
–  Copyright © 2022 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 targAppBundleID to "com.apple.mail" –SDEFを取り出すターゲットのアプリケーションのBundle ID

set thePath to POSIX path of (path to application id targAppBundleID)

set aSDEFname to retAppSdefNameFromBundleIPath(thePath, "OSAScriptingDefinition") of me
if aSDEFname = false then return

if aSDEFname does not end with ".sdef" then set aSDEFname to aSDEFname & ".sdef"
set sdefFullPath to thePath & "Contents/Resources/" & aSDEFname
set sdefAlias to (POSIX file sdefFullPath) as alias –sdefのフルパスを求める

–SDEF読み込み(Xincludeの展開が必要な状態)
tell current application
  set theXML to read sdefAlias as «class utf8»
end tell

–NSXMLDocumentの生成、Xincludeを有効に
set {theXMLDoc, theError} to current application’s NSXMLDocument’s alloc()’s initWithXMLString:theXML options:(current application’s NSXMLDocumentXInclude) |error|:(reference)

–XMLを文字データ化
set aDocStr to (theXMLDoc’s XMLData)
set aDocStr2 to (current application’s NSString’s alloc()’s initWithData:(aDocStr) encoding:(current application’s NSUTF8StringEncoding)) as string

–指定パスからアプリケーションのScriptabilityをbooleanで返す
on retAppSdefNameFromBundleIPath(appPath as string, aKey as string)
  set aDict to (current application’s NSBundle’s bundleWithPath:appPath)’s infoDictionary()
  
set aRes to aDict’s valueForKey:(aKey)
  
if aRes = missing value then return false
  
set asRes to aRes as string
  
  
return asRes as string
end retAppSdefNameFromBundleIPath

★Click Here to Open This Script 

Posted in file File path sdef XML | Tagged 12.0savvy | 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

指定URLのMS名を取得する v2a

Posted on 9月 3, 2019 by Takaaki Naganoya

Shane Stanleyが「HTMLをXMLと見立ててアクセスすれば外部フレームワークなしに処理できて簡単だよ」と、送ってくれたサンプルScriptです。

2つの意味で焦りました。

(1)指定URLの内容をダウンロードするのに、「initWithContentsOfURL:」で処理
(2)この調子で処理したら、お手軽にREST APIも呼べそうな雰囲気

いろいろ考えさせられる内容でもあります。こういう「それ自体で何か製品を構成できるほどのサイズの処理じゃないけど、何かに絶対に使ってますよね」的な処理をBlogで公開しておくことのメリットを感じつつ、XML処理とか正規表現の処理が個人的に不得意なので、とても参考になります。

自分の用途が残念な(そんなに生産的でもなく趣味的な、という意味で)ものだったので、恐縮するばかりですー(オンラインゲームの機体のデータをWikiからまるごと引っこ抜くというものだったので)。

AppleScript名:get a title.scptd
—
–  Created by: Shane Stanley
–  Created on: 2019/09/03
—
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

— classes, constants, and enums used
property NSXMLDocumentTidyHTML : a reference to 512
property NSXMLDocument : a reference to current application’s NSXMLDocument
property NSString : a reference to current application’s NSString
property |NSURL| : a reference to current application’s |NSURL|
property HTMLDocument : a reference to current application’s HTMLDocument
property NSMutableArray : a reference to current application’s NSMutableArray

set aURL to "https://w.atwiki.jp/senjounokizuna/pages/1650.html"
set aRes to getTitleFromAURL(aURL) of me
–> "ジム・スナイパー  RGM-79(G)"

on getTitleFromAURL(aURL)
  set theNSURL to |NSURL|’s URLWithString:aURL
  
set {theXML, theError} to NSXMLDocument’s alloc()’s initWithContentsOfURL:theNSURL options:NSXMLDocumentTidyHTML |error|:(reference)
  
if theXML is missing value then error theError’s localizedDescription() as text
  
repeat with i from 2 to 7 by 1
    set theNodes to (theXML’s nodesForXPath:("//h" & i) |error|:(missing value))
    
if theNodes’s |count|() is not 0 then return (theNodes’s firstObject()’s stringValue()) as text
  end repeat
  
error "Header is missing"
end getTitleFromAURL

★Click Here to Open This Script 

Posted in Text URL XML | Tagged 10.12savvy 10.13savvy 10.14savvy HTMLDocument NSMutableArray NSString NSURL NSXMLDocument NSXMLDocumentTidyHTML | Leave a comment

Macの製品カテゴリ名を取得する

Posted on 2月 20, 2018 by Takaaki Naganoya
AppleScript名:Macの製品カテゴリ名を取得する
— Created 2015-11-01 by Takaaki Naganoya
— 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set macRes to getSystemProfileInAGenre("SPHardwareDataType", "machine_name") of me
–>  "MacBook Pro"

on getSystemProfileInAGenre(aTargGenre as string, aTargKey as string)
  set sRes to do shell script ("/usr/sbin/system_profiler -xml " & aTargGenre)
  
set aSource to (readPlistFromStr(sRes) of me) as list
  
set aaList to contents of first item of aSource
  
  
set aList to _items of aaList
  
repeat with i in aList
    set aDict to (current application’s NSMutableDictionary’s dictionaryWithDictionary:(contents of i))
    
set aKeyList to (aDict’s allKeys()) as list
    
if aTargKey is in aKeyList then
      set aRes to (aDict’s valueForKeyPath:aTargKey)
      
if aRes is not equal to missing value then
        return aRes as string
      end if
    end if
  end repeat
  
  
return false
end getSystemProfileInAGenre

–stringのplistを読み込んでRecordに
on readPlistFromStr(theString)
  set aSource to current application’s NSString’s stringWithString:theString
  
set pListData to aSource’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aPlist to current application’s NSPropertyListSerialization’s propertyListFromData:pListData mutabilityOption:(current application’s NSPropertyListImmutable) |format|:(current application’s NSPropertyListFormat) errorDescription:(missing value)
  
return aPlist
end readPlistFromStr

★Click Here to Open This Script 

Posted in System XML | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

USBに接続されたUSBメモリの情報を取得する v2

Posted on 2月 20, 2018 by Takaaki Naganoya
AppleScript名:USBに接続されたUSBメモリの情報を取得する v2

set tmpPath to POSIX path of (path to temporary items from system domain)
set aFileName to (do shell script "/usr/bin/uuidgen")
set outPath to tmpPath & aFileName & ".plist"
do shell script "/usr/sbin/system_profiler -xml SPUSBDataType > " & outPath

tell application "System Events"
  set vRec to value of property list file (outPath as string)
  
set v1Rec to _items of (first item of vRec)
  
  
set dList to {}
  
set sList to {}
  
repeat with i in v1Rec
    set hitF to false
    
try
      set j to _items of i
      
set hitF to true
    end try
    
    
if hitF = true then
      repeat with jj in j
        try
          set jjj to volumes of jj
          
set sNum to d_serial_num of jj
          
set vStr to b_vendor_id of jj
          
          
repeat with ii in jjj
            set the end of dList to {serialNum:sNum, venderName:vStr, dData:contents of ii}
          end repeat
          
        end try
      end repeat
    end if
  end repeat
end tell

dList

–> {{serialNum:"7f12db856195ef", venderName:"0x056e (Elecom Co., Ltd.)", dData:{mount_point:"/Volumes/NO NAME", _name:"NO NAME", writable:"yes", bsd_name:"disk2s1", free_space:"3.75 GB", file_system:"MS-DOS FAT32", |size|:"3.77 GB"}}, {serialNum:"M004101800001", venderName:"0x4146", dData:{mount_point:"/Volumes/ぴよまる", _name:"ぴよまる", writable:"yes", bsd_name:"disk1s9", free_space:"56 MB", file_system:"HFS+", |size|:"123.1 MB"}}}

★Click Here to Open This Script 

Posted in System XML | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

SDカードを検出

Posted on 2月 15, 2018 by Takaaki Naganoya

マウントされたドライブのうちSDカードに相当するものを検出するAppleScriptです。

ただし、iMac Proで採用されたUHS‑II対応のSDカードスロット+UHS-II対応のSDカードがどのように見えるかは実機がないので確認できません。

exFATのことも考えると、「MSDOS format」を抽出条件に入れないほうがいいのかもしれません。

AppleScript名:SDカードを検出
— Created 2016-10-04 by Takaaki Naganoya
— 2016 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

tell application "Finder"
  set driveList to every disk whose format is (MSDOS format) and ejectable is true and startup is false
  
  
repeat with i in driveList
    set myDisk to disk of (first item of i)
    
set myMountPoint to POSIX path of (myDisk as alias)
    
–> "/Volumes/JVCCAM_SD/"
    
–> "/Volumes/RICOHDCX/"
    
set sdRes to detectSDCard(myMountPoint) of me
    
–> true –SD Card, false –Not SD Card
  end repeat
end tell

on detectSDCard(myMountPoint as string)
  
  
set resData to runCommandString("system_profiler -xml SPStorageDataType") of me
  
set aaDict to (readPlistFromStr(resData) of me) as list
  
set aDictList to (_items of first item of aaDict)
  
  
repeat with i in aDictList
    set j to contents of i
    
    
set aMountPoint to (mount_point of j) as string
    
–> "/Volumes/JVCCAM_SD"
    
–> "/Volumes/RICOHDCX"
    
    
if aMountPoint is not equal to "/" then
      if ((aMountPoint & "/") is equal to myMountPoint) then
        set aDevName to words of (device_name of physical_drive of j)
        
set aMediaName to words of (media_name of physical_drive of j)
        
        
–SD/SDHC/SDXCのカード検出
        
set aDevF to ("SD" is in aDevName) or ("SDHC" is in aDevName) or ("SDXC" is in aDevName)
        
set aMediaF to ("SD" is in aMediaName) or ("SDHC" is in aMediaName) or ("SDXC" is in aMediaName)
        
        
if (aDevF and aMediaF) then return true
      end if
    end if
  end repeat
  
  
return false
end detectSDCard

–文字列で与えたシェルコマンドを実行する
on runCommandString(commandStr as string)
  set aPipe to current application’s NSPipe’s pipe()
  
set aTask to current application’s NSTask’s alloc()’s init()
  
aTask’s setLaunchPath:"/bin/sh"
  
aTask’s setArguments:{"-c", current application’s NSString’s stringWithFormat_("%@", commandStr)}
  
aTask’s setStandardOutput:aPipe
  
set aFile to aPipe’s fileHandleForReading()
  
aTask’s |launch|()
  
return current application’s NSString’s alloc()’s initWithData:(aFile’s readDataToEndOfFile()) encoding:(current application’s NSUTF8StringEncoding)
end runCommandString

–stringのplistを読み込んでRecordに
on readPlistFromStr(theString)
  set aSource to current application’s NSString’s stringWithString:theString
  
set pListData to aSource’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aPlist to current application’s NSPropertyListSerialization’s propertyListFromData:pListData mutabilityOption:(current application’s NSPropertyListImmutable) |format|:(current application’s NSPropertyListFormat) errorDescription:(missing value)
  
return aPlist
end readPlistFromStr

★Click Here to Open This Script 

Posted in drive System XML | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

RSSをダウンロードしてparseする(XmlToDictKit)

Posted on 2月 7, 2018 by Takaaki Naganoya

–> XmlToDictKit.framework

AppleScript名:RSSをダウンロードしてparseする(XmlToDictKit)
— Created 2016-11-05 by Takaaki Naganoya
— 2016 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "XmlToDictKit" –https://github.com/nicklockwood/XMLDictionary

set aURL to current application’s |NSURL|’s alloc()’s initWithString:"http://piyocast.com/as/feed/"
set xmlString to current application’s NSString’s alloc()’s initWithContentsOfURL:aURL encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value)
if xmlString = missing value then return false
set xmlDoc to (current application’s NSDictionary’s dictionaryWithXMLString:xmlString)

set blogTitle to (xmlDoc’s valueForKeyPath:"channel.title") as string
–>  "AppleScirpt Hole"

–タイトル一覧を取得する
set titleList to (xmlDoc’s valueForKeyPath:"channel.item.title") as list
–>  {"XmlToDictKitでBlogのRSS情報を解析", "listのrecordをplistにserializeして、plistをde-serializeする", "Listのrecordをエンコーディングしてplist文字列にする", "serializeされたlistのrecordからKeynoteで新規ドキュメントを作成してグラフを作成", "system_profilerの結果のstringのplistをdictionaryにのコピー2", "XPathQuery4ObjCのじっけん2", "recordをXMLに v2", "XmlToDictKitでXMLをDictionaryに(remote file)", "XmlToDictKitでXMLをDictionaryに(local file)", "XMLをrecordにv2"}

–URL一覧を返す
set urlList to (xmlDoc’s valueForKeyPath:"channel.item.link") as list
–>  {"http://piyocast.com/as/archives/814", "http://piyocast.com/as/archives/812", "http://piyocast.com/as/archives/810", "http://piyocast.com/as/archives/805", "http://piyocast.com/as/archives/803", "http://piyocast.com/as/archives/799", "http://piyocast.com/as/archives/797", "http://piyocast.com/as/archives/792", "http://piyocast.com/as/archives/790", "http://piyocast.com/as/archives/788"}

–本文のプレビュー一覧
set descList to (xmlDoc’s valueForKeyPath:"channel.item.description") as list
(*
{"AppleScript名:XmlToDictKitでBlogのRSS情報を解析 &#8212; Created 2016-11-05 by Takaaki Naganoya&#8212; 2016 Piyomaru S &#8230; <a href=\"http://piyocast.com/as/archives/814\" class=\"more-link\"><span class=\"screen-reader-text\">\"XmlToDictKitでBlogのRSS情報を解析\"の</span>続きを読む</a>", ….
*)

–更新日時の一覧
set descList to (xmlDoc’s valueForKeyPath:"channel.item.pubDate") as list
–>  {"Wed, 07 Feb 2018 08:00:53 +0000", "Wed, 07 Feb 2018 07:58:06 +0000", "Wed, 07 Feb 2018 07:55:12 +0000", "Wed, 07 Feb 2018 07:50:07 +0000", "Wed, 07 Feb 2018 07:28:10 +0000", "Wed, 07 Feb 2018 07:23:45 +0000", "Wed, 07 Feb 2018 07:23:04 +0000", "Wed, 07 Feb 2018 07:20:21 +0000", "Wed, 07 Feb 2018 07:20:13 +0000", "Wed, 07 Feb 2018 07:11:33 +0000"}

★Click Here to Open This Script 

Posted in Record XML | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

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

Google Search

Popular posts

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

Tags

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

カテゴリー

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

アーカイブ

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

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

メタ情報

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

Forum Posts

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

メタ情報

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