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

月: 2018年7月

WordPressの指定IDの記事にリンクされているapplescriptからCocoa Classのproperty宣言を抽出

Posted on 7月 30, 2018 by Takaaki Naganoya

WordPressで稼働しているBlog(AppleScriptの穴)の、指定記事IDの本文を取得し、本文内でリンクしているURLのうち指定schemeのものを抽出し、URLリンクされているAppleScriptのソースをデコードしてproperty宣言文のうちCocoa Classの宣言を行っているものを抽出するAppleScriptです。

HTMLReader.frameworkを用いてBlog本文からのリンク抽出、リンクURL抽出を行っています。

–> HTMLReader.framework(To ~/Library/Frameworks/)

本Blogで、Tagの運用を変更しようと思い立ち、手作業で修正をはじめました。アプリケーション名のほかにCocoa Class名をTagにしようという試みです。

ただ、数個の記事のTag付け直しを行っただけで「手作業では終わらない」ことが判明。2月に再構築をはじめて1,000本ぐらいの記事をアップしているので、手作業ではとても無理です

本Blogの記事にURLリンクされているAppleScriptソースプログラムを(XML-RPC経由で)AppleScriptから自動で取得し、

その中のproperty宣言文を抽出して、

Cocoa Classの宣言文のみをリストアップして、

Blog記事のTagに自動で指定できないか、と試してみたものです。

現時点で、

  (1)指定Blog記事の本文を取得
  (2)(1)から指定URL SchemeのリンクURLを抽出
  (3)(2)のURL EncodeされているAppleScriptソースをDecode
  (4)property宣言文のみ抽出
  (5)property宣言ラベルがCocoa Classのものかをチェックして抽出

というところまでできています。本プログラムは、BlogのUser NameとPasswordが必要なので、リストのまま動かしてもエラーになり動作しません。同様にWordPressで運用されているBlogがあれば、そちらで試してみるのもよいでしょう。

XML-RPCでWordPressと通信するのには、記事アップロード自動化に使ったFrameworkもありますが、ためしにAppleScript標準搭載のcall xmlrpcコマンドを使ってみました。記事新規投稿コマンドだとクラッシュを起こしますが、この程度の用途ならクラッシュせずに使えるようです。

また、property文の抽出は構文要素を考慮していないため、コメントアウトされているものも拾ってくる可能性があります(単に行頭のproperty宣言文を拾っているだけなので、複数行コメントになっているものは拾われてくることでしょう)。

(*
property NSArray: a reference to current application’s NSArray
property NSString: a reference to current application’s NSString
*)

これを防ぐために、URLリンクされたAppleScriptをデコードした後で、いったんAppleScriptとして構文確認(コンパイル)を実施して、実際のAppleScriptとして評価すべきなのでしょう。

AppleScript名:WordPressの指定IDの記事にリンクされているapplescriptからCocoa Classのproperty宣言を抽出 v2
— Created 2018-07-30 by Takaaki Naganoya
— Modified 2018-07-31 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "HTMLReader" –https://github.com/nolanw/HTMLReader

property |NSURL| : a reference to current application’s |NSURL|
property NSString : a reference to current application’s NSString
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 NSMutableArray : a reference to current application’s NSMutableArray
property NSMutableDictionary : a reference to current application’s NSMutableDictionary
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding

–PostID
set postID to 3826
set aScheme to "applescript://"

–WordPressの指定Post IDの記事を取得してリンクされているURLからURL Schemeでフィルタして、リンクされているAppleScriptのソースを
–取得し、AS Sourceからproperty宣言文のみ抽出
set pList to getASSouceLinkedInWordPressPost(postID, aScheme) of me
–>  {"property NSBundle : a reference to current application’s NSBundle", "property |NSURL| : a reference to current application’s |NSURL|", "property HTMLDocument : a reference to current application’s HTMLDocument", "property NSMutableDictionary : a reference to current application’s NSMutableDictionary", "property NSPredicate : a reference to current application’s NSPredicate", "property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding", "property NSMutableSet : a reference to current application’s NSMutableSet", "property NSRegularExpressionSearch : a reference to current application’s NSRegularExpressionSearch", "property NSString : a reference to current application’s NSString", "property NSSortDescriptor : a reference to current application’s NSSortDescriptor"}

–property宣言文リストから、propetyがCocoa Classの宣言であるものだけを抽出
set p2List to filterPropertySentenseWhetherCocoaOrNot(pList) of me
–>  {"NSBundle", "HTMLDocument", "NSMutableDictionary", "NSPredicate", "NSMutableSet", "NSString", "NSSortDescriptor"}

on filterPropertySentenseWhetherCocoaOrNot(pList)
  set outList to {}
  
  
repeat with i in pList
    set j to contents of i
    
set j2 to repChar(j, "|", "") of me
    
    
–Parse String Into Words by Space
    
set aTmpStr to (NSString’s stringWithString:j2)
    
set wList to (aTmpStr’s componentsSeparatedByString:" ") as list
    
    
if wList contains {"a", "reference", "to", "current", "application’s"} then
      –通常のクラス名の場合(クラス名以外のpropertyの場合もある)
      
set aTarg to contents of item 2 of wList
      
      
–property値がCocoa Classかどうかを判定    
      
set fRes to searchClassInFrameworks(aTarg) of me
      
      
if fRes is not equal to false then
        set the end of outList to aTarg
      end if
    end if
  end repeat
  
  
return outList
end filterPropertySentenseWhetherCocoaOrNot

–指定クラスがいずれかのCocoa Frameworkに所属しているかを検索
on searchClassInFrameworks(aTarget)
  set aClass to current application’s NSClassFromString(aTarget)
  
if aClass = missing value then return false
  
set theComponenents to (NSBundle’s bundleForClass:aClass)’s bundleURL’s pathComponents()
  
set thePred to NSPredicate’s predicateWithFormat:"pathExtension == ’framework’"
  
set aRes to (theComponenents’s filteredArrayUsingPredicate:thePred)’s firstObject() as list of string or string
  
return aRes
end searchClassInFrameworks

–指定Post IDのWordPress記事から、指定SchemeのURLを抽出し、AS Sourceをdecodeしてproperty行のみ抽出
on getASSouceLinkedInWordPressPost(postID, aScheme)
  set {myUser, myPass} to getAcountData() of me
  
  
tell application "http://piyocast.com/as/xmlrpc.php"
    set wRes to (call xmlrpc {method name:"wp.getPost", parameters:{"1", myUser, myPass, postID as string}})
  end tell
  
set aBody to post_content of wRes –Blog本文
  
  
–記事中でリンクしているURLを取得し、指定のURL Schemeでフィルタする
  
set urlList to filterURLLinksByScheme(aBody, aScheme) of me
  
  
set propList to {}
  
  
repeat with i in urlList
    set j to contents of i
    
set urlRec to parseQueryDictFromURLString(j) of me
    
set tmpScript to (urlRec’s |script|) as string –Get AppleScript Source
    
    
set tList to paragraphs of tmpScript
    
set pList to filterListUsingPredicate(tList, "SELF BEGINSWITH[c] %@", "property") –後方一致
    
    
set propList to propList & pList
  end repeat
  
  
return propList
end getASSouceLinkedInWordPressPost

on filterListUsingPredicate(aList as list, aPredicateStr as string, targStr as string)
  set setKey to current application’s NSMutableSet’s setWithArray:aList
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat_(aPredicateStr, targStr)
  
set aRes to (setKey’s filteredSetUsingPredicate:aPredicate)
  
set bRes to aRes’s allObjects()
  
set cRes to bRes as {list, list of string or string}
  
return cRes
end filterListUsingPredicate

on parseQueryDictFromURLString(aURLStr as string)
  if aURLStr = "" then error "No URL String"
  
  
set aURL to |NSURL|’s URLWithString:aURLStr
  
set aQuery to aURL’s query() –Get Query string part from URL
  
if aQuery’s |length|() = 0 then return false
  
  
set aDict to NSMutableDictionary’s alloc()’s init()
  
set aParamList to (aQuery’s componentsSeparatedByString:"&") as list
  
  
repeat with i in aParamList
    set j to contents of i
    
if length of j > 0 then
      set tmpStr to (NSString’s stringWithString:j)
      
set eList to (tmpStr’s componentsSeparatedByString:"=")
      
set anElement to (eList’s firstObject()’s stringByReplacingPercentEscapesUsingEncoding:(NSUTF8StringEncoding))
      
set aValStr to (eList’s lastObject()’s stringByReplacingPercentEscapesUsingEncoding:(NSUTF8StringEncoding))
      (
aDict’s setObject:aValStr forKey:anElement)
    end if
  end repeat
  
  
return aDict
end parseQueryDictFromURLString

–指定のHTML文字列から、Link URLを抽出し、schemeで再抽出する
on filterURLLinksByScheme(aBody, aScheme)
  set conType to "text/html"
  
  
–HTML文字列をいったんNSDataにしているのは、HTMLReader.frameworkの仕様のため
  
set aData to (current application’s NSString’s stringWithString:aBody)’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aHTML to current application’s HTMLDocument’s documentWithData:aData contentTypeHeader:conType
  
  
set aTextArray to ((aHTML’s nodesMatchingSelector:"a")’s textContent) as list –リンク文字
  
set aLinkList to ((aHTML’s nodesMatchingSelector:"a")’s attributes’s valueForKeyPath:"href") as list –URL文字列
  
  
set outList to {}
  
repeat with i in aLinkList
    set j to contents of i
    
if j begins with aScheme then
      set the end of outList to j
    end if
  end repeat
  
  
return outList
end filterURLLinksByScheme

–文字置換
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

on getAcountData()
  return {"xxxxxxxx_xx", "XXXXXXXXXXXXXXXXXXXXXXXX"}
end getAcountData

★Click Here to Open This Script 

Posted in list Network Record URL XML-RPC | Tagged 10.11savvy 10.12savvy 10.13savvy NSArray NSBundle NSString NSURL | Leave a comment

Finder上で選択中の画像のうち、最小のものに合わせて各画像の左上を原点にサイズ統一

Posted on 7月 27, 2018 by Takaaki Naganoya

Finderで選択中の画像のうち、最小のものに合わせて各画像の左上を原点にサイズを統一するAppleScriptです。

Finderで選択中のファイルから画像のみ抽出し、そのうちサイズが最小のものに合わせて他の画像をトリミングし、変更したものをデスクトップフォルダに出力します。


▲大きさを揃える画像をFinder上で選択


▲処理前の画像。大きさがまちまち


▲処理後の画像。大きさが最小の画像に合わせてそろっている

スクリーンショット画像を複数撮った場合に、厳密に同じサイズに固定することは(各種スクリーンショット作成ユーティリティを使わないと)行いづらいところです。

そこで、最小の画像を計算で求めて、それに合わせて自動トリミングするようにしてみました。Cocoaの機能を用いて画像処理しているため、Photoshopは必要ありません。

最小の画像を求めるのに、幅+高さの値でソートして最小のものを求めています(widthとheightによる2 key sortではなく1 Keyで済ませたかったので)。

Blogや書籍用の掲載画面図の作成用、といったところでしょうか。Retina画面で撮ったスクリーンショットと非Retina画面のスクリーンショットが混在するとうまく動きません(スクリーンショット画像からはRetina環境で撮った画像であるかどうかを取得できません)。

スクリーンショットの画像からRetina/非Retina環境で撮ったかを判定するのは、(Retina対応機であるかをMachine IDから取得したあとで)Syslogにアクセスしてスクリーンが接続されたか、取り外されたかといった状態を追っていくしかないのかも。

本ScriptをmacOS 10.13.6上で動作確認して驚いたのですが、いままでRecordが返ってくるべき箇所でlistが返ってくる盛大なバグが直って、本ScriptがmacOS 10.13用に書き換えずに動きました(動かないことを確認しようとして動いたので驚いた)。

AppleScript名:Finder上で選択中の画像のうち、最小のものに合わせて各画像の左上を原点にサイズ統一 v2
— Created 2018-07-23 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "QuartzCore"

property |NSURL| : a reference to current application’s |NSURL|
property NSUUID : a reference to current application’s NSUUID
property NSArray : a reference to current application’s NSArray
property NSString : a reference to current application’s NSString
property NSImage : a reference to current application’s NSImage
property NSScreen : a reference to current application’s NSScreen
property NSZeroRect : a reference to current application’s NSZeroRect
property NSPredicate : a reference to current application’s NSPredicate
property NSPNGFileType : a reference to current application’s NSPNGFileType
property NSMutableArray : a reference to current application’s NSMutableArray
property NSCompositeCopy : a reference to current application’s NSCompositeCopy
property NSGraphicsContext : a reference to current application’s NSGraphicsContext
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep
property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey
property NSCalibratedRGBColorSpace : a reference to current application’s NSCalibratedRGBColorSpace

tell application "Finder"
  set selList to selection as alias list
end tell

–指定のAlias listのうち画像のみ抽出
set filRes1 to filterAliasListByUTI(selList, "public.image") of me
if filRes1 = {} then
  tell current application
    –Error Message (No Selection)
    
display dialog "Finder上で選択されているファイルはありません。" buttons {"OK"} default button 1 with icon 1 with title "画像リサイズ処理できません"
  end tell
  
return
end if

–各種情報を入れたArrayを作成
set anArray to NSMutableArray’s new()
repeat with i in selList
  set imgPath to (POSIX path of i)
  
  
set aImage to makeNSImageFromFile(i) of me
  
set sizeInfo to |size|() of aImage
  
set sizeInfo to sizeInfo & {aImg:aImage, total:(width of sizeInfo) + (height of sizeInfo), myPath:imgPath}
  (
anArray’s addObject:sizeInfo)
end repeat

–最小のサイズの画像の算出
set aRes to anArray’s valueForKeyPath:("@min.total")
set bRes to first item of (filterRecListByLabel(anArray, "total == " & aRes as string) of me) –最小サイズの画像

–最小サイズ画像のwidthとheight
set minWidth to bRes’s width
set minHeight to bRes’s height

–環境情報の取得
set aPath to POSIX path of (path to desktop)
set retinaF to (NSScreen’s mainScreen()’s backingScaleFactor()) as real
–>  2.0 (Retina) / 1.0 (Non Retina)

set cRes to filterRecListByLabel(anArray, "total != " & aRes as string) of me –最小サイズ以外の画像

repeat with i in cRes
  set j to contents of i
  
set anImage to aImg of j
  
set fRes to myPath of j
  
  
set cropedImage to (my cropNSImageBy:{0, 0, minWidth, minHeight} fromImage:anImage) –v1で間違っていた
  
  
–Retina環境対策
  
if retinaF > 1.0 then
    set cropedImage to (my resizedImage:cropedImage toScale:(1.0))
  end if
  
  
–ファイル書き込み
  
set fRes to retUUIDfilePathFromDir(aPath, "png") of me
  
set sRes to saveNSImageAtPathAsPNG(cropedImage, fRes) of me
end repeat

–リストに入れたレコードを、指定の属性ラベルの値で抽出
on filterRecListByLabel(aRecList as list, aPredicate as string)
  –ListからNSArrayへの型変換
  
set aArray to NSArray’s arrayWithArray:aRecList
  
  
–抽出
  
set aPredicate to NSPredicate’s predicateWithFormat:aPredicate
  
set filteredArray to aArray’s filteredArrayUsingPredicate:aPredicate
  
  
–NSArrayからListに型変換して返す
  
set bList to filteredArray as list
  
return bList
end filterRecListByLabel

–Alias listから指定UTIに含まれるものをPOSIX pathのリストで返す
on filterAliasListByUTI(aList, targUTI)
  set newList to {}
  
repeat with i in aList
    set j to POSIX path of i
    
set tmpUTI to my retUTIfromPath(j)
    
set utiRes to my filterUTIList({tmpUTI}, targUTI)
    
if utiRes is not equal to {} then
      set the end of newList to j
    end if
  end repeat
  
return newList
end filterAliasListByUTI

–指定のPOSIX pathのファイルのUTIを求める
on retUTIfromPath(aPOSIXPath)
  set aURL to |NSURL|’s fileURLWithPath:aPOSIXPath
  
set {theResult, theValue} to aURL’s getResourceValue:(reference) forKey:NSURLTypeIdentifierKey |error|:(missing value)
  
  
if theResult = true then
    return theValue as string
  else
    return theResult
  end if
end retUTIfromPath

–UTIリストが指定UTIに含まれているかどうか演算を行う
on filterUTIList(aUTIList, aUTIstr)
  set anArray to NSArray’s arrayWithArray:aUTIList
  
set aPred to NSPredicate’s predicateWithFormat_("SELF UTI-CONFORMS-TO %@", aUTIstr)
  
set bRes to (anArray’s filteredArrayUsingPredicate:aPred) as list
  
return bRes
end filterUTIList

on cropNSImageTo:{x1, y1, x2, y2} fromImage:theImage
  set newWidth to x2 – x1
  
set newHeight to y2 – y1
  
set theSize to (theImage’s |size|()) as record
  
set oldHeight to height of theSize
  
  
— transpose y value for Cocoa coordintates
  
set y1 to oldHeight – newHeight – y1
  
set newRect to {{x:x1, y:y1}, {width:newWidth, height:newHeight}}
  
theImage’s lockFocus()
  
set theRep to NSBitmapImageRep’s alloc()’s initWithFocusedViewRect:newRect
  
theImage’s unlockFocus()
  
  
set outImage to NSImage’s alloc()’s initWithSize:(theRep’s |size|())
  
outImage’s addRepresentation:theRep
  
  
return outImage
end cropNSImageTo:fromImage:

on makeNSImageFromFile(anAlias)
  set imgPath to (POSIX path of anAlias)
  
set aURL to (|NSURL|’s fileURLWithPath:(imgPath))
  
return (NSImage’s alloc()’s initWithContentsOfURL:aURL)
end makeNSImageFromFile

–NSImageを指定の大きさでトリミング
on cropNSImageBy:{x1, y1, newWidth, newHeight} fromImage:theImage
  set theSize to (theImage’s |size|()) as record
  
set oldHeight to height of theSize
  
  
— transpose y value for Cocoa coordintates
  
set y1 to oldHeight – newHeight – y1
  
set newRect to {{x:x1, y:y1}, {width:newWidth, height:newHeight}}
  
theImage’s lockFocus()
  
set theRep to NSBitmapImageRep’s alloc()’s initWithFocusedViewRect:newRect
  
theImage’s unlockFocus()
  
  
set outImage to NSImage’s alloc()’s initWithSize:(theRep’s |size|())
  
outImage’s addRepresentation:theRep
  
  
return outImage
end cropNSImageBy:fromImage:

on retUUIDfilePathFromDir(aPath, aEXT)
  set aUUIDstr to (NSUUID’s UUID()’s UUIDString()) as string
  
set aPath to ((NSString’s stringWithString:aPath)’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:aEXT
  
return aPath
end retUUIDfilePathFromDir

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to NSBitmapImageRep’s imageRepWithData:imageRep
  
set pathString to NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
set myNewImageData to (aRawimg’s representationUsingType:(NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –true/false
end saveNSImageAtPathAsPNG

on resizedImage:aSourceImg toScale:imgScale
  if (aSourceImg’s isValid()) as boolean = false then error "Invalid NSImage"
  
  
set aSize to aSourceImg’s |size|()
  
–>  {​​​​​width:32.0, ​​​​​height:32.0​​​}
  
  
set aWidth to (aSize’s width) * imgScale
  
set aHeight to (aSize’s height) * imgScale
  
  
set aRep to NSBitmapImageRep’s alloc()’s initWithBitmapDataPlanes:(missing value) pixelsWide:aWidth pixelsHigh:aHeight bitsPerSample:8 samplesPerPixel:4 hasAlpha:true isPlanar:false colorSpaceName:(NSCalibratedRGBColorSpace) bytesPerRow:0 bitsPerPixel:0
  
  
set newSize to {width:aWidth, height:aHeight}
  
aRep’s setSize:newSize
  
  
NSGraphicsContext’s saveGraphicsState()
  
NSGraphicsContext’s setCurrentContext:(NSGraphicsContext’s graphicsContextWithBitmapImageRep:aRep)
  
  
aSourceImg’s drawInRect:(current application’s NSMakeRect(0, 0, aWidth, aHeight)) fromRect:(NSZeroRect) operation:(NSCompositeCopy) fraction:(1.0)
  
  
NSGraphicsContext’s restoreGraphicsState()
  
  
set newImg to NSImage’s alloc()’s initWithSize:newSize
  
newImg’s addRepresentation:aRep
  
  
return newImg
end resizedImage:toScale:

★Click Here to Open This Script 

Posted in file Image | Tagged 10.11savvy 10.12savvy 10.13savvy Finder NSArray NSBitmapImageRep NSImage NSMutableArray NSPredicate NSScreen NSString NSURL NSUUID | 1 Comment

先頭からn個目までのターゲット文字を個別置換

Posted on 7月 25, 2018 by Takaaki Naganoya

置換ターゲット文字が複数存在する場合に、先頭からn個目までの置換ターゲットを個別に文字指定して置換するAppleScriptです。


▲行頭のスペースは削除(ヌル文字列に置換)、2個目のスペースはtabに置換したい


▲置換ずみ

Cocoaの機能を使って(作りためたサブルーチンを流用して)書いてみたら、トンでもなく長くなってしまったので、あらためてOLD Style AppleScriptの機能範囲だけでコンパクトに書き直したものです。

このぐらいの(↑)のどかな分量のデータに対してシーケンシャルに(文字を1文字ずつ取り出して比較&置換)処理を行うものなので、高速化などは一切考慮していません。大規模データにはまったく別のアプローチを行うことをおすすめします。

AppleScript名:先頭からn個目までのターゲット文字を個別指定した文字に置換
— Created 2018-07-23 by Takaaki Naganoya
— 2018 Piyomaru Software
— This script runs on OS X 10.10 or later
use scripting additions
use framework "Foundation"

set origStr to " aaaaa bbbb cccccc dddddd"
set repTarget to " "
set repList to {"", tab} –1個めのスペースは削除、2個めのスペースはtabに置換
set rStr to repLimitedOrderStrByList(origStr, repTarget, repList) of me

on repLimitedOrderStrByList(allText as string, targChar as string, repList)
  set repParam to length of repList
  
set itemCounter to 1
  
set outStr to ""
  
  
set bList to characters of allText
  
  
repeat with ii in bList
    set jj to contents of ii
    
if jj = targChar then
      
      
if repParam > 0 then
        set aRepStr to contents of item itemCounter of repList
        
set outStr to outStr & aRepStr
        
set repParam to repParam – 1
        
set itemCounter to itemCounter + 1
      else
        set outStr to outStr & jj
      end if
      
    else
      set outStr to outStr & jj
    end if
  end repeat
  
  
return outStr
end repLimitedOrderStrByList

★Click Here to Open This Script 

Posted in Text | Leave a comment

AppleScriptイベント「Think AppleScript」(仮称)を開催します

Posted on 7月 23, 2018 by Takaaki Naganoya

MOSAとの共催により、AppleScriptに関するイベント、「Think AppleScript」(仮称)を開催する予定です。

MOSA+Piyomaru Software共催
AppleScriptイベント「Think AppleScript」(仮称)

開催日時:2018年9月26日(水)19:00〜22:00(予定)
開催場所(予定):池袋Open Office FOREST
東京都豊島区東池袋3-7-9 AS ONE 東池袋ビル3階
参加費用:3階受付にて、個別にナイトドロップイン(1.000円)のチケットをご購入ください

・AppleScriptについてのイベントです。情報共有、質疑応答などを目的とします
・AppleScriptの歴史と位置づけ、拡大する利用範囲についてのご紹介
・海外の動向などのご紹介
・事例紹介など
・来場者からの質問をみんなで考える「Q&A」
・AppleScriptに関するものであれば、著作、Blog、製品、導入事例などどんどん紹介してください! 大歓迎です!(事前に言っていただければ時間枠など最大限配慮いたします。すでに知り合い筋に事例の発表を依頼しています)
→ ただし、出席者からの内容についての質問は可能なかぎりお答えください

受付フォームについてはconnpass上に作成いたします(まだ間に合っていません)。

定期的に(3か月に一度ぐらい?)開催できるといいですね、、、、

Posted in イベント(Event) | Leave a comment

note.muで指定のユーザーのノートを取得する

Posted on 7月 22, 2018 by Takaaki Naganoya

note.muの非公開REST API(でも、みんな知っている)を呼び出して、指定ユーザーのノート(投稿記事)を取得するAppleScriptです。

使い慣れたNSURLConnectionがmacOS 10.11で非推奨APIになって久しく、頻繁に使っているREST API呼び出し処理がいきなり動かなくなるのは困るため、NSURLSessionを用いてREST APIを呼び出すよう徐々に変更しています。

当初、REST APIの呼び出し部分は共通ルーチン化して、さまざまなREST APIを共通ルーチンで処理できるとよいだろうかと思っていました。実際にさまざまなREST APIを呼び出してみると、APIごとに意外なほど癖があって、なかなか「すべてのREST APIの共通処理ルーチン」というところまで共通化する段階までには至っていないところ。

左がNSURLSessionを用いた呼び出し、右がNSURLConnectionを用いた呼び出しを行なったものです。せっかくNSURLSessionを使ってみてはいるものの、同一の処理でもNSURLConnectionの方が40%ぐらい高速です。同一ネットワーク環境(iPhone経由のテザリング接続)でNSURLConnectionが0.4秒ぐらい、NSURLSessionでだいたい0.5から0.7秒といったところ。有線ネットワーク接続だともう少し速度が改善するかもしれません。

NSURLSessionに明示的な同期処理が存在しないため、NSURLSessionが受けわたすdelegateイベントをAppleScript側でループしつつ待っており、NSURLConnectionで素直に同期処理メソッドを呼び出すよりもオーバーヘッドが大きくなっているものと推測しています。

NSURLSessionでREST APIを呼び出すあたりの処理をまるごと独立したFrameworkにでも追い出すとよいのではないか、といったところです。

AppleScript名:(GET)指定のユーザーのノート v2
— Created 2018-06-16 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

property |NSURL| : a reference to current application’s |NSURL|
property NSString : a reference to current application’s NSString
property NSURLSession : a reference to current application’s NSURLSession
property NSJSONSerialization : a reference to current application’s NSJSONSerialization
property NSMutableURLRequest : a reference to current application’s NSMutableURLRequest
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding
property NSURLSessionConfiguration : a reference to current application’s NSURLSessionConfiguration

property retData : missing value

set retData to missing value

set reqURLStr to "https://note.mu/api/v1/notes"
set aRec to {urlname:"140software"} –note ID
set aURL to retURLwithParams(reqURLStr, aRec) of me

set aRESTres to callRestGETAPIAndParseResults(aURL) of me

on callRestGETAPIAndParseResults(reqURLStr)
  set aURL to |NSURL|’s URLWithString:reqURLStr
  
set aRequest to NSMutableURLRequest’s requestWithURL:aURL
  
aRequest’s setHTTPMethod:"GET"
  
aRequest’s setTimeoutInterval:10
  
aRequest’s setValue:"gzip" forHTTPHeaderField:"Content-Encoding"
  
aRequest’s setValue:"application/json; charset=UTF-8" forHTTPHeaderField:"Content-Type"
  
  
set aConfig to NSURLSessionConfiguration’s defaultSessionConfiguration()
  
set aSession to NSURLSession’s sessionWithConfiguration:aConfig delegate:(me) delegateQueue:(missing value)
  
set aTask to aSession’s dataTaskWithRequest:aRequest
  
  
aTask’s resume() –Start URL Session
  
  
repeat 10000 times
    if retData is not equal to missing value then exit repeat
    
current application’s NSThread’s sleepForTimeInterval:("0.001" as real) –delay 0.001
  end repeat
  
  
retData
end callRestGETAPIAndParseResults

on URLSession:tmpSession dataTask:tmpTask didReceiveData:tmpData
  set aStat to (tmpTask’s state()) as list of string or string
  
  
set resStr to NSString’s alloc()’s initWithData:tmpData encoding:(NSUTF8StringEncoding)
  
set jsonString to NSString’s stringWithString:(resStr)
  
  
set jsonData to jsonString’s dataUsingEncoding:(NSUTF8StringEncoding)
  
set aJsonDict to NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
  
set retData to aJsonDict as list of string or string
end URLSession:dataTask:didReceiveData:

on retURLwithParams(aBaseURL, aRec)
  set aDic to current application’s NSMutableDictionary’s dictionaryWithDictionary:aRec
  
set aKeyList to (aDic’s allKeys()) as list
  
set aValList to (aDic’s allValues()) as list
  
set aLen to length of aKeyList
  
  
set qList to {}
  
repeat with i from 1 to aLen
    set aName to contents of item i of aKeyList
    
set aVal to contents of item i of aValList
    
set the end of qList to (current application’s NSURLQueryItem’s queryItemWithName:aName value:aVal)
  end repeat
  
  
set aComp to current application’s NSURLComponents’s alloc()’s initWithString:aBaseURL
  
aComp’s setQueryItems:qList
  
set aURL to (aComp’s |URL|()’s absoluteString()) as text
  
  
return aURL
end retURLwithParams

★Click Here to Open This Script 

Posted in JSON list REST API URL | Tagged 10.11savvy 10.12savvy 10.13savvy NSJSONSerialization NSMutableURLRequest NSString NSURL NSURLSession NSURLSessionConfiguration NSUTF8StringEncoding | 1 Comment

色付き単色画像を作成する(自由色指定&色名推定)

Posted on 7月 17, 2018 by Takaaki Naganoya

指定画像を任意の色で単色化し、指定色名をファイル名に反映させてファイル出力するAppleScriptです。

もとは、「色付き単色画像を作成する」AppleScriptに、

 ・choose colorによるユーザー選択色を反映
 ・choose colorで指定した色のざっくりとした色名検出

などの機能をつなぎ合わせたものです。

日本地図の白地図からカラーバリエーション画像を出力する際に作成しました。線が黒で書かれている白地図(白地図というのはそういうものですが)から、さまざまな色のバリエーションを作成。その際に、どのような色を指定したかをファイル名に反映させておいたほうが便利だったので、そのようにしてみました。

GPUImage.frameworkを利用しています。

–> GPUImage.framework (To ~/Library/Frameworks/)

色名推定のロジックもけっこうしっくりきていますが、明度も反映して、明るいものは「light-」、暗いものは「dark-」と出力させてもいいような気がします。ただし、「dark-orange」はBrownのことですし、ほかにも色名を別途振り直したほうがいいパターンもあるように思われます。

AppleScript名:色付き単色画像を作成する(自由色指定&色名推定)
— Created 2017-02-11 by Takaaki Naganoya
— Modified 2018-07-15 by Takaaki Naganoya
— 2017-2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "GPUImage" –https://github.com/BradLarson/GPUImage

property NSUUID : a reference to current application’s NSUUID
property NSColor : a reference to current application’s NSColor
property NSString : a reference to current application’s NSString
property NSImage : a reference to current application’s NSImage
property NSBezierPath : a reference to current application’s NSBezierPath
property NSPNGFileType : a reference to current application’s NSPNGFileType
property GPUImagePicture : a reference to current application’s GPUImagePicture
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep

–Select Image File
set aFile to POSIX path of (choose file of type {"public.image"} with prompt "Select image")

–Select Color
set {rCol, gCol, bCol} to choose color

set fillColorR to makeNSColorFromRGBAval(rCol, gCol, bCol, 65535, 65535) of me
set fillColorRName to retColorDomainNameFromNSColor(fillColorR) of me –だいたいの色名称を計算

set imgRes to makeMonoColoredImage(aFile, fillColorR) of me
set fRes to retUUIDandKeyfilePath(aFile, fillColorRName, "png") of me
set bRes to saveNSImageAtPathAsPNG(imgRes, fRes) of me

— return "UUID_aKey.aEXT" full path
on retUUIDandKeyfilePath(aPath, aKey, aEXT)
  set aUUIDstr to ((NSUUID’s UUID()’s UUIDString()) as string) & "_" & aKey
  
set aPath to ((NSString’s stringWithString:aPath)’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:aEXT
  
return aPath
end retUUIDandKeyfilePath

on makeMonoColoredImage(aFile, NScolorObj)
  set aImage to NSImage’s alloc()’s initWithContentsOfFile:aFile
  
return makeColoredNSImageWithColor(aImage, NScolorObj) of me –色付き単色画像を作成する
end makeMonoColoredImage

on makeColoredNSImageWithColor(aImage, fillColor)
  set aSize to aImage’s |size|()
  
set aWidth to width of aSize
  
set aHeight to height of aSize
  
set newNSImage to makeNSImageWithFilledWithColor(aWidth, aHeight, fillColor)
  
set grayImage to filterWithNSImage(aImage, "GPUImageGrayscaleFilter") of me
  
set compImage to composeImageWithBlendFilter(grayImage, newNSImage, "GPUImageScreenBlendFilter") of me
  
return compImage
end makeColoredNSImageWithColor

on filterWithNSImage(aNSImage, filterName as string)
  set aClass to current application’s NSClassFromString(filterName)
  
set aImageFilter to aClass’s alloc()’s init()
  
set aProcImg to (aImageFilter’s imageByFilteringImage:aNSImage)
  
return aProcImg
end filterWithNSImage

on composeImageWithBlendFilter(aImage, bImage, filterName)
  set aClass to current application’s NSClassFromString(filterName)
  
set blendFilter to aClass’s alloc()’s init()
  
set pictureA to GPUImagePicture’s alloc()’s initWithImage:aImage
  
pictureA’s addTarget:blendFilter
  
pictureA’s processImage()
  
set imgRes to blendFilter’s imageByFilteringImage:bImage
  
return imgRes
end composeImageWithBlendFilter

–指定サイズの画像を作成し、指定色で塗ってNSImageで返す
on makeNSImageWithFilledWithColor(aWidth, aHeight, fillColor)
  –Imageの作成  
  
set curSize to current application’s NSMakeSize(aWidth, aHeight)
  
set anImage to NSImage’s alloc()’s initWithSize:curSize
  
  
anImage’s lockFocus() –描画開始
  
  
set theRect to {{x:0, y:0}, {height:aHeight, width:aWidth}}
  
set theNSBezierPath to NSBezierPath’s bezierPath
  
theNSBezierPath’s appendBezierPathWithRect:theRect
  
  
fillColor’s |set|() –色設定
  
theNSBezierPath’s fill() –ぬりつぶし
  
  
anImage’s unlockFocus() –描画ここまで
  
  
–生成した画像のRaw画像を作成
  
set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to NSBitmapImageRep’s imageRepWithData:imageRep
  
  
set newImg to NSImage’s alloc()’s initWithSize:curSize
  
newImg’s addRepresentation:aRawimg
  
return newImg
end makeNSImageWithFilledWithColor

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to NSBitmapImageRep’s imageRepWithData:imageRep
  
set pathString to NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
set myNewImageData to (aRawimg’s representationUsingType:(NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –true/false
end saveNSImageAtPathAsPNG

–NSColor(内容はRGBAカラー)からだいたいの色名を推測
on retColorDomainNameFromNSColor(aCol)
  set hueVal to aCol’s hueComponent()
  
set satVal to aCol’s saturationComponent()
  
set brightVal to aCol’s brightnessComponent()
  
  
if satVal ≤ 0.01 then set satVal to 0.0
  
  
set colName to ""
  
  
if satVal = 0.0 then
    if brightVal ≤ 0.2 then
      set colName to "black"
    else if (brightVal > 0.95) then
      set colName to "white"
    else
      set colName to "gray"
    end if
  else
    if hueVal ≤ (15.0 / 360) or hueVal ≥ (330 / 360) then
      set colName to "red"
    else if hueVal ≤ (45.0 / 360) then
      set colName to "orange"
    else if hueVal < (70.0 / 360) then
      set colName to "yellow"
    else if hueVal < (150.0 / 360) then
      set colName to "green"
    else if hueVal < (190.0 / 360) then
      set colName to "green(cyan)"
    else if (hueVal < 250.0 / 360.0) then
      set colName to "blue"
    else if (hueVal < 290.0 / 360.0) then
      set colName to "purple"
    else
      set colName to "red(magenta)"
    end if
  end if
  
  
return colName
end retColorDomainNameFromNSColor

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

★Click Here to Open This Script 

Posted in Color file Image | Tagged 10.11savvy 10.12savvy 10.13savvy NSBezierPath NSBitmapImageRep NSColor NSImage NSString NSUUID | Leave a comment

Blogアーカイブ本 vol.2を販売開始

Posted on 7月 16, 2018 by Takaaki Naganoya

ごく一部の愛読者の皆様からのご要望を受け、2018年1月のBlog消滅以前の内容を1年ごとにまとめた「Blogアーカイブ本」のVol.2を販売開始しました。Vol.2は2009年1〜12月の内容をまとめています。全367ページ、2,000円。ファイル形式はPDFで、キーワードによる全文検索や印刷が行えます。

→ オンライン販売ページ
→ お試し版ダウンロードページ

XcodeプロジェクトのダウンロードリンクやYouTubeのムービーへのリンクもきちんと反映し直しています。

続刊のボリューム感については、(最低でも)こんな感じです。

 vol.3:2010/1〜12(仮組みページ数:247)
 vol.4:2011/1〜2012/12(仮組みページ数:372)
 vol.5:2013/1〜2014/12(仮組みページ数:276)
 vol.6:2015/1〜12(仮組みページ数:320)

■Vol.2 掲載AppleScript(全184本)

Photoで特定のアルバムに入っている写真の枚数をカウントする
iPhotoで写真のファイル名に合致する写真を取得する
iPhotoで、複数名称による写真指定を行う例(できない)
Numbersでオープン中のドキュメントを数える
Numbersでウィンドウを数える(動作がおかしい)
Numbersでウィンドウの情報を取得する
Numbersのアプリケーションのプロパティを取得する
Numbersで書類を保存する
pdfinfoを使ってPDFのページ数をかぞえる
Numbersで統合された選択セルを元にもどす
CaminoでWindow 1の情報を取得する
Caminoで新規ウインドウで指定URLをオープン
CaminoでBookmarkを操作するテスト(駄目)
変数やサブルーチン名称に日本語を使用する
QuickTime Playerがバージョン7.6にアップデート
Xcodeでオープン中のプロジェクトで、ビルドターゲット「deployment」を使用してクリーニング実行後、ビルドを行う
入れ子のリストをフラット化v01
入れ子のリストをフラット化v02
入れ子のリストをフラット化v03
指定階層下で、指定クリエータコードのファイルを取得
SkimでPDFの各種情報を取得する
Skimで注釈(note)を削除する
Numbersで選択範囲を取得
Nunbersで選択範囲の値を取得
Numbersで指定範囲を選択
Preview.appで最低限のScript命令実行機能をイネーブルに
Excel 2008でX軸方向に右端から、データが存在しているセルをサーチ
GUI Scriptingによる記述(1)
Shade 10でレンダリングを行う
GUI Scriptingによる記述(2)
GUI Scriptingによる記述(3)
pdfinfoの結果をparseするv2
Shade 10でドキュメントを保存する
Shade 10で新規ドキュメントを作成
Shade 10でsceneをDXF形式で書き出す
リスト中で重複を検出する(大文字小文字を同一視)
Font Bookで指定フォントのファイルがどこに置かれているかを検知する
diskutilitiesで起動HDDのユーザー権限修復
Font Bookで指定typefaceの詳細な情報を取得する
アプリケーションに命令を行う記述方法で最短のもの
Safariのダウンロードフォルダを求めるv1
Safariのダウンロードフォルダを求めるv2
Safariのダウンロードフォルダを求めるv3
Safariのダウンロードフォルダを求めるv4
アドレスブックで表示中のPersonに画像をTIFF変換して読み込み
アプレットをコピーしてリネーム v2
指定文字列ではじまるプロセスをすべて終了させる
指定ファイルがバンドル形式のアプレットかどうかチェック
ソート用のカラムを生成する
複数リストの合成
version テスト
指定名称のプログラムを強制終了させる
数値を「時間」「分」でフォーマットしたテキストで返す
MacJournalでアプリのプロパティを取得
MacJournalで書類のプロパティを取得
MacJournalでキーワード検索状態を解除
MacJournalで選択中のjournal entryを取得する
MacJournalでjournalを選択UIを表示しつつ表示
MacJournalで任意のjournalをロックする(未遂)
国民の祝日を求めるv2
リスト中から重複項目をリストアップする
現在日時から曜日を番号で返す
リスト内のアイテムへの項目追加
contains/is inによる存在確認は、入れ子のリストに使えない
Photoshop Elements 6のAS辞書はPhotoshop CS3と同じ
入れ子のリスト内のis in/containsによる存在確認
某氏のtwitter上の発言を集めてテキスト化
twitter検索結果のJSONをparseする
6/13にTMUGのMeetingで新作「Moving Agency」をデモ
FireFoxでオープン中のURLを取得する
FireFoxでオープンしているURLを取得。Leopard対応版
郵便専門ネットでバージョン番号を取得
郵便専門ネットでXML-RPC経由でJISコード(5桁、6桁どちらでも)から、その市区町村に属している郵便番号のリストを取得
郵便専門ネットで道府県のコード(地方公共団体コードの先頭2文字)から都道府県名を返す
郵便専門ネットでXML-RPC経由で郵便番号に対応する世界測地系(WGS84)の緯度経度コード(Geocode)を返す
郵便専門ネットで一度に取得できるデータ件数を返す
郵便専門ネットでXML-RPC経由で引数に都道府県のJISコード(JISコードの先頭2文字)を渡すと、その都道府県に属しているJISコードを取得
郵便専門ネットでXML-RPC経由で郵便番号から住所を返す
郵便専門ネットで郵便番号の存在チェック
郵便専門ネットで引数に指定した郵便番号で何件ヒットするのかをint型で返す
郵便専門ネットでXML-RPC経由で郵便番号を6桁(チェックデジット付き)の全国地方公共団体コード/JISコード/市町村コードに変換
WordPress.comが受け取るXML-RPCのメソッド名一覧を取得する
ファイルの安全な書き出し
AppleScript Studioを念頭に置いたライブラリ整備
WordPressのBlogに画像ファイルをアップロード
Safariで表示中のページ内容をMacJournalの現在選択中のJournalにペースト
Diary++Xでアプリの情報を取得
Diary++Xでドキュメントの情報を取得
Diary++Xで指定カテゴリ内のアーティクルを取得する
XcodeでクリーニングしてビルドしてZip圧縮
指定月の第x指定曜日に該当する日付を求める(曜日数値指定対応)
国民の祝日を求める v4
指定年月の祝日の日を数値のリストで返す
Twitterrifficで選択中の発言の時間をGrowlで表示。アイコン付きで
URL Access Scriptingにファイル名の32文字制限が
Twitterifficで選択中の発言の時間をGrowlで表示。アイコン付きで v3
AppleScriptで開発を行うユーザーアカウントにATOKは禁物
Google Chrome BetaがAppleScriptに非対応
国民の祝日を求め__指定期間に該当するものを返す
もんのすごいざっくりな元号計算ルーチン
指定月のうち、日曜日に該当するものを日付だけ返す
1年間の各週の開始日と終了日を求める(月曜日はじまりカレンダー)
ファイル名文字列から拡張子のみ取得する
日曜日はじまりのカレンダーで指定月が何週分あるか行数を数える
指定年の各月の開始日と終了日を算出する
指定フォルダ内の指定種別(kind)のファイル一覧を取得
指定アプリケーションのAppleScript予約語をリストアップ
メールの返信文1行目のテキストからメールアドレスを抽出する v1
メールの返信文1行目のテキストからメールアドレスを抽出する v2
メールアドレスチェック
Snow Leoaprdでスクリプトエディタが「AppleScriptエディタ」に
Snow LeoaprdのAppleScriptに関するリリースノート
Snow LeopardのAppleScriptに関するリリースノート(2)
指定フォルダ内の指定種別(kind)のファイル一覧を取得
指定アプリケーションのAppleScript予約語をリストアップ
メールの返信文1行目のテキストからメールアドレスを抽出する v1
メールの返信文1行目のテキストからメールアドレスを抽出する v2
メールアドレスチェック
Snow Leoaprdでスクリプトエディタが「AppleScriptエディタ」に
Snow LeoaprdのAppleScriptに関するリリースノート
Snow LeopardのAppleScriptに関するリリースノート(2)
リスト中の要素の存在確認(10.6以降)
10.6でtext item delimitersがリストで指定可能に
QuickTime PlayerのXと7を区別して命令を発行する
Diary++Xで最近の日記本文をもとに今日の日記を新規作成する
Diary++Xで最近の日記本文をもとに今日の日記を新規作成する v2
9/19にホスティングサービス側の都合で5分間ダウン
Diary++Xで最近の日記本文をもとに今日の日記を新規作成する v3
Sin Cos演算ルーチン
AppleScriptObjCのドキュメント公開が開始される
リスト中の要素の存在確認(10.6以降)
10.6でtext item delimitersがリストで指定可能に
QuickTime PlayerのXと7を区別して命令を発行する
Diary++Xで最近の日記本文をもとに今日の日記を新規作成する
Diary++Xで最近の日記本文をもとに今日の日記を新規作成する v2
9/19にホスティングサービス側の都合で5分間ダウン
Diary++Xで最近の日記本文をもとに今日の日記を新規作成する v3
Sin Cos演算ルーチン
AppleScriptObjCのドキュメント公開が開始される
Mail.appの指定メールボックス内に任意のメールボックスを新規作成 v2
テキストによるプログレスインジケータ作成 v2
LateNight SoftwareのMark Alldrittが自社製OSAXの64ビット非対応について言及
whoseによるフィルタ参照
Cyberduck 3.3b4がAppleScriptに非対応
全角文字から半角文字への置換
System EventsでDockの設定を取得、変更する
Diary++X v1.1以降で日付を指定して日記アーティクルを作成
Xcode 3.2.1でAS用語辞書が大幅拡充
URL形式の文字エスケープを行う
リスト中に入っている指定要素をサーチして、合致した出現アイテム番号を返す
指定文字列の中に特定の文字が何回出現するかをカウントして返す
InDesign CS3のuser interaction levelを取得、設定する
テキスト中の任意の順番の文字取り出し Mac OS X 10.4.11への対応
Xcode 3.2.1でアプリケーションの情報を取得する
Xcode 3.2.1でプロジェクトの属性情報を取得する
10.5以降でRemote AppleEvent操作時にdisplay dialog等を使えない
AppleScriptの文字列比較(1)
AppleScriptの文字列比較(2)~considering, ignoring
AppleScriptの文字列比較(3)~濁点/半濁点の考慮/無視指定
AppleScriptの文字列比較(4)~日本語の大文字/小文字
AppleScriptの文字列比較(5)~句読点の考慮/無視
等号つき不等号の同義語
System EventsでScreen Saverの設定にアクセスする
Web共有がオンになっているかどうかを検出する
AppleScriptObjC-Dev MLが新設された
System Events経由でQuickTimeムービーにアクセスする2
System Events経由でQuickTimeムービーのannotationにアクセスする
擬似的にPropertyファイルを使ってカウントアップ
cyberduckでファイルのアップロード
AppleScriptObjc 3分間クッキング
指定の大きさでカラのリストを作成する
クリップボードに入っている情報の改行を外してクリップボードに書き戻す
PlistファイルをParseして返す
選択したアプリケーションのInfo.plistを読んで、実行バイナリの名称を取得する
オブジェクトの複数同時指定
指定フォルダ中のファイルを消してフォルダだけ残す
指定フォルダの中のフォルダをオープン
Excel選択範囲から各種文字列長のデータをピックアップ v6
Photoshop CS3で指定エリアを切り出して新規保存
指定値を構成するペアの全パターンのリストを求める
連続する文字(たぶんスペース)を1つにまとめる
指定文字列の中に指定文字が何回出現するかカウントする
伏せ字文字列を返す
指定日に在任中の内閣総理大臣の氏名を取得 v2

Posted in 未分類 | Leave a comment

日本測地系から世界測地系への座標変換

Posted on 7月 14, 2018 by Takaaki Naganoya

日本測地系の緯度・経度情報から世界測地系の緯度・経度情報に変換するAppleScriptです。

AppleScriptに35種類の関数計算機能を付加する「calcLibAS」の計算精度を確認するための実例でもあります。だいたい期待の精度は出せている感じです。

より精度を求められるような用途には、AppleScriptの数値変数自体が浮動小数点演算で10桁の計算精度しかないので、数値計算自体を外部にすべて出してしまうか、より精度の高い変数型を作ってしまうか(文字列で扱うようにすれば問題なさそう)というところでしょうか。

「日本測地系から世界測地系への座標変換(近似式)」のほうはObjective-Cから、「日本測地系から世界測地系への直行座標変換」のほうはRubyからAppleScriptに書き換えてみたものです。

Rubyのプログラムが割と単調だったので、読んでいて疲れてしまいました。変数名の付け方が途中で変わっているのは、「とりあえず動けばいい」ぐらいで組んでいたのと、変数名にいちいち「Local」とか付けるのに疲れたからです。

Piyomaru Script Assistantで変数名のみ一括置換してもいいわけですが、それはそれ、、、

AppleScript名:日本測地系から世界測地系への座標変換(近似式)
— Created 2018-07-13 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set jpLat to 42.16593046887
set jpLng to 142.771877437246
set {wdLat, wdLng, wdH} to tky2wgsLinea(jpLat, jpLng, 0) of me –日本測地系から世界測地系に換算
–>  {​​​​​42.168515890674, ​​​​​142.768119997121, ​​​​​0​​​}

set {latJ, lonJ, heightJ} to wgs2tkyLinea(wdLat, wdLng, wdH) of me –世界測地系から日本測地系に換算
–>  {​​​​​42.16593052955, ​​​​​142.77187743437, ​​​​​0​​​}

–日本測地系から世界測地系に換算
–http://d.hatena.ne.jp/iRSS/20111112/1321113232
on tky2wgsLinea(latJ, lonJ, heightJ)
  set heightW to heightJ
  
set lonW to lonJ – latJ * 4.6038E-5 – lonJ * 8.3043E-5 + 0.01004
  
set latW to latJ – latJ * 1.0695E-4 + lonJ * 1.7464E-5 + 0.0046017
  
return {latW, lonW, heightW}
end tky2wgsLinea

–世界測地系から日本測地系に換算
–https://altarf.net/computer/技術的なポエム/3332
on wgs2tkyLinea(latW, lonW, heightW)
  set heightJ to heightW
  
set latJ to (latW * 1.000106961) – (lonW * 1.7467E-5) – 0.004602017
  
set lonJ to (lonW * 1.000083049) + (latW * 4.6047E-5) – 0.010041046
  
return {latJ, lonJ, heightJ}
end wgs2tkyLinea

★Click Here to Open This Script 

AppleScript名:日本測地系から世界測地系への直行座標変換
— Created 2018-07-13 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use math : script "calcLibAS" –http://piyocast.com/as/archives/3523

set jpLat to 42.16593046887
set jpLng to 142.771877437246

set {wdLat, wdLng, wdH} to JapanGeodeticSystem’s convertIntoWgs(jpLat, jpLng)
–>  {​​​​​42.168504277889, ​​​​​142.768075650137, ​​​​​61.914452206343​​​}

–https://altarf.net/computer/ruby/3347
–日本測地系から世界測地系に換算
script JapanGeodeticSystem
  –ラジアン(度)
  
property rdNum : pi / 180
  
  
–日本測地系の定数(ベッセル楕円体)
  
property rJP : 6.377397155E+6 –赤道半径
  
property fJP : 1 / 299.1528128 –扁平率
  
property e2JP : (2 * fJP) – (fJP * fJP) –第一離心率
  
  
–世界測地系の定数(WGS84)
  
property rWS : 6.378137E+6 –赤道半径
  
property fWS : 1 / 298.257223563 –扁平率
  
property e2WS : (2 * fWS) – (fWS * fWS) –第一離心率
  
  
–並行移動量(m)
  
property dxNum : -148
  
property dyNum : 507.0
  
property dzNum : 681.0
  
  
–楕円体高
  
property heightNum : 0
  
  
  
–日本測地系から世界測地系に変換する
  
on convertIntoWgs(aLat, aLong)
    set {x, y, z} to llh2xyz(aLat, aLong, heightNum, rJP, e2JP, rdNum) of me
    
    
set x to x + dxNum
    
set y to y + dyNum
    
set z to z + dzNum
    
    
set {lat1, lng1, h1} to xyz2llh(x, y, z, rWS, e2WS, rdNum) of me
    
return {lat1, lng1, h1}
  end convertIntoWgs
  
  
  
–座標系の変換(緯度経度 -> xyz)
  
on llh2xyz(latLocal, lngLocal, hLocal, aLocal, e2Local, rdLocal)
    set latLocal to latLocal * rdLocal
    
set lngLocal to lngLocal * rdLocal
    
    
set sbNum to calcSin(latLocal) of math
    
set cbNum to calcCos(latLocal) of math
    
    
set rnLocal to aLocal / (calcSqrt(1 – e2Local * sbNum * sbNum) of math)
    
    
set xLocal to (rnLocal + hLocal) * cbNum * (calcCos(lngLocal) of math)
    
set yLocal to (rnLocal + hLocal) * cbNum * (calcSin(lngLocal) of math)
    
set zLocal to (rnLocal * (1 – e2Local) + hLocal) * sbNum
    
    
return {xLocal, yLocal, zLocal}
  end llh2xyz
  
  
  
–座標系の変換(xyz -> 緯度経度)
  
on xyz2llh(x, y, z, a, e2, rdLocal)
    set bda to calcSqrt(1 – e2) of math
    
set p to calcSqrt(x * x + y * y) of math
    
set t to calcAtan2(z, p * bda) of math
    
set stNum to calcSin(t) of math
    
set ctNum to calcCos(t) of math
    
set b to calcAtan2(z + e2 * a / bda * stNum * stNum * stNum, p – e2 * a * ctNum * ctNum * ctNum) of math
    
    
set l to calcAtan2(y, x) of math
    
set sb to calcSin(b) of math
    
set rn to a / (calcSqrt(1 – e2 * sb * sb) of math)
    
set h to p / (calcCos(b) of math) – rn
    
set l1 to b / rdLocal
    
set l2 to l / rdLocal
    
return {l1, l2, h}
  end xyz2llh
  
end script

★Click Here to Open This Script 

Posted in geolocation | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

noteのオンラインマガジン「猛者」に新規Noteを寄稿(4)

Posted on 7月 11, 2018 by Takaaki Naganoya

オンラインマガジンApp Engineer Journal “猛者”(モサ)に「Appleを倒すメーカーを作ってみよう」「Apple Watchの打倒のしかた(上)」を寄稿しました。

Posted in 未分類 | Leave a comment

オープン中のNumbers書類のすべてのシート上のテーブルのデータを連結して新規書類に入れる v2

Posted on 7月 10, 2018 by Takaaki Naganoya

オープン中のNumbers書類のうち最前面のものを対象に、すべてのシート上のテーブル1のデータを連結して新規書類に入れるAppleScriptです。

(↑)Numbers書類中のテーブルのカラム数がすべて同じことが本Scriptの前提条件。

データ結合まではすぐに処理が終わるものの、結合したデータを新規Numbers書類にAppleScriptから順次突っ込むと、データ数の増加にともなって処理時間が大幅に増えるので、そのやり方はやるべきではありません(経験のない素人がやりそうな処理)。

なので、本ScriptではCSVファイルを組み立てて、デスクトップに書き出し、それをNumbersにオープンさせます。

これだと処理は一瞬です。開発環境では、シート9枚&総合計263行のデータを連結してCSVに書き出してNumbers上でオープンするのに1.6秒しかかかりません。

AppleScript名:オープン中のNumbers書類のすべてのシート上のテーブルのデータを連結して新規書類に入れる v2
— Created 2018-07-09 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use bPlus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html

script spd
  property allData : {} –Numbersから取得したデータをストアしておく
  
property all2DData : {} –取得したデータを2D Arrayに変換した際にデータをストアしておく
end script

set (allData of spd) to {}
set (all2DData of spd) to {}

set dataWidth to 2

tell application "Numbers"
  tell front document
    set aList to every sheet
    
    
repeat with i in aList
      tell i
        tell table 1
          –テーブル中のセルの値をすべて取得(1D Listで帰ってくる)
          
set aList to value of every cell
          
          
–1D ListをSweep(missing valueの入っているアイテムを削除)
          
set bList to sweep1DList(aList) of me
          
          
–取得してSweepしたデータを連結
          
set (allData of spd) to (allData of spd) & (bList as list)
        end tell
      end tell
    end repeat
    
  end tell
end tell

–1D Listを2D Listに変換
set (all2DData of spd) to conv1DListTo2DList((allData of spd), dataWidth) of me

–まとめたデータをCSVファイルとして書き出し
set aPath to ((path to desktop) as string) & (do shell script "uuidgen") & ".csv"
saveAsCSV((all2DData of spd), aPath) of me

do shell script "sync" –SSDで処理している場合には必要ないが、、、
set anAlias to aPath as alias

–書き出したCSVファイルをNumbersでオープン
tell application "Numbers"
  open anAlias
  
activate
end tell

on sweep1DList(aList)
  load framework
  
return (current application’s SMSForder’s arrayByDeletingBlanksIn:aList) as list
end sweep1DList

on conv1DListTo2DList(aList, groupingNum)
  load framework
  
return (current application’s SMSForder’s subarraysFrom:aList groupedBy:groupingNum |error|:(missing value)) as list
end conv1DListTo2DList

–2D List to CSV file
on saveAsCSV(aList, aPath)
  set crlfChar to (string id 13) & (string id 10)
  
set LF to (string id 10)
  
set wholeText to ""
  
  
repeat with i in aList
    set newLine to {}
    
    
–Sanitize (Double Quote)
    
repeat with ii in i
      set jj to ii as text
      
set kk to repChar(jj, string id 34, (string id 34) & (string id 34)) of me –Escape Double Quote
      
set the end of newLine to kk
    end repeat
    
    
–Change Delimiter
    
set aLineText to ""
    
set curDelim to AppleScript’s text item delimiters
    
set AppleScript’s text item delimiters to "\",\""
    
set aLineList to newLine as text
    
set AppleScript’s text item delimiters to curDelim
    
    
set aLineText to repChar(aLineList, return, "") of me –delete return
    
set aLineText to repChar(aLineText, LF, "") of me –delete lf
    
    
set wholeText to wholeText & "\"" & aLineText & "\"" & crlfChar –line terminator: CR+LF
  end repeat
  
  
if (aPath as string) does not end with ".csv" then
    set bPath to aPath & ".csv" as Unicode text
  else
    set bPath to aPath as Unicode text
  end if
  
  
writeToFile(wholeText, bPath, false) of me
  
end saveAsCSV

on writeToFile(this_data, target_file, append_data)
  tell current application
    try
      set the target_file to the target_file as text
      
set the open_target_file to open for access file target_file with write permission
      
if append_data is false then set eof of the open_target_file to 0
      
write this_data to the open_target_file starting at eof
      
close access the open_target_file
      
return true
    on error error_message
      try
        close access file target_file
      end try
      
return error_message
    end try
  end tell
end writeToFile

on repChar(origText as text, targChar as text, repChar as text)
  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

★Click Here to Open This Script 

Posted in list | Tagged 10.11savvy 10.12savvy 10.13savvy Numbers | Leave a comment

PDFから指定ページ以降を削除

Posted on 7月 10, 2018 by Takaaki Naganoya

PDFから指定ページ以降を削除するAppleScriptです。

こんな(↑)418ページもあるPDFから、おためし版の、冒頭から40ページだけ抽出したPDFを作成する際に使用したものです。

もともとは418ページありましたが、、、

実行後は40ページに、、、

AppleScript名:PDFから指定ページ以降を削除
— Modified 2018-07-08 by Takaaki Naganoya
–Original By Shane Stanley
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "QuartzCore"
use aBplus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html

property NSSet : a reference to current application’s NSSet
property |NSURL| : a reference to current application’s |NSURL|
property NSArray : a reference to current application’s NSArray
property SMSForder : a reference to current application’s SMSForder
property NSIndexSet : a reference to current application’s NSIndexSet
property PDFDocument : a reference to current application’s PDFDocument
property NSSortDescriptor : a reference to current application’s NSSortDescriptor

load framework

set sPage to 41 –ここから末尾までのページを削除
set inFile to (choose file of type {"pdf"} with prompt "Choose your PDF files:")
set pRes to removePDFPageAfter(inFile, sPage) of me

–指定パスのPDFの指定ページ以降をすべて削除
on removePDFPageAfter(inFile, sPage)
  set pCount to pdfPageCount(inFile) of me
  
set eCount to pCount – sPage + 1
  
  
set aindexSet to NSIndexSet’s indexSetWithIndexesInRange:(current application’s NSMakeRange(sPage, eCount))
  
set targPageList to (SMSForder’s arrayWithIndexSet:aindexSet) as list
  
  
return removeSpecificPagesFromPDF(inFile, targPageList) of me
end removePDFPageAfter

–指定PDF書類の複数ページの一括削除
on removeSpecificPagesFromPDF(inFileAlias, targPageNumList as list)
  set inNSURL to |NSURL|’s fileURLWithPath:(POSIX path of inFileAlias)
  
set theDoc to PDFDocument’s alloc()’s initWithURL:inNSURL
  
  
–削除対象ページリストをユニーク化して降順ソート(後方から削除)
  
set pRes to theDoc’s pageCount()
  
set t3List to relativeToAbsNumList(targPageNumList, pRes) of me
  
  
repeat with i in t3List
    copy i to targPageNum
    (
theDoc’s removePageAtIndex:(targPageNum – 1))
  end repeat
  
  
–Overwrite Exsiting PDF
  
set aRes to (theDoc’s writeToURL:inNSURL) as boolean
  
  
return aRes
end removeSpecificPagesFromPDF

–絶対ページと相対ページが混在した削除対象ページリストを絶対ページに変換して重複削除して降順ソート
on relativeToAbsNumList(aList, aMax)
  set newList to {}
  
  
repeat with i in aList
    set j to contents of i
    
if i < 0 then
      set j to aMax + j
    end if
    
    
if (j ≤ aMax) and (j is not equal to 0) then
      set the end of newList to j
    end if
  end repeat
  
  
set t1List to uniquify1DList(newList, true) of me
  
set t2List to sort1DNumListWithOrder(t1List, false) of me
  
  
return t2List
end relativeToAbsNumList

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

–Sort 1-Dimension List(String Number List)
on sort1DNumListWithOrder(theList as list, aBool as boolean)
  tell NSSet to set theSet to setWithArray_(theList)
  
tell NSSortDescriptor to set theDescriptor to sortDescriptorWithKey_ascending_("floatValue", aBool)
  
set sortedList to theSet’s sortedArrayUsingDescriptors:{theDescriptor}
  
return (sortedList) as list
end sort1DNumListWithOrder

–指定PDFのページ数をかぞえる(10.9対応。普通にPDFpageから取得)
–返り値:PDFファイルのページ数(整数値)
on pdfPageCount(aFile)
  set aFile to POSIX path of aFile
  
set theURL to |NSURL|’s fileURLWithPath:aFile
  
set aPDFdoc to PDFDocument’s alloc()’s initWithURL:theURL
  
set aRes to aPDFdoc’s pageCount()
  
return aRes as integer
end pdfPageCount

★Click Here to Open This Script 

Posted in file PDF | Tagged 10.11savvy 10.12savvy 10.13savvy NSArray NSIndexSet NSSet NSSortDescriptor NSURL PDFDocument | Leave a comment

Blogアーカイブ本 vol.1を販売開始

Posted on 7月 9, 2018 by Takaaki Naganoya

ごく一部の愛読者の皆様からのご要望を受け、2018年1月のBlog消滅以前の内容を1年ごとにまとめた「Blogアーカイブ本」のVol.1を販売開始しました。Vol.1は2008年3〜12月の内容をまとめています。全418ページ、2,000円。ファイル形式はPDFで、キーワードによる全文検索や印刷が行えます。

→ オンライン販売ページ
→ お試し版ダウンロードページ

2014年以前の巻については、Cocoaの機能をほとんど使っていないので、Cocoa Scriptingについてはわからないとか、Cocoa Scriptingになじめない方には「Cocoaを使わないやりかた」が説明されている、現時点では数少ないまとまった参考文献になるはずです。

続刊刊行スケジュールについては、「できた分から」としか言いようがありませんが、各巻のボリュームについては、

 vol.2:2009/1〜12(仮組みページ数:332)
 vol.3:2010/1〜12(仮組みページ数:247)
 vol.4:2011/1〜2012/12(仮組みページ数:372)
 vol.5:2013/1〜2014/12(仮組みページ数:276)
 vol.6:2015/1〜12(仮組みページ数:320)

といったところです。価格は一律2,000円です。当初は日本語版だけですが、英語版も出せるといいですね。Vol.5/6については、Cocoa Scriptingがわからないと手が出しづらいので、Cooca Scriptingの入門資料を添付することも検討中です。

■Vol.1 掲載AppleScript(全262本)
5桁の乱数を生成
指定アプリの存在確認
BSDサブシステムの存在確認
リストから重複部分を除外(ユニーク化)
春分の日と秋分の日を求める
自分の(インターネットアクセス時の)IPアドレスを調べる
起動中のアプリのうちScriptableなものをリストにして選択
起動ディスクの空き容量を返す
リストの内容を乱数でシャッフル
CPUのクロック数だけを求める
与えられたリストから、値がヌルの要素を削除して返す
最小値を取得する1
最小値を取得する2
最小値を取得する3
文字列中の最長Wordを返す
リストをテキストに
リストのスイープ
Automator集計
chooseFromListでアイテム番号を返す
OSのバージョンを求める
リストを任意のデリミタ付きでテキストに
文字列のアルファベットチェック
拡張子を取得する
日本語URL Encoding
指定年月の長さを求める
指定文字を置換(リプレース)
国民の祝日を求める
時分秒をシステム設定と関係なく一律に取得
プロセス名一覧を取得
指定フォルダまで強制的に作成
指数表示数値を文字列化
Safariの選択部分のテキストを取得する
各種情報取得
デフォルトの出力先のプリンタ名称(キュー名称?)を取得
リストをタブ区切りのテキストに変換
MacのハードウェアのシリアルNoを取得
BluetoothのOn、Off
リスト中の指定要素をサーチして削除して返す
ACで動いているかDCで動いているかを取得する
指定クリエータのアプリケーションの情報を返す
最前面のFinderウィンドウのアイコンサイズを取得する
リスト中の全要素が同じかどうかをbooleanで返す
指定矩形内に含まれるデータをリストで返す
URLエンコードされたファイルパスを元のテキスト(POSIX Path)に戻す
Desktop Windowの大きさを取得してメインモニタの大きさを得る
RSS用のRFC822形式の日付を返すv2
OSのバージョンを求める5
ユーザー名をLong Formatで取得する2
リスト内のアイテムへの項目追加
リスト項目の並べ替え
指定のiDiskをマウントする
OSのバージョンの2桁目(メジャーバージョン)を取得
イベント継承実験1
文字列中のピリオドの個数を数える
ISO形式の日付をdateオブジェクトに
twitter.comの更新
Zipでフォルダ構造ごと圧縮
指定キーワードの出現回数のカウント
System UI Soundが有効になっているかどうかをチェック
指定桁でゼロパディングしたファイル名を返す
set the beginning of
データのhexダンプ_v2
entire contentsをalias listで取得する
10.4.9〜10.4.11でバージョンが10.4.9と返ってくるバグを回避するOSバージョンの取得方法
今日の日付をYYYYMMDDで求める
指定文字列を指定バイト数以内に収める
画面のサイズを取得するらしい
リストのCSV書き出し
list sort
インターネット接続確認
ファイルの各種情報を取得する
指定の文字エンコーディングでファイル書き出し
1月分のワークログ作成(祝日反映版)
1月分のワークログ作成(iCal連携Ver)
Omni Outlinerでドキュメントの全行削除
クリップボード中のテキストから、行単位にトピック作成
最前面のOmniOutliner書類をDHTMLでデスクトップにExport
Terminalで同じパスの画面をもう1枚ひらく
ターミナルのcurrentをFinderでひらく
Finderの最前面のパスをTerminalで開く(強化ver4)
iPhotoで選択中の写真をデスクトップピクチャに設定
Finderで作成したZipアーカイブを展開してオリジナルのアーカイブを削除する
指定ファイルがTIFFで128×128であれば、icnsファイルに変換する
10進数をn進数文字列に変換する
自分用のtempoary folderをtmporary items foder(user domain)に作成する
指定のAutomator Workflowのファイルを実行する
File Busyが解除になるのを待つ
指定プロセスの可視_不可視切り替え
文字列の前後から別々の文字を指定してトリミング
Menu Xtraに入っているアイテムの一覧を取得する
再帰でファイルをカウント
parseByDelim:指定デリミタで文字列をリストに変換
OSバージョンの各桁を求める
警告を出しつつ再起動
時間フォーマットをhh-mm-ssからsに変更
GUI Scriptingをenableに
GUI Scriptingをdisableに
ワイヤレスキーボードのバッテリ残量を得る
指定フォルダ内に指定ファイルが存在するかどうかをチェック
OSのバージョンを求める2
OSのバージョンを求める3
OSのバージョンを求める4
OSのバージョンとビルドNoを求める
対象文字列の中で、特定の文字以降を取得
Front Rowが実行中かどうかを調べる
iCalでReadOnlyではないカレンダーの番号を取得
指定のタグを外す
数字の間に入っているゴミを除去
アルファベットを大文字 or 小文字に変換する
アルファベットの大文字か小文字かを検出する
電池容量を取得
iTunesでどこのIPからライブラリを共有されているかを検出
印刷可能なプリンタ一覧から選択してプリント実行
指定のAutomator Workflowのファイルを実行するv2
Dockの制御
Skypeのバージョンを求める
Skypeで接続状態を取得する
Skypeで指定IDの人に音声コール
Skypeでチャットメッセージを送信
Skypeで最近のチャットメッセージをリストアップ
Skypeでユーザー権限を取得
Skypeでフレンズを検索
Skypeでセルフテスト
Skypeでオンライン中の人間の数を取得する
Skypeでオーディオ出力設定を取得
SkypeでUser Statusを求める
SkypeでStatusを変更
SkypeでP-STNの状態を得る
Skypeでauthentication待ちのユーザーをリストアップ
Google Earthで現在表示中の画面のスクリーンショットを撮るv1
Google Earthでバージョン情報を取得
日本語入りテキストのURLエンコーディング
Systranで翻訳
Mail.appでAccountの情報を取得する
Mail.appで新着メールを確認する
Mail.appで新着メールの確認インタバルを変更する
Mail.appで選択中のメッセージから迷惑メールフラグの状態を取得する
添付ファイルのダウンロード先を求める
選択中のメッセージの実ファイルが存在する場所を取得するv3
URL Access ScriptingでDL
GUI Scriptingの確認
JPEG画像の破損チェック
Safariの選択部分のテキストを取得する
SafariでオープンしているWindowをすべてクローズする
指定文字列の中に指定リストの各アイテムが含まれているかをチェック
rmコマンドで指定フォルダ内のファイルの強制削除
modemでダイヤルする
modemでダイヤルする2
エイリアスをDockに追加する
入り組んだリストの中に指定要素が存在するかどうかをチェック
指定の名称およびバージョンに該当するアプリケーションプロセスが起動しているかどうかをチェック
Database Eventsでパスを指定してDBを作成する
Database Eventsを終了する
Database EventsのQuit Delayを指定
Database Eventsで、すべてのDBをクローズして終了
Database Eventsで、既存のDBを指定してオープンする
Database Eventsを起動して、オープン中のDBを数える
画像の縦長横長を見てフォルダ仕分け
リストをレコードに
レコードから特定要素を取り出し
Safariのウィンドウを画面いっぱいに拡大する
スクリプトエディタ上のキャレットがある行に、ファイル名をコメントで展開
指定文字列の中に指定リストの並びが含まれているかをチェック。含まれていたら起点のアイテム番号を、ない場合にはfalseを返す
指定文字列の中に指定リストの並びが含まれているかをチェック。含まれていたら起点のアイテム番号を、ない場合にはfalseを返す v2
テキストから余計な空白行を削除する
リストを任意のデリミタ付きでテキストにv2
画面スナップショットのファイル形式を変更
Acrobat Professionalでしおりを作成(文字化け)
Pagesの最前面のドキュメントを閉じてラベルを付ける
Acrobat Professionalでしおりを数える
Acrobat Professionalでしおりを全消去
Acrobat Professionalで指定ページに移動
フォルダ同士の内容比較
ファイルのMac OS形式のフルパスのテキストから、ファイル名のみを取得
バージョン番号文字列からメジャーバージョンのみ取り出し
クリエーターコードを指定してアプリケーションを起動する
QuickTime Playerで録音を開始する
QuickTime Playerで録画を開始する
ヨドバシ.comのWebの画面に表示されている200×200ピクセル以上の画像をダウンロードする v2
指定アプリのメインウィンドウのサイズを返す
指定フォルダ内の指定ファイルを削除
真偽値の反転
指定のディスクイメージが暗号化されているかどうかを判定する
ファイルのコピーをshell scriptで実行
uuidgenでユニークな(重複のない)文字列を取得
アクティブウィンドウのアクティブセルの値を取得
現在の列のセル幅を変更する
現在の行のセルの高さを変更する
空のplistファイルを指定パスに作成する
空のplistファイルを指定パスに作成するv2
PDFのページ数を数える
dateコマンドから生成した日付テキストから、ASのdateオブジェクトを生成する
active cellが属するentire rowを取得する
Unionコマンドで複数の範囲を同時に使う
条件を指定してセルを抽出する
指定セルの値を取得/設定する
セルの文字列を取得する
Bubble Sortでリストをソートする
Insertion Sortでリストをソートする
挿入ソートを入れ子のリストに対して行う(ソートキー項目指定つき)
シェルソート
shell sortで入れ子のリストをソート
奇数かどうかチェック
曜日リストの並び順をチェック
曜日リストの並び順をチェック v2
iCalに「日本の祝日」を追加
MindManagerで、ルートトピックを選択状態にする
Excelで、バージョンに依存しないで選択範囲のデータ取得
指定の数値リストを作成する
データが数値かどうか調べる
カレンダーのインクリメント/デクリメント
ポップアップメニュー項目の高速生成
MACアドレスを取得する(Mac OS X 10.5のバグ回避版)
指定日に在任中の内閣総理大臣の氏名を取得
数値テキストに対して指定桁ごとにセパレータ文字を入れる
リストから選択してアイテム番号を返す
リスト中の複数の指定要素を削除して返す
1年分のカレンダーリストを作成
1年分のカレンダーリストを作成して指定日が何週目かを求める v1
1年分のカレンダーリストを作成して指定日が何週目かを求める v2
1年分のカレンダーリストを作成して指定日が何週目かを求める v2.1
DragThingで表示しているDock名称を取得する
DragThingの特定のDock中で現在選択中のレイヤーを求める
DragThingで、最前面のDock上で現在選択されているレイヤーの名称を返す
リストの一部を取り出す
デスクトップ上のピクチャファイルを指定フォルダに移動
Keynoteでslideの情報を取得する
10.5で(登録してある)プリンタ名称の一覧を取得するv1
10.5で(登録してある)プリンタ名称の一覧を取得するv3
ColorSync Scriptingで各種情報を取得
アドレスブックで所有者の情報を取得する
アドレスブックで選択中のPersonの情報を取得する
FM v7〜9で、オープン中のデータベースを数える
オープン中のデータベースの中にあるテーブル数を数える
オープン中のデータベース中のテーブル1にあるフィールドを数える
オープン中のデータベースのレイアウト(画面)を数える
オープン中のデータベースのレイアウトの名称を取得する
オープン中のデータベースで条件検索(複数条件)
オープン中のデータベースでソート
Microsoft Office 2008用の「VBAからAppleScriptへの移行支援ガイド」が公開
10.5で暗黙のキャストが行われなくなった例(getMLen)
OmniPlanでWindowの情報を取得する
OmniPlanでドキュメント内のプロジェクトを数える
リストの重複項目を除去、リスト2つ同時バージョン
Excel v.Xで新規ドキュメントを作成して任意のワークシートを作成
Excel v.2004/2008でウィンドウの最大化
Excel v.Xで最前面のウィンドウを最大化する
Excel v.2008でウィンドウ枠の分割を固定
International Settingsの言語で第一優先になっているものを取得
指定フォルダにあるテキストとZipアーカイブのリストを取得。エイリアスで v0
指定フォルダにあるテキストとzipアーカイブのリストを取得。エイリアスで v1
指定フォルダにあるテキストとzipアーカイブのリストを取得。エイリアスで v2
度数分布のテキスト出力
指定フォルダにある特定のラベル(複数)のファイルのリストを取得。エイリアスで
MindManagerで、ルートトピック以外のトピックをすべて取得
指定フォルダにある特定の書類種別(複数)のファイルのリストを取得。エイリアスで
特定の文字ではじまるリスト要素を削除して返す
与えられたURLからファイル名を取り出す
単純ダウンロード
クリップボードに入っているURLのファイルをダウンロード
POSIX pathからクォート記号を除去する(unquote)
ファイル名から拡張子を外す

Posted in 未分類 | Leave a comment

CotEditorの最前面のテキストで空行で区切ったブロックを逆順にする

Posted on 7月 8, 2018 by Takaaki Naganoya

CotEditorの最前面のテキスト中で、空行で区切ったブロックを逆順にならべかえるAppleScriptです。

こういう(↑)状態のテキストを、

こういう(↑)状態にならべかえます。

ここでは、わかりやすく空行でブロックを区切っていますが、別のもので区切りを検出してみたり、テキスト全体から自動的にブロック検出をテキストエディタ自体がやってくれるといいのになー、と思っています。

AppleScript名:CotEditorの最前面のテキストで空行で区切ったブロックを逆順にする
— Created 2018-07-07 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

–CotEditorから本文テキストを取得
tell application "CotEditor"
  tell front document
    set aText to contents of it
  end tell
  
set aList to paragraphs of aText
end tell

–空行で区切られたテキストブロックをブロック単位で逆順に組み立てる
set bText to makeRetrunSeparatedStrBlockReversed(aList) of me

–計算結果をCotEditorの本文テキストに書き戻す
tell application "CotEditor"
  tell front document
    set (contents of it) to bText
  end tell
end tell

on makeRetrunSeparatedStrBlockReversed(aList)
  –行ごとにリスト化した1D Listをブロック単位の2D List化
  
set newList to {}
  
set tmpList to {}
  
  
repeat with i in aList
    set j to contents of i
    
if j = "" then
      if tmpList = {} then
        set tmpList to {}
      else
        set the end of newList to tmpList
        
set the end of newList to {}
        
set tmpList to {}
      end if
    else
      set the end of tmpList to j
    end if
  end repeat
  
  
if tmpList is not equal to {} then
    set the end of newList to tmpList
    
set the end of newList to {}
  end if
  
  
set newBList to reverse of newList –ブロックを逆順に
  
  
–2D Listをテキストに
  
set newCList to FlattenList(newBList) of me
  
set resBstr to retStrFromArrayWithDelimiter(newCList, return) of me
  
  
return resBstr
end makeRetrunSeparatedStrBlockReversed

–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 retStrFromArrayWithDelimiter(aList, aDelim)
  set anArray to current application’s NSArray’s arrayWithArray:aList
  
set aRes to anArray’s componentsJoinedByString:aDelim
  
return aRes as text
end retStrFromArrayWithDelimiter

★Click Here to Open This Script 

Posted in list Text | Tagged 10.11savvy 10.12savvy 10.13savvy CotEditor NSArray | Leave a comment

Finder上で選択中のMarkdown書類をファイル名で昇順ソート(A→Z)して、各書類のタイトル見出しを取得する

Posted on 7月 8, 2018 by Takaaki Naganoya

Finder上で選択中のMarkdown書類を取得し、ファイル名で昇順ソート(A→Z)して、各Markdown書類中のタイトルのうち最もレベルの高い(重要な)ものを抽出し、まとめてテキストにしてクリップボードに転送するAppleScriptです。

大量にあるMarkdown書類の本文中から一番重要なタイトルを抽出する作業を……さすがに手作業で行うわけには行かなかったので、AppleScriptを書いて処理してみました。ただし、新規に書いた処理はほとんどなく、既存のルーチンの寄せ合わせで構成しています。

Finder上でMarkdown書類を選択した状態で本Scriptを実行すると(Markdown書類以外は除外して)、AppleScriptでMarkdown書類を読み込んで(Markdown書類がUTF-8固定なのでUTF-8を指定して読み込み)、正規表現で書類中のタイトルを抽出し、重要なタイトル(#の個数が少ない)をピックアップ。これをすべての書類について行います。

処理結果をクリップボードに転送します。

最終的には、(手作業で加工して)このようになります。

若干の手作業は発生してしまいますが、このScriptを組まなかったら、とてもその手作業を行う気も起こらなかったわけで、、、

AppleScript名:Finder上で選択中のMarkdown書類をファイル名で昇順ソート(A→Z)して、各書類のタイトル見出しを取得する
— Created 2018-06-26 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "Quartz"
use mdLib : script "Metadata Lib" version "1.0.0"
use bPlus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html

property |NSURL| : a reference to current application’s |NSURL|
property NSArray : a reference to current application’s NSArray
property NSString : a reference to current application’s NSString
property SMSForder : a reference to current application’s SMSForder
property NSIndexSet : a reference to current application’s NSIndexSet
property NSPredicate : a reference to current application’s NSPredicate
property NSMutableSet : a reference to current application’s NSMutableSet
property NSFileManager : a reference to current application’s NSFileManager
property NSCountedSet : a reference to current application’s NSCountedSet
property NSURLPathKey : a reference to current application’s NSURLPathKey
property NSMutableArray : a reference to current application’s NSMutableArray
property NSURLNameKey : a reference to current application’s NSURLNameKey
property NSSortDescriptor : a reference to current application’s NSSortDescriptor
property NSURLIsPackageKey : a reference to current application’s NSURLIsPackageKey
property NSRegularExpression : a reference to current application’s NSRegularExpression
property NSURLIsDirectoryKey : a reference to current application’s NSURLIsDirectoryKey
property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey
property NSURLContentModificationDateKey : a reference to current application’s NSURLContentModificationDateKey
property NSRegularExpressionAnchorsMatchLines : a reference to current application’s NSRegularExpressionAnchorsMatchLines
property NSDirectoryEnumerationSkipsHiddenFiles : a reference to current application’s NSDirectoryEnumerationSkipsHiddenFiles
property NSRegularExpressionDotMatchesLineSeparators : a reference to current application’s NSRegularExpressionDotMatchesLineSeparators

load framework

–set inFiles to (choose file of type {"pdf"} with prompt "Choose your PDF files:" with multiple selections allowed)
tell application "Finder"
  set inFiles to selection as alias list
end tell

if inFiles = {} then return

–指定のAlias listのうちMarkdown書類のみ抽出
set filRes1 to filterAliasListByUTI(inFiles, "net.daringfireball.markdown") of me

–指定のPOSIX path listから、各Markdown書類中の一番重要な見出しを抽出して返す
set tRes to listTitlesFromMarkdownDocPathList(filRes1) of me

–取得したタイトル一覧リストをテキストに変換
set t2Res to retStrFromArrayWithDelimiter(tRes, return) of me

–クリップボードに結果を転送
set the clipboard to t2Res

on listTitlesFromMarkdownDocPathList(inFiles)
  set outList to {}
  
set inFilesSorted to my filesInListSortAscending(inFiles)
  
  
repeat with i in inFilesSorted
    –POSIX pathからaliasにパス変換してテキスト読み込み
    
set j to POSIX file (contents of i)
    
set jj to j as alias
    
set aStr to (read jj as «class utf8»)
    
    
set aList to retHeaders(aStr) of me –Markdown書類中の見出しをリストアップ
    
–>  {​​​​​{​​​​​​​1, ​​​​​​​" 2008/3/9 5桁の乱数を生成"​​​​​}​​​}
    
    
if aList is not equal to {} then
      –2D Listの昇順ソート
      
set sortIndexes to {0} –Key Item id: begin from 0
      
set sortOrders to {true} –ascending = true
      
set sortTypes to {"compare:"}
      
set resList to (current application’s SMSForder’s subarraysIn:(aList) sortedByIndexes:sortIndexes ascending:sortOrders sortTypes:sortTypes |error|:(missing value)) as list
      
      
set aCon to contents of second item of first item of resList
      
set the end of outList to aCon
    end if
  end repeat
  
return outList
end listTitlesFromMarkdownDocPathList

on filesInListSortAscending(aliasList as list)
  set cList to {}
  
repeat with i in aliasList
    set j to contents of i
    
set aFileName to ((current application’s NSString’s stringWithString:j)’s valueForKeyPath:"lastPathComponent")
    
set the end of cList to {fileName:aFileName, pathDat:j}
  end repeat
  
  
set aResList to sortRecListByLabel(cList, "fileName", true) of me –昇順ソート
  
set bResList to (aResList’s valueForKeyPath:"pathDat") as list of string or string
  
return bResList
end filesInListSortAscending

–Alias listから指定UTIに含まれるものをPOSIX pathのリストで返す
on filterAliasListByUTI(aList, targUTI)
  set newList to {}
  
repeat with i in aList
    set j to POSIX path of i
    
set tmpUTI to my retUTIfromPath(j)
    
set utiRes to my filterUTIList({tmpUTI}, targUTI)
    
if utiRes is not equal to {} then
      set the end of newList to j
    end if
  end repeat
  
return newList
end filterAliasListByUTI

–指定のPOSIX pathのファイルのUTIを求める
on retUTIfromPath(aPOSIXPath)
  set aURL to |NSURL|’s fileURLWithPath:aPOSIXPath
  
set {theResult, theValue} to aURL’s getResourceValue:(reference) forKey:NSURLTypeIdentifierKey |error|:(missing value)
  
  
if theResult = true then
    return theValue as string
  else
    return theResult
  end if
end retUTIfromPath

–UTIリストが指定UTIに含まれているかどうか演算を行う
on filterUTIList(aUTIList, aUTIstr)
  set anArray to NSArray’s arrayWithArray:aUTIList
  
set aPred to NSPredicate’s predicateWithFormat_("SELF UTI-CONFORMS-TO %@", aUTIstr)
  
set bRes to (anArray’s filteredArrayUsingPredicate:aPred) as list
  
return bRes
end filterUTIList

on returnNumberCharsOnly(aStr)
  set anNSString to current application’s NSString’s stringWithString:aStr
  
set anNSString to anNSString’s stringByReplacingOccurrencesOfString:"[^0-9]" withString:"" options:(current application’s NSRegularExpressionSearch) range:{0, anNSString’s |length|()}
  
return anNSString as text
end returnNumberCharsOnly

–リストに入れたレコードを、指定の属性ラベルの値でソート
on sortRecListByLabel(aRecList as list, aLabelStr as string, ascendF as boolean)
  set aArray to current application’s NSArray’s arrayWithArray:aRecList
  
  
set sortDesc to current application’s NSSortDescriptor’s alloc()’s initWithKey:aLabelStr ascending:ascendF
  
set sortDescArray to current application’s NSArray’s arrayWithObjects:sortDesc
  
set sortedArray to aArray’s sortedArrayUsingDescriptors:sortDescArray
  
return sortedArray
end sortRecListByLabel

–見出し抽出用サブルーチン群
on retHeaders(aCon)
  set tList to {}
  
set regStr to "^#{1,6}[^#]*?$"
  
  
set headerList to my findPattern:regStr inString:aCon
  
repeat with i in headerList
    set j to contents of i
    
set regStr2 to "^#{1,6}[^#]*?"
    
set headerLevel to length of first item of (my findPattern:regStr2 inString:j)
    
set the end of tList to {headerLevel, text (headerLevel + 1) thru -1 in j}
  end repeat
  
  
return tList
end retHeaders

on findPattern:thePattern inString:theString
  set theOptions to ((NSRegularExpressionDotMatchesLineSeparators) as integer) + ((NSRegularExpressionAnchorsMatchLines) as integer)
  
set theRegEx to NSRegularExpression’s regularExpressionWithPattern:thePattern options:theOptions |error|:(missing value)
  
set theFinds to theRegEx’s matchesInString:theString options:0 range:{location:0, |length|:length of theString}
  
set theFinds to theFinds as list — so we can loop through
  
set theResult to {} — we will add to this
  
set theNSString to NSString’s stringWithString:theString
  
repeat with i from 1 to count of items of theFinds
    set theRange to (item i of theFinds)’s range()
    
set end of theResult to (theNSString’s substringWithRange:theRange) as string
  end repeat
  
return theResult
end findPattern:inString:

–リストを指定デリミタをはさんでテキスト化
on retStrFromArrayWithDelimiter(aList, aDelim)
  set anArray to current application’s NSArray’s arrayWithArray:aList
  
set aRes to anArray’s componentsJoinedByString:aDelim
  
return aRes as list of string or string
end retStrFromArrayWithDelimiter

★Click Here to Open This Script 

Posted in file list Markdown regexp Sort Text | Tagged 10.11savvy 10.12savvy 10.13savvy Finder NSArray NSCountedSet NSDirectoryEnumerationSkipsHiddenFiles NSFileManager NSIndexSet NSMutableArray NSMutableSet NSPredicate NSRegularExpression NSRegularExpressionAnchorsMatchLines NSRegularExpressionDotMatchesLineSeparators NSSortDescriptor NSString NSURL NSURLContentModificationDateKey NSURLIsDirectoryKey NSURLIsPackageKey NSURLNameKey NSURLPathKey NSURLTypeIdentifierKey | 3 Comments

CotEditorの最前面のテキストの日付フォーマットを変換する

Posted on 7月 7, 2018 by Takaaki Naganoya

CotEditorでオープン中の最前面の書類中のテキストの、日付フォーマットを変換するAppleScriptです。


▲スクリーンショットは作成中のものです

Blogのアーカイブ本のオマケとして(記事だけだとウンザリする仕上がりだったので)、冒頭にその年に何があったかをAppleのニュースリリースから抽出して掲載してみたのですが、日付の形式が独特だったので、手で打ち直していました。

繰り返して行うと面倒だったので、NSDataDetectorで自然言語テキスト(CotEditorの本文テキスト)から日付を自動検出して書き換えを試みたのですが、NSDataDetectorではこのサンプルのようなほんのちょっとだけ手の加わった日付テキストでは検出してくれませんでした。

一応、フォーマット自体は固定だったので、フォーマッターだけ指定すれば日付テキストとして認識し、常識的なYYYY/MM/DDの日付フォーマットに書き換えるようにしてみました。


▲日付フォーマット文字列の入力


▲日付フォーマット置換したテキスト(処理は一瞬)

ただし、日付フォーマットテキストが行で独立しているもの(添付スクリーンショットのように)を処理対象にしているので、あまり汎用性はなさそうです。

一般的には正規表現で指定することになるんでしょうけれど、その正規表現というかもともとの日付フォーマットを元のテキストから自動検出してくれることがベストだと思います。

なお、CotEditorに依存した処理はひとつもないので、JeditΩでもmiでもテキストエディットでもTextWranglerでもBBEditでも、対象にして処理することはかんたんです。クリップボードの内容に対して処理したほうがいいのかもしれません。

AppleScript名:CotEditorの最前面のテキストの日付フォーマットを変換する
— Created 2018-07-07 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.5"
use framework "Foundation"
use scripting additions

property NSArray : a reference to current application’s NSArray
property NSString : a reference to current application’s NSString
property NSLocale : a reference to current application’s NSLocale
property NSDictionary : a reference to current application’s NSDictionary
property NSCountedSet : a reference to current application’s NSCountedSet
property NSMutableArray : a reference to current application’s NSMutableArray
property NSSortDescriptor : a reference to current application’s NSSortDescriptor
property NSDateFormatter : a reference to current application’s NSDateFormatter

set tmpArray to NSMutableArray’s new()

–変換元(テキストから自動取得できるとよかったのに)
set dFfromStr to text returned of (display dialog "Input Date Format:(年=yyyy, 月=MM, 日=dd)" default answer "MM月 dd, yyyy")

–変換先
set dOutFormStr to "yyyy/MM/dd"

tell application "CotEditor"
  tell front document
    set aRes to contents of it
  end tell
  
  
set aList to paragraphs of aRes
end tell

repeat with i in aList
  set j to contents of i
  
set theDate to dateFromStringWithDateFormat(j, dFfromStr) of me
  
if theDate is not equal to missing value then
    set newDateStr to convDateObjToStrWithFormat(theDate, dOutFormStr) of me
    (
tmpArray’s addObject:newDateStr)
  else
    (tmpArray’s addObject:j)
  end if
end repeat

–NSArrayを指定デリミタをはさんでテキスト化
set tRes to tmpArray’s componentsJoinedByString:(return)
set ttRes to tRes as string

tell application "CotEditor"
  tell front document
    set (contents of it) to ttRes
  end tell
end tell

–日付文字列からdate objectを作成する
on dateFromStringWithDateFormat(dateString as string, dateFormat as string)
  set dStr to NSString’s stringWithString:dateString
  
set dateFormatStr to NSString’s stringWithString:dateFormat
  
  
set aDateFormatter to NSDateFormatter’s alloc()’s init()
  
aDateFormatter’s setDateFormat:dateFormatStr
  
aDateFormatter’s setLocale:(NSLocale’s alloc()’s initWithLocaleIdentifier:"en_US_POSIX")
  
  
set aDestDate to (aDateFormatter’s dateFromString:dStr)
  
  
return aDestDate as list of string or string
end dateFromStringWithDateFormat

–date objectから指定の日付文字列を作成する
on convDateObjToStrWithFormat(aDateO as date, aFormatStr as string)
  set aDF to NSDateFormatter’s alloc()’s init()
  
  
set aLoc to NSLocale’s currentLocale()
  
set aLocStr to (aLoc’s localeIdentifier()) as string
  
  
aDF’s setLocale:(NSLocale’s alloc()’s initWithLocaleIdentifier:aLocStr)
  
aDF’s setDateFormat:aFormatStr
  
set dRes to (aDF’s stringFromDate:aDateO) as string
  
return dRes
end convDateObjToStrWithFormat

★Click Here to Open This Script 

Posted in Calendar Text | Tagged 10.11savvy 10.12savvy 10.13savvy CotEditor NSArray NSCountedSet NSDateFormatter NSDictionary NSLocale NSMutableArray NSSortDescriptor NSString | Leave a comment

NSCountedSetでヒストグラム計算、指定単語リストを削除

Posted on 7月 6, 2018 by Takaaki Naganoya

指定の単語リストから登場頻度の計算(ヒストグラム)を行い、指定単語リストに入っているものについては除外するAppleScriptです。

指定のPDFからURLリンクを抽出し、そのリンクURLをデコードしてAppleScriptのURLリンクからソーステキストを取得し、単語ごとにparseして集計してタグクラウドのRTFを出力するAppleScriptを作成したときに使用したものです。

単に、プログラムリストをparseしてタグクラウドを作成しただけでは、あまり本質(ノイズ要素を除外した分析したい対象のデータ)が見えてきませんでした。

変数名やコマンドなどを除外したかったので、これら(分析対象外のデータ=ノイズ)を集計時に除外するという処理を加えてみたものです。

AppleScript名:NSCountedSetでヒストグラム計算、指定単語リストを削除
— Created 2018-07-06 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set theList to {"set", "set", "set", "tell", "application", "application", "Finder", "Finder", "Safari"}
set exList to {"Finder", "Safari"}
set aRes to wordsCountWithRemovingWordList(theList, exList) of me
–>  {​​​​​{​​​​​​​theKey:"set", ​​​​​​​theCount:3​​​​​}, ​​​​​{​​​​​​​theKey:"application", ​​​​​​​theCount:2​​​​​}, ​​​​​{​​​​​​​theKey:"tell", ​​​​​​​theCount:1​​​​​}​​​}

on wordsCountWithRemovingWordList(theList as list, excludeWordList as list)
  set theCountedSet to current application’s NSCountedSet’s alloc()’s initWithArray:theList
  
  
set newArray to current application’s NSMutableArray’s new()
  
set objList to (theCountedSet’s allObjects()) as list
  
  
repeat with i in objList
    set j to contents of i
    
if j is not in excludeWordList then
      (newArray’s addObject:{theKey:j, theCount:(theCountedSet’s countForObject:j)})
    end if
  end repeat
  
  
return newArray as list of string or string
end wordsCountWithRemovingWordList

★Click Here to Open This Script 

Posted in list Record Text | Tagged 10.11savvy 10.12savvy 10.13savvy NSCountedSet NSMutableArray | Leave a comment

System UI Soundが有効になっているかどうかをチェック v2

Posted on 7月 6, 2018 by Takaaki Naganoya

「システム環境設定」の「サウンド」で、「ユーザーインタフェースのサウンドエフェクトを再生」がオンになっているかどうかを確認するAppleScriptです。


▲false(左)、true(右)

本Blogのアーカイブ本の作成のために過去の記事を整理していたら、本Scriptを発掘し、いまの環境では動かない記述内容だったので書き換えてみたものです。


▲アーカイブ本、1年分で300〜400ページぐらいになりそうで、、、

AppleScript名:System UI Soundが有効になっているかどうかをチェック v2
set sRes to getEnableUISound() of me
–> true / false

–System UI Soundが有効になっているかどうかをチェック
on getEnableUISound()
  set a to do shell script "defaults read ’Apple Global Domain’ ’com.apple.sound.uiaudio.enabled’"
  
return (a = "1")
end getEnableUISound

★Click Here to Open This Script 

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

最前面のFinder Windowをクローン

Posted on 7月 4, 2018 by Takaaki Naganoya

Finderの最前面のウィンドウを、同じ対象フォルダ&同じビュー形式で新規作成するAppleScriptです。

昔どこかで拾ってきたものを使い続けているものです。利用頻度はかなり高く、ファイルの整理をFinder上で行なっているときには、たいてい利用しています。

ファイル作成日が2011年になっていましたが、実際にはさらに古い時期のものだと思います。

開けてみて驚きました(v1)。海外のScripterとの間でなんとなく成立している、

 ・過度に英文っぽく書かない
 ・「the」の乱発はやらない(できてもやらない)
 ・過度に短縮記述は行わない
 ・よほどの必要性がないかぎり、暗黙の実行結果「result」は使わない(何を処理しているかがわかりにくいので)
 ・「get」は省略できる場合が多いので、あえて書かない

というお約束が守られておらず、「the」は入りまくっているわ、「get」が無意味に(この後でresultで受け取っていたのだろうか)使われているわで、読みにくいことこのうえない代物でした。

そこで、v2のように書き換えました。これならかなり読みやすく、わかりやすく、無駄な処理もありません。

はるかかなた昔のAppleScriptの中には、今見るとあまり書きこなれていない記述もあったりして、読み直すとかなり驚くものがたくさんあります。

AppleScript名:最前面のWindowをクローン v1
tell application "Finder"
  set sDisk to (name of startup disk) & ":"
  
  
get the exists of the front Finder window –なにこれ???
  
if the (exists of the front Finder window) is true then
    try
      set newWindow to target of front window
      
set oldView to current view of front window
      
make new Finder window to newWindow
      
set current view of front window to oldView
    end try
  else
    try
      make new Finder window to alias sDisk
      
set the current view of the front Finder window to column view
    end try
  end if
end tell

★Click Here to Open This Script 

AppleScript名:最前面のFinder Windowをクローン v2
tell application "Finder"
  set wEx to (exists of front Finder window)
  
  
if wEx = true then
    try
      set winRef to a reference to front window
      
set curTarget to target of winRef
      
set curView to current view of winRef
      
make new Finder window to curTarget
      
set current view of winRef to curView
    end try
  else
    try
      make new Finder window
      
set current view of front Finder window to list view
    end try
  end if
end tell

★Click Here to Open This Script 

Posted in GUI | Tagged 10.11savvy 10.12savvy 10.13savvy Finder | Leave a comment

Mac Blue-ray Playerで表示中の内容をKeynoteに追記

Posted on 7月 3, 2018 by Takaaki Naganoya

Mac Blue-ray Playerで表示中のディスクの映像を1コマキャプチャして、その画像をオープン中のKeynote書類の末尾に追記するAppleScriptです。

–> Watch Demo Movie

Mac Blue-ray Playerには表示中の映像を静止画像のスナップショットを作成する機能があり、保存先のフォルダは「環境設定」で指定できるようになっています。

本ScriptはmacOS標準搭載のScript Menuに入れて実行することを想定しています。また、自分はMac Blue-ray PlayerでBru-rayディスクではなくDVDを再生することが多く、本検証もDVDディスクで行なっています(たぶんBlu-rayでも大丈夫です)。

キャプチャ先のKeynote書類をあらかじめ作成してオープンしておきます。次に、Mac Blue-ray Playerでディスクを再生して、キャプチャしたい場所で一時停止し、本Scriptをメニューから呼び出して実行すると、Playerの表示内容をキャプチャして、Keynote書類の末尾に新規スライドを追加し、そこにキャプチャした画像をインポートします。

Mac Blue-ray Playerは発売直後(2011年)に購入し、そのままアップデートして利用していたのですが、発売後7年以上経過した現在ではサポートが終了。

アプリケーションを作る側の人間から言わせれば、ひんぱんにオンラインアップデートを行い、6年以上も同一製品ラインナップを維持してきたというのは(品質について批判もないことはないですが)、素直に尊敬に値します。

話が横道に入ってしまいましたが、Mac Blue-ray Playerは現在では「Mac Blu-ray Player Pro」「Mac Blu-ray Player Standard」そして無料版の「Free Mac Media Player」へと別れたようです。

「Free Mac Media Player」は機能面からMac Blue-ray Playerとほぼ同じものに見えます。AppleScript用語辞書もMac Blue-ray Playerと同じものであり、Mac Blue-ray Player用のAppleScriptはFree Mac Media Playerでも使えます(tell application名を直すだけです)。

実際に、本Scriptを「Free Mac Media Player」向けに書き換えて実行できることを確認しています。

AppleScript名:Mac Blue-ray Playerで表示中の内容をKeynoteに追記
— Created 2018-07-02 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

property |NSURL| : a reference to current application’s |NSURL|
property NSPredicate : a reference to current application’s NSPredicate
property NSFileManager : a reference to current application’s NSFileManager
property NSUserDefaults : a reference to current application’s NSUserDefaults
property NSDirectoryEnumerationSkipsHiddenFiles : a reference to current application’s NSDirectoryEnumerationSkipsHiddenFiles

set aExtension to "png" — Mac Blue-ray Player’s Snapshot file name extension
set aKeyword to "スナップショット" –Mac Blue-ray Player’s Snapshot file name’s pre-fix (@Japanese User environment), maybe this is localized string

–Mac Blueray Playerの設定からスナップショットの設定値を取得する
set theID to "com.macblurayplayer.Mac Blu-ray Player"
set theTargKey to "Preferences.snapshotSavePath"
set vRes to defaultsReadFromPlistEntry(theID, theTargKey) of me

–Mac Blueray Playerの環境設定に「~」(チルダ)が入っていた場合に備えて展開
set pathString to current application’s NSString’s stringWithString:vRes
set sourceFolder to pathString’s stringByExpandingTildeInPath()

–処理前にスナップショットのファイルを削除
set file1Res to getFilePathListByExtAndKeyword(sourceFolder, aExtension, aKeyword) of me –ファイル一覧取得
trashItemsByList(file1Res) of me –削除

–Mac Blueray Playerで表示している内容を設定中のフォルダに「スナップショット -YYYY-MM-DD at hh_mm_ss AM-9999999999.png」のファイル名で保存
tell application "Blu-ray Player"
  snapshot –こんだけ
end tell

–処理前にスナップショットのファイルを削除
set file2Res to getFilePathListByExtAndKeyword(sourceFolder, aExtension, aKeyword) of me –ファイル一覧取得
if file2Res = file1Res or file2Res = {} then return –No Snap

–Add Snapshot images to Keynote
repeat with i in file2Res
  set tmpFile to POSIX file i
  
set tmpAlias to tmpFile as alias
  
  
tell application "Keynote"
    tell front document
      set endSlide to make new slide at end
      
      
set blankMaster to master slide "空白" –"Blank" in Japanese. This string is *localized*
      
      
tell endSlide
        set base slide to blankMaster
        
set thisImage to make new image with properties {file:tmpAlias}
      end tell
    end tell
  end tell
  
  
–ファイル削除(ゴミ箱に移動)
  
trashItemAt(tmpAlias) of me
end repeat

–指定フォルダ内のファイルを、拡張子と先頭キーワードで抽出
on getFilePathListByExtAndKeyword(aFol, aExt, aKeyword)
  set aFM to NSFileManager’s defaultManager()
  
set aURL to |NSURL|’s fileURLWithPath:aFol
  
set urlArray to aFM’s contentsOfDirectoryAtURL:aURL includingPropertiesForKeys:{} options:(NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
  
set thePred to NSPredicate’s predicateWithFormat:"pathExtension == [c]%@ && lastPathComponent BEGINSWITH %@" argumentArray:{aExt, aKeyword}
  
set anArray to (urlArray’s filteredArrayUsingPredicate:thePred)
  
if anArray = missing value then return {}
  
return (anArray’s valueForKeyPath:"path") as list
end getFilePathListByExtAndKeyword

–ファイル削除(ゴミ箱に移動) POSIX path listで指定
on trashItemsByList(posixPathList)
  repeat with i in posixPathList
    set fRes to trashItemAt(i) of me
    
if fRes = false then error "Error deleting a path:" & (i as string)
  end repeat
end trashItemsByList

–ファイル削除(ゴミ箱に移動)
on trashItemAt(anAlias)
  set theNSFileManager to NSFileManager’s defaultManager()
  
set anNSURL to |NSURL|’s fileURLWithPath:(POSIX path of anAlias)
  
set theResult to theNSFileManager’s trashItemAtURL:anNSURL resultingItemURL:(missing value) |error|:(missing value)
  
return (theResult as integer = 1) as boolean
end trashItemAt

–指定IDのplistから指定キーの内容を取り出す
on defaultsReadFromPlistEntry(theID, theTargKey)
  set storedDefaults to (NSUserDefaults’s standardUserDefaults()’s persistentDomainForName:theID)
  
set keyList to storedDefaults’s allKeys() as list
  
if theTargKey is not in keyList then return false
  
set aRes to (storedDefaults’s valueForKeyPath:theTargKey) as list of string or string — as anything
  
return aRes
end defaultsReadFromPlistEntry

★Click Here to Open This Script 

Posted in Image | Tagged 10.11savvy 10.12savvy 10.13savvy Free Mac Media Player Keynote Mac Blu-ray Player NSDirectoryEnumerationSkipsHiddenFiles NSFileManager NSPredicate NSURL NSUserDefaults | Leave a comment

指定フォルダ内の指定拡張子のファイルのうち、指定キーワードで始まるものを

Posted on 7月 3, 2018 by Takaaki Naganoya

指定フォルダ(デスクトップ)内の指定拡張子のファイルのうち、ファイル名が指定キーワードではじまるものを抽出するAppleScriptです。

AppleScriptでは定番の処理ですが、Finderが10.7あたりでCocoa化されて書き直しが行われたあたりからフィルタ参照を併用した条件抽出のパフォーマンスが大幅に低下。

アプリケーション間通信でパフォーマンスを低下させないための機能であるフィルタ参照が、かえって処理速度を低下させるというたいへん皮肉な事態に。

AppleScript名:指定フォルダ内の指定拡張子のファイルのうち、指定キーワードで始まるものをaliasリストで返す(Finder Version)
tell application "Finder"
  tell folder (path to desktop)
    set aList to (every file whose name starts with "スナップショット" and kind of it is "PNGイメージ") as alias list
  end tell
end tell

★Click Here to Open This Script 

Finder経由で行うと、処理時間は驚愕の4.6秒(67項目から1項目を抽出するだけの処理です)。これをCocoaの機能を用いて処理すると0.002秒。同じAppleScriptなのに2,000倍以上高速。逆にいえば、現在のFinder経由でのファイル処理の速度は遅すぎです。

macOS 10.10以降では、各種ファイル処理についてはFinderではなくCocoaの機能を用いたほうがよいでしょう。

その他、Finder上で選択中のファイルの一覧を取得するとか、Finder上で選択中のフォルダを取得するといった処理であればパフォーマンスの低下はないので、使っても(処理速度上の)問題はありません。

AppleScript名:指定フォルダ内の指定拡張子のファイルのうち、指定キーワードで始まるものをPOSIX pathリストで返す
— Created 2015-10-01 by Takaaki Naganoya
— Modified 2015-10-01 by Shane Stanley–With Cocoa-Style Filtering
— Modified 2018-07-03 by Takaaki Naganoya–Added filtering feature
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"

property |NSURL| : a reference to current application’s |NSURL|
property NSPredicate : a reference to current application’s NSPredicate
property NSFileManager : a reference to current application’s NSFileManager
property NSDirectoryEnumerationSkipsHiddenFiles : a reference to current application’s NSDirectoryEnumerationSkipsHiddenFiles

set aExtension to "png" — no dot
set aKeyword to "スナップショット" –"Snapshot" in Japanese
set aTargetFolder to POSIX path of (path to desktop folder)

set fList to getFilePathListByExtAndKeyword(aTargetFolder, aExtension, aKeyword) of me
–>  {"/Users/me/Desktop/スナップショット-2018-07-03 at 11_42_12 AM-1696613812.png"}

on getFilePathListByExtAndKeyword(aFol, aExt, aKeyword)
  set aFM to NSFileManager’s defaultManager()
  
set aURL to |NSURL|’s fileURLWithPath:aFol
  
set urlArray to aFM’s contentsOfDirectoryAtURL:aURL includingPropertiesForKeys:{} options:(NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
  
set thePred to NSPredicate’s predicateWithFormat:"pathExtension == [c]%@ && lastPathComponent BEGINSWITH %@" argumentArray:{aExt, aKeyword}
  
set anArray to (urlArray’s filteredArrayUsingPredicate:thePred)
  
if anArray = missing value then return {}
  
return (anArray’s valueForKeyPath:"path") as list
end getFilePathListByExtAndKeyword

★Click Here to Open This Script 

Posted in file | Tagged 10.11savvy 10.12savvy 10.13savvy Finder NSDirectoryEnumerationSkipsHiddenFiles NSFileManager NSPredicate NSURL | Leave a comment

Post navigation

  • Older posts

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

Google Search

Popular posts

  • macOS 13, Ventura(継続更新)
  • アラートダイアログ上にWebViewで3Dコンテンツを表示(WebGL+three.js)v3
  • UI Browserがgithub上でソース公開され、オープンソースに
  • macOS 13 TTS Voice環境に変更
  • Xcode 14.2でAppleScript App Templateを復活させる
  • 2022年に書いた価値あるAppleScript
  • ChatGPTで文章のベクトル化(Embedding)
  • 新発売:AppleScriptからSiriを呼び出そう!
  • iWork 12.2がリリースされた
  • 従来と異なるmacOS 13の性格?
  • 新発売:CotEditor Scripting Book with AppleScript
  • macOS 13対応アップデート:AppleScript実践的テクニック集(1)GUI Scripting
  • AS関連データの取り扱いを容易にする(はずの)privateDataTypeLib
  • macOS 13でNSNotFoundバグふたたび
  • macOS 12.5.1、11.6.8でFinderのselectionでスクリーンショット画像をopenできない問題
  • ChatGPTでchatに対する応答文を取得
  • 新発売:iWork Scripting Book with AppleScript
  • Finderの隠し命令openVirtualLocationが発見される
  • macOS 13.1アップデートでスクリプトエディタの挙動がようやくまともに
  • あのコン過去ログビューワー(暫定版)

Tags

10.11savvy (1101) 10.12savvy (1242) 10.13savvy (1390) 10.14savvy (586) 10.15savvy (434) 11.0savvy (277) 12.0savvy (185) 13.0savvy (55) CotEditor (60) Finder (47) iTunes (19) Keynote (98) NSAlert (60) NSArray (51) NSBezierPath (18) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (51) NSDictionary (27) NSFileManager (23) NSFont (18) 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 (56) Pages (37) Safari (41) Script Editor (20) WKUserContentController (21) WKUserScript (20) WKUserScriptInjectionTimeAtDocumentEnd (18) WKWebView (23) WKWebViewConfiguration (22)

カテゴリー

  • 2D Bin Packing
  • 3D
  • AirDrop
  • AirPlay
  • Animation
  • AppleScript Application on Xcode
  • beta
  • Bluetooth
  • Books
  • boolean
  • bounds
  • Bug
  • Calendar
  • call by reference
  • Clipboard
  • Code Sign
  • Color
  • Custom Class
  • dialog
  • drive
  • 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
  • Machine Learning
  • Map
  • Markdown
  • Menu
  • Metadata
  • MIDI
  • MIME
  • Natural Language Processing
  • Network
  • news
  • Noification
  • Notarization
  • Number
  • Object control
  • OCR
  • OSA
  • 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)
  • 未分類

アーカイブ

  • 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