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

カテゴリー: list

現在のスライドと次のスライドでオーバーラップしている画像とグループを検出して位置をそろえる

Posted on 9月 10, 2020 by Takaaki Naganoya

Keynoteの最前面の書類で、現在表示中のスライドと次のスライドの間で、矩形座標が重なっている「画像」と「グループアイテム」(複数のオブジェクトをグループ化したアイテム)を検出して、現在のスライドの開始位置に場所をそろえるAppleScriptです。

# 最初掲載したもの(v1)は、動作しているものの処理内容に誤りがあったので修正しました(v2)

連続したスライド上に画面図を配置して、その画面図の位置をそろえるためのものです。何回か書いたような気がします。見た目より書くのが大変ではないので、ついつい書いてしまう処理です。

単にそれぞれの対象候補のオブジェクトの矩形開始座標と幅&高さをリスト化して、それをNSRectに変換して重ね合わせが発生していないかをCocoaの機能で判定しているだけです。この、一番めんどくさい部分をCocoaに丸投げしているので、おおよそ知性というものを感じさせないレベルのScriptです。

画像やグループアイテム 以外の表オブジェクト同士の重なりあいの検出を行うものに書き換えるのは簡単ですが、複数のオブジェクトの重なり合いが発生している場合には対処できません。

AppleScript名:現在のスライドと次のスライドでオーバーラップしている画像とグループを検出して位置をそろえる v2.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/09/10
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

tell application "Keynote"
  set dCount to count every document
  
if dCount = 0 then return –ドキュメントがオープンしていないと処理終了
  
  
tell front document
    set allNum to count every slide
    
if allNum < 2 then return –slideの枚数が少なかった場合に処理終了
    
    
set curSlide to current slide
    
if allNum = curSlide then return –current slideが末尾だった場合処理終了
    
    
set sNum to slide number of curSlide
    
set nextSlide to slide (sNum + 1)
    
    
–最初のページ(スライド)からオブジェクトを収集
    
tell current slide
      set curObj1 to every image
      
set curObj2 to every group
      
set curObjList to curObj1 & curObj2
      
if curObjList = {} then return
    end tell
    
    
–次のページ(スライド)からオブジェクトを収集
    
tell nextSlide
      set nextObj1 to every image
      
set nextObj2 to every group
      
set nextObjList to nextObj1 & nextObj2
      
if nextObjList = {} then return
    end tell
    
    
set nexObjRes to calcOverlappedObj(curObjList, nextObjList) of me
    
repeat with i in nexObjRes
      copy i to {origID, targID}
      
set aOrigObj to contents of item origID of curObjList
      
set aTargObj to contents of item origID of nextObjList
      
set origPos to position of aOrigObj
      
set position of aTargObj to origPos
    end repeat
    
    
set current slide to slide sNum
  end tell
end tell

–与えられた2つのリストに入っているKeynoteオブジェクトの矩形座標が重なっているものをIDペアで出力する
–同時に複数のオブジェクトが重なっていないことが前提
on calcOverlappedObj(objList1, objList2)
  tell application "Keynote"
    –最初のページのオブジェクトからオブジェクトIDとNSRectからなるリストを作成
    
set objRecList1 to {}
    
set aCount to 1
    
repeat with i in objList1
      if contents of i is not equal to {} then
        set {x1, y1} to position of i
        
set aRect to {origin:{x:x1, y:y1}, |size|:{|width|:(width of i), |height|:(height of i)}}
        
        
set the end of objRecList1 to {objID:aCount, rect:aRect}
      end if
      
set aCount to aCount + 1
    end repeat
    
    
–次のページのオブジェクトからオブジェクトIDとNSRectからなるリストを作成
    
set objRecList2 to {}
    
set aCount to 1
    
repeat with i in objList2
      if contents of i is not equal to {} then
        set {x1, y1} to position of i
        
set aRect to {origin:{x:x1, y:y1}, |size|:{|width|:(width of i), |height|:(height of i)}}
        
        
set the end of objRecList2 to {objID:aCount, rect:aRect}
      end if
      
set aCount to aCount + 1
    end repeat
    
    
–最初のページのオブジェクトと次のページのオブジェクトで矩形エリアが重なっているオブジェクトを抽出してそれぞれのIDをペアにしたリストを作成
    
set matchList to {}
    
repeat with i in objRecList1
      
      
set origRect to rect of i
      
set origID to objID of i
      
      
repeat with ii in objRecList2
        
        
set targRect to rect of ii
        
set targID to objID of ii
        
set tRes to detectRectanglesCollision(origRect, targRect) of me
        
        
if tRes = true then
          set the end of matchList to {origID, targID}
        end if
      end repeat
      
    end repeat
    
    
return matchList
  end tell
end calcOverlappedObj

–NSRect同士の衝突判定
on detectRectanglesCollision(aRect, bRect)
  set a1Res to (current application’s NSIntersectionRect(aRect, bRect)) as {record, list}
  
set tmpClass to class of a1Res
  
  
if tmpClass = record then
    –macOS 10.10, 10.11, 10.12
    
return not (a1Res = {origin:{x:0.0, y:0.0}, |size|:{width:0.0, height:0.0}})
  else if tmpClass = list then
    –macOS 10.13 or later
    
return not (a1Res = {{0.0, 0.0}, {0.0, 0.0}})
  end if
end detectRectanglesCollision

★Click Here to Open This Script 

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

指定の言語コードを、指定のLocaleの表現で、言語名称に

Posted on 8月 14, 2020 by Takaaki Naganoya

配列に入れた言語コードに対して、指定のLocaleの言語による表現で、言語名称を求めるAppleScriptです。

AppleScript名:指定の言語コードを、指定のLocaleの表現で、言語名称に.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/08/14
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set langList to {"en", "ru", "ja"}
set aList to getLocalizedLangNameList(langList, "ja_JP") of me
–> {"英語", "ロシア語", "日本語"}

set aList to getLocalizedLangNameList(langList, "en_US") of me
–> {"English", "Russian", "Japanese"}

set aList to getLocalizedLangNameList(langList, "zh-Hans") of me
—> {"英文", "俄文", "日文"}

on getLocalizedLangNameList(langList, aLocaleID)
  set aLocale to (current application’s NSLocale’s localeWithLocaleIdentifier:aLocaleID)
  
set langLocalizedList to {}
  
repeat with i in langList
    set aLang to getLangNameWithLocale(i, aLocale) of me
    
set the end of langLocalizedList to aLang
  end repeat
  
  
return langLocalizedList
end getLocalizedLangNameList

on getLangNameWithLocale(langCode, aLocale)
  set aLangName to (aLocale’s displayNameForKey:(current application’s NSLocaleIdentifier) value:langCode) as string
  
return aLangName
end getLangNameWithLocale

★Click Here to Open This Script 

Posted in Language list Locale | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy | Leave a comment

指定の言語コードを、デフォルトのLocaleの表現で、言語名称に

Posted on 8月 14, 2020 by Takaaki Naganoya

配列変数に入れた言語コードを、デフォルトのLocaleの言語による表現で、言語名称を求めるAppleScriptです。

AppleScript名:指定の言語コードを、デフォルトのLocaleの表現で、言語名称に.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/08/14
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set langList to {"en", "ru", "ja"}
set aList to getLocalizedLangNameList(langList) of me
–> {"英語", "ロシア語", "日本語"}

on getLocalizedLangNameList(langList)
  set aLocale to (current application’s NSLocale’s currentLocale())
  
set langLocalizedList to {}
  
repeat with i in langList
    set aLang to getLangNameWithLocale(i, aLocale) of me
    
set the end of langLocalizedList to aLang
  end repeat
  
  
return langLocalizedList
end getLocalizedLangNameList

on getLangNameWithLocale(langCode, aLocale)
  set aLangName to (aLocale’s displayNameForKey:(current application’s NSLocaleIdentifier) value:langCode) as string
  
return aLangName
end getLangNameWithLocale

★Click Here to Open This Script 

Posted in Language list Locale | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy | Leave a comment

指定TTSボイスキャラクタの読み上げ例文テキストを取得

Posted on 7月 6, 2020 by Takaaki Naganoya

指定のテキスト読み上げ(Text To Speech)ボイスキャラクターの読み上げ例文テキストを取得して実際に読み上げるAppleScriptです。

TTS音声は言語や性別、年齢、高音質かどうかなどの情報を持っているので、これらを指定して絞り込むことが可能です。また、指定TTS音声キャラクターの例文テキストもこのように取得できます。

AppleScript名:指定TTSボイスキャラクタの読み上げ例文テキストを取得.scpt
— Created 2015-08-25 by Takaaki Naganoya
— Modified 2015-08-26 by Shane Stanley, Takaaki Naganoya
— Modified 2020-07-06 by Takaaki Naganoya
— 2020 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use scripting additions

set vList to getVoiceNames() of me
using terms from scripting additions
  set aTargTTSVoiceName to contents of (choose from list vList)
end using terms from

using terms from scripting additions
  set v1Res to getDemoText(aTargTTSVoiceName) of me
  
say v1Res using aTargTTSVoiceName
end using terms from

–Get TTS Voice sample text
on getDemoText(aName as string)
  set vList to getVoiceNames() of me
  
if aName is not in vList then return ""
  
set anID to getSpecifiedVoiceIDfromVoiceName(aName) of me
  
  
set aDemoText to ((current application’s NSSpeechSynthesizer’s attributesForVoice:anID)’s VoiceDemoText)
  
return aDemoText as string
end getDemoText

–Get all voice names
on getVoiceNames()
  –Make Blank Array
  
set outArray to current application’s NSMutableArray’s arrayWithObject:{}
  
set aList to {}
  
  
–Make Installed Voice List
  
set nameList to current application’s NSSpeechSynthesizer’s availableVoices()
  
repeat with i in nameList
    set j to contents of i
    
    
set aDic to ((current application’s NSSpeechSynthesizer’s attributesForVoice:j))
    
    
set aDemoText to (aDic’s VoiceDemoText) as string
    
set aName to (aDic’s VoiceName) as string
    
    
set the end of aList to aName
  end repeat
  
  
return aList as list
end getVoiceNames

–Voice Name –> Voice ID
on getSpecifiedVoiceIDfromVoiceName(VoiceName as string)
  set outArray to current application’s NSMutableArray’s arrayWithObject:{}
  
  
set aList to current application’s NSSpeechSynthesizer’s availableVoices()
  
set bList to aList as list
  
  
repeat with i in bList
    set j to contents of i
    
set aDic to (current application’s NSSpeechSynthesizer’s attributesForVoice:j)
    (
outArray’s addObject:aDic)
  end repeat
  
  
–Filter Voice
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat_("VoiceName == %@", VoiceName)
  
  
set filteredArray to outArray’s filteredArrayUsingPredicate:aPredicate
  
set aReList to (filteredArray’s valueForKey:"VoiceIdentifier") as list
  
  
if length of aReList = 1 then
    return first item of aReList
  else
    return ""
  end if
end getSpecifiedVoiceIDfromVoiceName

★Click Here to Open This Script 

Posted in list Record System Text to Speech | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSMutableArray NSPredicate NSSpeechSynthesizer | Leave a comment

linked listとvector

Posted on 7月 5, 2020 by Takaaki Naganoya

今日その存在を初めて知りました。linked listとvector。2020年になって知らない予約語があったとは、目が覚めるような思いです。

AppleScriptの隠れ予約語なんだとか。たまにこういう「隠れ仕様」が転がっていて息が止まりそうになります。

set x to {{{1, 2, 3}}} as linked list
--> {1,2,3}

リストの一種らしいのですが、Language Guideにも掲載されていないので、正直よくわかりません。

不用意に多次元化してしまったlistを最低限の次元に落としてくれるようです(linked list)。

かといって、有効活用したいとかいうことは考えないほうがいいようです(Apple側でも検証していないでしょうね、いろんなランタイム環境での実行内容とか)。

set x to {{{1, 2, 3}}} as linked list
--> {1,2,3}

set a to length of x
--> 3

set b to class of x
--> list

--set the end of x to 4
--> error "end of {1, 2, 3}を4に設定できません。" number -10006 from last insertion point of {1, 2, 3}

--set beginning of x to 0
--> error "beginning of {1, 2, 3}を0に設定できません。" number -10006 from insertion point 1 of {1, 2, 3}

set x to x & 6
--> {1, 2, 3, 6}

vectorもlinked list同様な感じではあるものの、要素をbeginningとendに追加できるようで。

set aVec to {{{1, 2, 3}}} as vector
set aLen to length of aVec
--> 1

set aClass to class of aVec
--> list

set the beginning of aVec to 0
--> {0, {{1, 2, 3}}}

set the end of aVec to 9
--> {0, {{1, 2, 3}}, 9}

不定クラスの予約語「anything」もその筋での評判がよろしくありません。macOS 10.14以降のスクリプトエディタでようやく誤解釈されなくなりましたが、それまではASObjC環境で「list of string or string」と解釈されてしまっていました。一方でScript Debugger上では「any」と解釈され、足並みが揃っていません。

明確に予約語がないにもかかわらず、機能が実装されているのが「as «class utf8»」。機能がないと致命的に問題が出るので、なくなることはないと思います。

edama2さんと本件について雑談していたら、「見かけたことがある」とのことで、その場で調べてみたら見つかりました。

http://mtlab.ecn.fpu.ac.jp/WSM_1999/990521193527.html

Posted in How To list | Tagged 10.14savvy 10.15savvy 11.0savvy | 1 Comment

Keynote書類上の画像を実パスを求めてアーカイブ展開してオープン

Posted on 7月 4, 2020 by Takaaki Naganoya

Keynote書類上の指定画像のアーカイブ中のパスを求め、指定画像のファイル名と照合し、当該画像ファイルのみアーカイブ展開してからPreview.appでオープンするAppleScriptです。

Keynote書類には2つの形式(パッケージ形式、フラット形式)があり、現在のデフォルトはフラット形式です。

パッケージ形式についてはFinder上でパッケージバンドルを表示させて、内部データ構造を実際に見られるようになっています。

では、フラット形式はどうかといえば、上記のパッケージ形式データをZip圧縮して拡張子を「.key」に変更したものです。

そのため、拡張子を「.key」から「.zip」に付け替えて、アーカイブ展開すると、実際にパッケージ内部のファイルにアクセスできます。

本Scriptは、フラット形式のKeynote書類に対して動作します。パッケージ形式は想定していません(パッケージ形式は単にファイル構造にアクセスすればよいだけなので)。

画像を貼り付けたスライドを表示した状態で本AppleScriptを実行すると、スライド上に貼り付けた画像をデスクトップフォルダに展開し、Previw.appでオープンします。1回実行するとデスクトップに画像ファイルの名前のフォルダが作られ、その中に画像が展開されています。この状態でScriptを再実行すると、フォルダ名が重複するためエラーになります。再実行したい場合にはデスクトップ上の画像名のフォルダを削除しておいてください。

指定Keynote書類の、指定スライド上にある指定イメージについては、ファイル名がわかるだけでパスやデータを取得できるわけではありません。

そこで、フラット形式のKeynote書類中の画像一覧を取得し、このファイル名と符合するものをピックアップします。ただし、ファイル名が完全一致するわけではなく、オリジナルのファイル名が「someImage.png」だった場合に、「someImage-221.png」といったファイル名が見つかります。

また、見つかるのは実ファイルだけでなくプレビュー用の「someImage-small-221.png」といったものも入っています。このプレビュー用イメージについてはスキップしています。

その後、さまざまな処理を行なってもよいでしょうけれども、とりあえず現状ではPreview.appでファイルをオープンしています。

AppleScript名:Keynote書類上の画像をアーカイブ展開して実パスを求めて展開.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/07/04
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

tell application "Keynote"
  set dCount to count (every document)
  
if dCount = 0 then return
  
  
tell front document
    set myPath to (file of it)
    
if myPath = missing value then return false –Unsaved
    
    
tell current slide
      tell image 1
        set aFile to file name
        
–> "switchControl.png"
      end tell
    end tell
  end tell
end tell

set myPOSIXPath to POSIX path of (myPath as alias)

–Extract document internal image paths by extracting Keynote’s zip archive
set dList to getInternalImagesWithinKeynote(myPath) of me

–Extract file name and ext from image 1 path
set pPath to POSIX path of aFile
set {aName, aExt} to getExtAndFilenameFromPath(pPath) of me

–Filter Keynote internal image list by image 1’s file name and ext
set theArray to current application’s NSArray’s arrayWithArray:dList
set thePred to current application’s NSPredicate’s predicateWithFormat_("self.pathExtension == %@ && self.lastPathComponent beginswith %@ ", aExt, aName)
set bList to (theArray’s filteredArrayUsingPredicate:thePred) as list
–> {"Data/switchControl-226.png", "Data/switchControl-small-227.png"}

–Extrat file
set exF to false

repeat with i in bList
  set outName to getFilenameAndExtFromPath(i) of me
  
  
if outName does not contain "-small-" then –Skip Preview Image
    set outPath to POSIX path of (path to desktop) & outName
    
set bRes to do shell script "unzip -j " & quoted form of myPOSIXPath & " " & quoted form of i & " -d " & " " & outPath
    
    
set extractPath to POSIX path of (path to desktop) & outName & "/" & outName
    
do shell script "open " & quoted form of extractPath –Open for test
    
    
set exF to true
  end if
end repeat

if exF = false then return false

–Keynote書類中の画像ファイル一覧を取得
on getInternalImagesWithinKeynote(myPath)
  set kPath to POSIX path of myPath
  
set aRes to do shell script "unzip -Z1 " & quoted form of kPath & " | grep ^Data/"
  
set aList to paragraphs of aRes
  
return aList
end getInternalImagesWithinKeynote

–ファイルパスからファイル名部分と拡張子を分離
on getExtAndFilenameFromPath(aPOSIXpath)
  set pathString to current application’s NSString’s stringWithString:aPOSIXpath
  
set aStr to pathString’s lastPathComponent()
  
set aExt to (aStr’s pathExtension())
  
set bStr to aStr’s stringByDeletingPathExtension()
  
return {bStr as string, aExt as string}
end getExtAndFilenameFromPath

–ファイルパスからファイル名部分のみ取得
on getFilenameAndExtFromPath(aPOSIXpath)
  set pathString to current application’s NSString’s stringWithString:aPOSIXpath
  
set aStr to pathString’s lastPathComponent()
  
return aStr as string
end getFilenameAndExtFromPath

★Click Here to Open This Script 

Posted in file Image list | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy Keynote | Leave a comment

chartJSでアニメーション円グラフをダイアログ表示 v2.scptd

Posted on 6月 30, 2020 by Takaaki Naganoya

アラートダイアログ上にWkWebViewを作成し、その上でChart.jsによる円グラフを表示するAppleScriptです。


▲実行するとテーマ選択ののちにグラフ表示を行います


–> Download chartJSPieChartDemo.scptd(Script Bundle with Lirbrary and HTML)

Chart.jsは、ダイアグラムやフローチャートなどを描画するJavaScriptのライブラリです。割とデータのカスタマイズがしやすい感じです。

AppleScript名:chartJSでアニメーション円グラフをダイアログ表示 v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/06/26
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use webD : script "webDialogLib"

set aRes to first item of (choose from list {"light1", "light2", "dark1", "dark2"} with prompt "Choose theme")

set aList to {{y:45.43, label:"Chrome"}, {y:32.4, label:"Safari"}, {y:6.67, label:"Firefox"}, {y:5.41, label:"Microsoft Edge"}, {y:5.26, label:"Internet Explorer"}, {y:1.19, label:"Samsung Internet"}}
set myTitle to "Desktop Browser Market Share in Japan May 2020"

–https://canvasjs.com/javascript-charts/pie-chart-legends/
set mePath to path to me
set resPath to (mePath as string) & "Contents:Resources:index.html"
set myStr to (read (resPath as alias) as «class utf8») as string

set aJsonStr to array2DToJSONArray(aList) of me
set aString to current application’s NSString’s stringWithFormat_(myStr, aRes as string, myTitle, aJsonStr) as string

set paramObj to {myMessage:"Animation Pie Chart", mySubMessage:"This is a canvasJS test", htmlStr:aString, jsDelimiters:{"<script>", "</script>"}, viewSize:{900, 620}}

webD’s displayWebDialog(paramObj)

on array2DToJSONArray(aList)
  set anArray to current application’s NSMutableArray’s arrayWithArray:aList
  
set jsonData to current application’s NSJSONSerialization’s dataWithJSONObject:anArray options:(0 as integer) |error|:(missing value)
  
set resString to current application’s NSString’s alloc()’s initWithData:jsonData encoding:(current application’s NSUTF8StringEncoding)
  
return resString
end array2DToJSONArray

★Click Here to Open This Script 

Posted in dialog JSON list Record | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSJSONSerialization NSMutableArray NSString | Leave a comment

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

Posted on 6月 29, 2020 by Takaaki Naganoya

CotEditorの最前面のドキュメントで選択中の、JavaScriptのrecord in listをAppleScriptのオブジェクトに変換するAppleScriptです。

こんな風にJavaScriptのプログラム中のrecord in listを選択しておいてScriptを実行すると、

AppleScriptのオブジェクトに変換します。

AppleScript名:CotEditor上で選択中のJavaScriptのrecord in listをASのオブジェクトに変換.scpt
— Created 2015-07-20 by Takaaki Naganoya
— 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

tell application "CotEditor"
  tell front document
    set jsonText to contents of selection
  end tell
end tell

set a to repChar(jsonText, "[", "{") of me
set b to repChar(a, "]", "}") of me
set c to repChar(b, string id 10, "") of me
set d to repChar(c, tab, "") of me

try
  set e to run script d
  
set f to convToStr(e) of textKit
  
  
tell application "CotEditor"
    make new document
    
tell front document
      set contents to f
    end tell
  end tell
on error erM
  display dialog erM
  
end try

–文字置換
on repChar(origText as string, targChar as string, repChar as string)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to targChar
  
set tmpList to text items of origText
  
set AppleScript’s text item delimiters to repChar
  
set retText to tmpList as string
  
set AppleScript’s text item delimiters to curDelim
  
return retText
end repChar

–リストでもレコードでもなんでも文字列化して返すキット
script textKit
  
  
on convToStr(aRec)
    set aClass to (class of aRec) as string
    
    
if (aClass = "integer") or (aClass = "number") or (aClass = "real") or (aClass = "string") or (aClass = "text") or (aClass = "Unicode text") or (aClass = "boolean") then
      set aRes to aRec as string
    else if aClass is "list" then
      set aRes to listToString(aRec)
    else if aClass is "record" then
      set aRes to recToString(aRec)
    else
      try
        set aRes to aRec as string
      on error
        –アプリケーションのオブジェクトとかはエラーで返す
        
return false
      end try
    end if
    
    
return aRes
    
  end convToStr
  
  
  
–レコードをStringに変換
  
  
–エラートラップを使って、わざとエラーを発生させ、エラーメッセージからレコードをstringに変換する
  
on recToString(aRec)
    
    
–レコードを無理矢理stringにcastして、エラーメッセージを取得する
    
try
      set a to aRec as string –ここでエラー発生
    on error aMes
      set a to aMes
    end try
    
    
–エラーメッセージ文字列から、元のレコードの情報を組み立てる
    
set b to trimStrFromTo(a, "{", "}")
    
set b to "{" & b & "}"
    
    
return b
  end recToString
  
  
  
on trimStrFromTo(aStr, fromStr, toStr)
    –fromStrは前から探す
    
if fromStr is not equal to "" then
      set sPos to (offset of fromStr in aStr) + 1
    else
      set sPos to 1
    end if
    
    
–toStrは後ろから探す
    
if toStr is not equal to "" then
      set b to (reverse of characters of aStr) as string
      
set ePos to (offset of toStr in b)
      
set ePos to ((length of aStr) – ePos)
    else
      set ePos to length of aStr
    end if
    
set aRes to text sPos thru ePos of aStr
    
    
return aRes
    
  end trimStrFromTo
  
  
  
–リストおよびリストに入ったレコードをStringに変換
  
  
on listToString(aList)
    set listText to {"{"}
    
set quotChar to ASCII character 34
    
set firstFlag to true
    
    
repeat with i in aList
      set j to contents of i
      
set aClass to (class of i) as string
      
if (aClass = "integer") or (aClass = "number") or (aClass = "real") or (aClass = "boolean") then
        set the end of listText to (getFirst(firstFlag) of me & j as text)
        
set firstFlag to false
      else if (aClass = "string") or (aClass = "text") or (aClass = "Unicode text") then
        set the end of listText to ((getFirst(firstFlag) of me & quotChar & j as text) & quotChar)
        
set firstFlag to false
      else if aClass is "list" then
        set the end of listText to (getFirst(firstFlag) & listToString(j)) –ちょっと再帰処理
        
set firstFlag to false
      else if aClass is "record" then
        set the end of listText to (getFirst(firstFlag) & recToString(j))
        
set firstFlag to false
      end if
    end repeat
    
    
set the end of listText to "}"
    
set listText to listText as text
    
    
return listText
  end listToString
  
  
on getFirst(aFlag)
    if aFlag = true then return ""
    
if aFlag = false then return ", "
  end getFirst
  
end script

★Click Here to Open This Script 

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

AMChartsで円グラフをダイアログ上に表示 v3

Posted on 6月 27, 2020 by Takaaki Naganoya

アラートダイアログ上にWkWebViewを作成し、その上でAMChartsによる円グラフを表示するAppleScriptです。

ダイアログでテーマ選択したのちに、グラフ表示を行います。

—> Download ampiechartSample(AppleScript bundle with Script Library and HTMLs)

AppleScript名:AMChartsで円グラフをダイアログ上に表示 v3.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/06/25
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use webD : script "webDialogLib"

set themeList to {"dark", "dataviz", "material", "kelly", "frozen", "moonrisekingdom", "spiritedaway"}

set aSel to (choose from list themeList with prompt "Select Theme")
if aSel = false then
  set aTheme to false
  
set aHTML to "index_notheme.html"
else
  set aTheme to contents of first item of aSel
  
if aTheme = "dark" then
    set aTheme to false
    
set aHTML to "index_dark.html"
  else
    set aHTML to "index.html"
  end if
end if

set aList to {{label:"ひよこ王国", value:403}, {label:"ぴよぴよ連邦", value:301}, {label:"ぴよランド", value:101}, {label:"ぴよー", value:65}}
set bList to sortRecListByLabel(aList, {"value"}, {false}) of me –降順ソート

–https://www.amcharts.com/demos/pie-chart/
set mePath to path to me
set resPath to (mePath as string) & "Contents:Resources:" & aHTML
set myStr to (read (resPath as alias) as «class utf8») as string

set jsonStr to array2DToJSONArray(bList) of me as string

if aTheme = false then
  set aString to current application’s NSString’s stringWithFormat_(myStr, jsonStr) as string
else
  set aString to current application’s NSString’s stringWithFormat_(myStr, aTheme, aTheme, jsonStr) as string
end if

set paramObj to {myMessage:"Simple Pie Chart", mySubMessage:"This is a AMCharts test", htmlStr:aString, jsDelimiters:{"<script>", "</script>"}, viewSize:{1000, 550}}

webD’s displayWebDialog(paramObj)

on array2DToJSONArray(aList)
  set anArray to current application’s NSMutableArray’s arrayWithArray:aList
  
set jsonData to current application’s NSJSONSerialization’s dataWithJSONObject:anArray options:(0 as integer) |error|:(missing value)
  
set resString to current application’s NSString’s alloc()’s initWithData:jsonData encoding:(current application’s NSUTF8StringEncoding)
  
return resString
end array2DToJSONArray

–リストに入れたレコードを、指定の属性ラベルの値でソート
on sortRecListByLabel(aRecList as list, aLabelStr as list, ascendF as list)
  set aArray to current application’s NSArray’s arrayWithArray:aRecList
  
  
set aCount to length of aLabelStr
  
set sortDescArray to current application’s NSMutableArray’s new()
  
repeat with i from 1 to aCount
    set aLabel to (item i of aLabelStr)
    
set aKey to (item i of ascendF)
    
set sortDesc to (current application’s NSSortDescriptor’s alloc()’s initWithKey:aLabel ascending:aKey)
    (
sortDescArray’s addObject:sortDesc)
  end repeat
  
  
return (aArray’s sortedArrayUsingDescriptors:sortDescArray) as list
end sortRecListByLabel

★Click Here to Open This Script 

Posted in dialog list Sort | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSArray NSJSONSerialization NSMutableArray NSSortDescriptor NSString | Leave a comment

AMChartsでバブルチャート+世界地図をダイアログ上に表示 v2

Posted on 6月 26, 2020 by Takaaki Naganoya

アラートダイアログ上にWkWebViewを作成し、その上でAMChartsによるバブルチャートつき世界地図を表示するAppleScriptです。

–> Download amBubbleMap.zip(Script Bundle with AppleScript Library and HTML)

表示用のデータをAppleScriptのRecord(をListに入れたもの)に変換して、外部から供給するようにして、表示するさいにJSONに変換してHTMLに差し込んで表示しています。

正直、record形式にすると編集が大変なような気がするので、プログラムリスト中から外部に追い出して、plistとかJSONとかいろいろ他の形式で保持しておくといいと思います。もちろん、AppleScriptらしくNumbersの表データ中にデータを展開してもよいのですが、「ならNumbersでグラフ表示させたほうがよいのでは?」というところなので、あえて触れませんでした。

AMChart掲載のグラフはデータを差し込みやすくていいですね。

AppleScript名:AMChartsでバブルチャート+世界地図をダイアログ上に表示 v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/06/25
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use webD : script "webDialogLib"

set aList to retData() of me
set jStr to array2DToJSONArray(aList) of me as string

–https://www.zingchart.com/
set mePath to path to me
set resPath to (mePath as string) & "Contents:Resources:index.html"
set myStr to read (resPath as alias) as «class utf8»

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

set paramObj to {myMessage:"Map with Bubbles", mySubMessage:"This is a AMCharts test", htmlStr:aString, jsDelimiters:{"<script>", "</script>"}, viewSize:{1000, 620}}

webD’s displayWebDialog(paramObj)

on array2DToJSONArray(aList)
  set anArray to current application’s NSMutableArray’s arrayWithArray:aList
  
set jsonData to current application’s NSJSONSerialization’s dataWithJSONObject:anArray options:(0 as integer) |error|:(missing value)
  
set resString to current application’s NSString’s alloc()’s initWithData:jsonData encoding:(current application’s NSUTF8StringEncoding)
  
return resString
end array2DToJSONArray

on retData()
  return {{|id|:"AF", |name|:"Afghanistan", value:32358260, |color|:"#ff0000"}, {|id|:"AL", |name|:"Albania", value:3215988, |color|:"#00ff00"}, {|id|:"DZ", |name|:"Algeria", value:35980193, |color|:"#0000ff"}, {|id|:"AO", |name|:"Angola", value:19618432, |color|:"#0000ff"}, {|id|:"AR", |name|:"Argentina", value:40764561, |color|:"#ffff00"}, {|id|:"AM", |name|:"Armenia", value:3100236, |color|:"#00ff00"}, {|id|:"AU", |name|:"Australia", value:22605732, |color|:"#8aabb0"}, {|id|:"AT", |name|:"Austria", value:8413429, |color|:"#00ff00"}, {|id|:"AZ", |name|:"Azerbaijan", value:9306023, |color|:"#00ff00"}, {|id|:"BH", |name|:"Bahrain", value:1323535, |color|:"#ff0000"}, {|id|:"BD", |name|:"Bangladesh", value:150493658, |color|:"#ff0000"}, {|id|:"BY", |name|:"Belarus", value:9559441, |color|:"#00ff00"}, {|id|:"BE", |name|:"Belgium", value:10754056, |color|:"#00ff00"}, {|id|:"BJ", |name|:"Benin", value:9099922, |color|:"#0000ff"}, {|id|:"BT", |name|:"Bhutan", value:738267, |color|:"#ff0000"}, {|id|:"BO", |name|:"Bolivia", value:10088108, |color|:"#ffff00"}, {|id|:"BA", |name|:"Bosnia and Herzegovina", value:3752228, |color|:"#00ff00"}, {|id|:"BW", |name|:"Botswana", value:2030738, |color|:"#0000ff"}, {|id|:"BR", |name|:"Brazil", value:196655014, |color|:"#ffff00"}, {|id|:"BN", |name|:"Brunei", value:405938, |color|:"#ff0000"}, {|id|:"BG", |name|:"Bulgaria", value:7446135, |color|:"#00ff00"}, {|id|:"BF", |name|:"Burkina Faso", value:16967845, |color|:"#0000ff"}, {|id|:"BI", |name|:"Burundi", value:8575172, |color|:"#0000ff"}, {|id|:"KH", |name|:"Cambodia", value:14305183, |color|:"#ff0000"}, {|id|:"CM", |name|:"Cameroon", value:20030362, |color|:"#0000ff"}, {|id|:"CA", |name|:"Canada", value:34349561, |color|:"#888822"}, {|id|:"CV", |name|:"Cape Verde", value:500585, |color|:"#0000ff"}, {|id|:"CF", |name|:"Central African Rep.", value:4486837, |color|:"#0000ff"}, {|id|:"TD", |name|:"Chad", value:11525496, |color|:"#0000ff"}, {|id|:"CL", |name|:"Chile", value:17269525, |color|:"#ffff00"}, {|id|:"CN", |name|:"China", value:1.347565324E+9, |color|:"#ff0000"}, {|id|:"CO", |name|:"Colombia", value:46927125, |color|:"#ffff00"}, {|id|:"KM", |name|:"Comoros", value:753943, |color|:"#0000ff"}, {|id|:"CD", |name|:"Congo, Dem. Rep.", value:67757577, |color|:"#0000ff"}, {|id|:"CG", |name|:"Congo, Rep.", value:4139748, |color|:"#0000ff"}, {|id|:"CR", |name|:"Costa Rica", value:4726575, |color|:"#888822"}, {|id|:"CI", |name|:"Cote d’Ivoire", value:20152894, |color|:"#0000ff"}, {|id|:"HR", |name|:"Croatia", value:4395560, |color|:"#00ff00"}, {|id|:"CU", |name|:"Cuba", value:11253665, |color|:"#888822"}, {|id|:"CY", |name|:"Cyprus", value:1116564, |color|:"#00ff00"}, {|id|:"CZ", |name|:"Czech Rep.", value:10534293, |color|:"#00ff00"}, {|id|:"DK", |name|:"Denmark", value:5572594, |color|:"#00ff00"}, {|id|:"DJ", |name|:"Djibouti", value:905564, |color|:"#0000ff"}, {|id|:"DO", |name|:"Dominican Rep.", value:10056181, |color|:"#888822"}, {|id|:"EC", |name|:"Ecuador", value:14666055, |color|:"#ffff00"}, {|id|:"EG", |name|:"Egypt", value:82536770, |color|:"#0000ff"}, {|id|:"SV", |name|:"El Salvador", value:6227491, |color|:"#888822"}, {|id|:"GQ", |name|:"Equatorial Guinea", value:720213, |color|:"#0000ff"}, {|id|:"ER", |name|:"Eritrea", value:5415280, |color|:"#0000ff"}, {|id|:"EE", |name|:"Estonia", value:1340537, |color|:"#00ff00"}, {|id|:"ET", |name|:"Ethiopia", value:84734262, |color|:"#0000ff"}, {|id|:"FJ", |name|:"Fiji", value:868406, |color|:"#8aabb0"}, {|id|:"FI", |name|:"Finland", value:5384770, |color|:"#00ff00"}, {|id|:"FR", |name|:"France", value:63125894, |color|:"#00ff00"}, {|id|:"GA", |name|:"Gabon", value:1534262, |color|:"#0000ff"}, {|id|:"GM", |name|:"Gambia", value:1776103, |color|:"#0000ff"}, {|id|:"GE", |name|:"Georgia", value:4329026, |color|:"#00ff00"}, {|id|:"DE", |name|:"Germany", value:82162512, |color|:"#00ff00"}, {|id|:"GH", |name|:"Ghana", value:24965816, |color|:"#0000ff"}, {|id|:"GR", |name|:"Greece", value:11390031, |color|:"#00ff00"}, {|id|:"GT", |name|:"Guatemala", value:14757316, |color|:"#888822"}, {|id|:"GN", |name|:"Guinea", value:10221808, |color|:"#0000ff"}, {|id|:"GW", |name|:"Guinea-Bissau", value:1547061, |color|:"#0000ff"}, {|id|:"GY", |name|:"Guyana", value:756040, |color|:"#ffff00"}, {|id|:"HT", |name|:"Haiti", value:10123787, |color|:"#888822"}, {|id|:"HN", |name|:"Honduras", value:7754687, |color|:"#888822"}, {|id|:"HK", |name|:"Hong Kong, China", value:7122187, |color|:"#ff0000"}, {|id|:"HU", |name|:"Hungary", value:9966116, |color|:"#00ff00"}, {|id|:"IS", |name|:"Iceland", value:324366, |color|:"#00ff00"}, {|id|:"IN", |name|:"India", value:1.24149196E+9, |color|:"#ff0000"}, {|id|:"ID", |name|:"Indonesia", value:242325638, |color|:"#ff0000"}, {|id|:"IR", |name|:"Iran", value:74798599, |color|:"#ff0000"}, {|id|:"IQ", |name|:"Iraq", value:32664942, |color|:"#ff0000"}, {|id|:"IE", |name|:"Ireland", value:4525802, |color|:"#00ff00"}, {|id|:"IL", |name|:"Israel", value:7562194, |color|:"#ff0000"}, {|id|:"IT", |name|:"Italy", value:60788694, |color|:"#00ff00"}, {|id|:"JM", |name|:"Jamaica", value:2751273, |color|:"#888822"}, {|id|:"JP", |name|:"Japan", value:126497241, |color|:"#ff0000"}, {|id|:"JO", |name|:"Jordan", value:6330169, |color|:"#ff0000"}, {|id|:"KZ", |name|:"Kazakhstan", value:16206750, |color|:"#ff0000"}, {|id|:"KE", |name|:"Kenya", value:41609728, |color|:"#0000ff"}, {|id|:"KP", |name|:"Korea, Dem. Rep.", value:24451285, |color|:"#ff0000"}, {|id|:"KR", |name|:"Korea, Rep.", value:48391343, |color|:"#ff0000"}, {|id|:"KW", |name|:"Kuwait", value:2818042, |color|:"#ff0000"}, {|id|:"KG", |name|:"Kyrgyzstan", value:5392580, |color|:"#ff0000"}, {|id|:"LA", |name|:"Laos", value:6288037, |color|:"#ff0000"}, {|id|:"LV", |name|:"Latvia", value:2243142, |color|:"#00ff00"}, {|id|:"LB", |name|:"Lebanon", value:4259405, |color|:"#ff0000"}, {|id|:"LS", |name|:"Lesotho", value:2193843, |color|:"#0000ff"}, {|id|:"LR", |name|:"Liberia", value:4128572, |color|:"#0000ff"}, {|id|:"LY", |name|:"Libya", value:6422772, |color|:"#0000ff"}, {|id|:"LT", |name|:"Lithuania", value:3307481, |color|:"#00ff00"}, {|id|:"LU", |name|:"Luxembourg", value:515941, |color|:"#00ff00"}, {|id|:"MK", |name|:"Macedonia, FYR", value:2063893, |color|:"#00ff00"}, {|id|:"MG", |name|:"Madagascar", value:21315135, |color|:"#0000ff"}, {|id|:"MW", |name|:"Malawi", value:15380888, |color|:"#0000ff"}, {|id|:"MY", |name|:"Malaysia", value:28859154, |color|:"#ff0000"}, {|id|:"ML", |name|:"Mali", value:15839538, |color|:"#0000ff"}, {|id|:"MR", |name|:"Mauritania", value:3541540, |color|:"#0000ff"}, {|id|:"MU", |name|:"Mauritius", value:1306593, |color|:"#0000ff"}, {|id|:"MX", |name|:"Mexico", value:114793341, |color|:"#888822"}, {|id|:"MD", |name|:"Moldova", value:3544864, |color|:"#00ff00"}, {|id|:"MN", |name|:"Mongolia", value:2800114, |color|:"#ff0000"}, {|id|:"ME", |name|:"Montenegro", value:632261, |color|:"#00ff00"}, {|id|:"MA", |name|:"Morocco", value:32272974, |color|:"#0000ff"}, {|id|:"MZ", |name|:"Mozambique", value:23929708, |color|:"#0000ff"}, {|id|:"MM", |name|:"Myanmar", value:48336763, |color|:"#ff0000"}, {|id|:"NA", |name|:"Namibia", value:2324004, |color|:"#0000ff"}, {|id|:"NP", |name|:"Nepal", value:30485798, |color|:"#ff0000"}, {|id|:"NL", |name|:"Netherlands", value:16664746, |color|:"#00ff00"}, {|id|:"NZ", |name|:"New Zealand", value:4414509, |color|:"#8aabb0"}, {|id|:"NI", |name|:"Nicaragua", value:5869859, |color|:"#888822"}, {|id|:"NE", |name|:"Niger", value:16068994, |color|:"#0000ff"}, {|id|:"NG", |name|:"Nigeria", value:162470737, |color|:"#0000ff"}, {|id|:"NO", |name|:"Norway", value:4924848, |color|:"#00ff00"}, {|id|:"OM", |name|:"Oman", value:2846145, |color|:"#ff0000"}, {|id|:"PK", |name|:"Pakistan", value:176745364, |color|:"#ff0000"}, {|id|:"PA", |name|:"Panama", value:3571185, |color|:"#888822"}, {|id|:"PG", |name|:"Papua New Guinea", value:7013829, |color|:"#8aabb0"}, {|id|:"PY", |name|:"Paraguay", value:6568290, |color|:"#ffff00"}, {|id|:"PE", |name|:"Peru", value:29399817, |color|:"#ffff00"}, {|id|:"PH", |name|:"Philippines", value:94852030, |color|:"#ff0000"}, {|id|:"PL", |name|:"Poland", value:38298949, |color|:"#00ff00"}, {|id|:"PT", |name|:"Portugal", value:10689663, |color|:"#00ff00"}, {|id|:"PR", |name|:"Puerto Rico", value:3745526, |color|:"#888822"}, {|id|:"QA", |name|:"Qatar", value:1870041, |color|:"#ff0000"}, {|id|:"RO", |name|:"Romania", value:21436495, |color|:"#00ff00"}, {|id|:"RU", |name|:"Russia", value:142835555, |color|:"#00ff00"}, {|id|:"RW", |name|:"Rwanda", value:10942950, |color|:"#0000ff"}, {|id|:"SA", |name|:"Saudi Arabia", value:28082541, |color|:"#ff0000"}, {|id|:"SN", |name|:"Senegal", value:12767556, |color|:"#0000ff"}, {|id|:"RS", |name|:"Serbia", value:9853969, |color|:"#00ff00"}, {|id|:"SL", |name|:"Sierra Leone", value:5997486, |color|:"#0000ff"}, {|id|:"SG", |name|:"Singapore", value:5187933, |color|:"#ff0000"}, {|id|:"SK", |name|:"Slovak Republic", value:5471502, |color|:"#00ff00"}, {|id|:"SI", |name|:"Slovenia", value:2035012, |color|:"#00ff00"}, {|id|:"SB", |name|:"Solomon Islands", value:552267, |color|:"#8aabb0"}, {|id|:"SO", |name|:"Somalia", value:9556873, |color|:"#0000ff"}, {|id|:"ZA", |name|:"South Africa", value:50459978, |color|:"#0000ff"}, {|id|:"ES", |name|:"Spain", value:46454895, |color|:"#00ff00"}, {|id|:"LK", |name|:"Sri Lanka", value:21045394, |color|:"#ff0000"}, {|id|:"SD", |name|:"Sudan", value:34735288, |color|:"#0000ff"}, {|id|:"SR", |name|:"Suriname", value:529419, |color|:"#ffff00"}, {|id|:"SZ", |name|:"Swaziland", value:1203330, |color|:"#0000ff"}, {|id|:"SE", |name|:"Sweden", value:9440747, |color|:"#00ff00"}, {|id|:"CH", |name|:"Switzerland", value:7701690, |color|:"#00ff00"}, {|id|:"SY", |name|:"Syria", value:20766037, |color|:"#ff0000"}, {|id|:"TW", |name|:"Taiwan", value:23072000, |color|:"#ff0000"}, {|id|:"TJ", |name|:"Tajikistan", value:6976958, |color|:"#ff0000"}, {|id|:"TZ", |name|:"Tanzania", value:46218486, |color|:"#0000ff"}, {|id|:"TH", |name|:"Thailand", value:69518555, |color|:"#ff0000"}, {|id|:"TG", |name|:"Togo", value:6154813, |color|:"#0000ff"}, {|id|:"TT", |name|:"Trinidad and Tobago", value:1346350, |color|:"#888822"}, {|id|:"TN", |name|:"Tunisia", value:10594057, |color|:"#0000ff"}, {|id|:"TR", |name|:"Turkey", value:73639596, |color|:"#00ff00"}, {|id|:"TM", |name|:"Turkmenistan", value:5105301, |color|:"#ff0000"}, {|id|:"UG", |name|:"Uganda", value:34509205, |color|:"#0000ff"}, {|id|:"UA", |name|:"Ukraine", value:45190180, |color|:"#00ff00"}, {|id|:"AE", |name|:"United Arab Emirates", value:7890924, |color|:"#ff0000"}, {|id|:"GB", |name|:"United Kingdom", value:62417431, |color|:"#00ff00"}, {|id|:"US", |name|:"United States", value:313085380, |color|:"#888822"}, {|id|:"UY", |name|:"Uruguay", value:3380008, |color|:"#ffff00"}, {|id|:"UZ", |name|:"Uzbekistan", value:27760267, |color|:"#ff0000"}, {|id|:"VE", |name|:"Venezuela", value:29436891, |color|:"#ffff00"}, {|id|:"PS", |name|:"West Bank and Gaza", value:4152369, |color|:"#ff0000"}, {|id|:"VN", |name|:"Vietnam", value:88791996, |color|:"#ff0000"}, {|id|:"YE", |name|:"Yemen, Rep.", value:24799880, |color|:"#ff0000"}, {|id|:"ZM", |name|:"Zambia", value:13474959, |color|:"#0000ff"}, {|id|:"ZW", |name|:"Zimbabwe", value:12754378, |color|:"#0000ff"}}
end retData

★Click Here to Open This Script 

Posted in dialog JSON list Record | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSJSONSerialization NSMutableArray NSString | Leave a comment

Pagesでテキストアイテムか本文テキストから最大文字サイズのテキストを返す

Posted on 6月 12, 2020 by Takaaki Naganoya

Pagesでオープン中の最前面の書類から、最大文字サイズのテキスト(文字ボックス/本文テキスト)を抽出するAppleScriptです。

Pagesでは、本文にテキストをベタ打ちしつつ、文字スタイルを適用していくワープロ的な作り方と、ボックスでテキストアイテムを配置して文字を入れていくDTP的な(?)作り方の2通りがあります(混在できます)。

両方取得して文字サイズが大きい方を採用します。

AppleScript名:テキストアイテムか本文テキストから最大文字サイズのテキストを返す.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/06/12
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

property NSMutableArray : a reference to current application’s NSMutableArray

set aRes to getMaxTextFromTextItemsAndBodText() of me
–> {"テクノロジーが色彩(カラー)を決定している例は?"}–本文縦組みテキスト
–> {"AppleScript"}–テキストボックス組みテキスト

on getMaxTextFromTextItemsAndBodText()
  set aRes to getMaxTextFromTextItems() of me
  
set bRes to getMaxTextFromBodyText() of me
  
  
set aMax to maxSize of aRes
  
set bMax to maxSize of bRes
  
  
if aMax > bMax then
    return maxTextList of aRes
  else
    return maxTextList of bRes
  end if
end getMaxTextFromTextItemsAndBodText

on getMaxTextFromTextItems()
  tell application "Pages"
    tell front document
      set tmpList to every text item
      
if length of tmpList > 0 then
        set szList to size of object text of every text item
        
set aMaxPoint to calcMax(szList) of me –最大の文字サイズを取得
        
        
–文字サイズが最大のテキストアイテムを抽出
        
set resList to object text of every text item whose size of object text is aMaxPoint
      else
        set aMaxPoint to 0
        
set resList to {}
      end if
      
return {maxSize:aMaxPoint, maxTextList:resList}
    end tell
  end tell
end getMaxTextFromTextItems

–本文テキストから最大文字サイズのテキストを取得する
on getMaxTextFromBodyText()
  tell application "Pages"
    tell front document
      tell body text
        set tmpP to every paragraph
        
if tmpP = {""} then
          return {maxSize:0, maxTextList:{}}
        end if
        
        
–フォントサイズのみパラグラフ単位に取得
        
set szList to size of every paragraph
        
set aMaxPoint to calcMax(szList) of me –最大の文字サイズを取得
        
        
–文字サイズが最大のパラグラフを抽出
        
set resList to every paragraph whose size is aMaxPoint
        
–> {"テクノロジーが色彩(カラー)を決定している例は?"}
        
        
return {maxSize:aMaxPoint, maxTextList:resList}
      end tell
    end tell
  end tell
end getMaxTextFromBodyText

on calcMax(aList as list)
  set nArray to (NSMutableArray’s arrayWithArray:aList)
  
set maxRes to (nArray’s valueForKeyPath:"@max.self")’s doubleValue()
  
return maxRes
end calcMax

★Click Here to Open This Script 

Posted in list | Tagged 10.14savvy 10.15savvy Pages | Leave a comment

Pagesで最前面の書類中のテキストアイテムの文字サイズが最大のもののテキストを求める

Posted on 6月 12, 2020 by Takaaki Naganoya

Pagesでオープン中の最前面の書類から、最大文字サイズのテキストアイテム(文字ボックス)のテキストを抽出するAppleScriptです。

Pagesでは、本文にテキストをベタ打ちしつつ、文字スタイルを適用していくワープロ的な作り方と、ボックスでテキストアイテムを配置して文字を入れていくDTP的な(?)作り方の2通りがあります(混在できます)。

ここでは、ボックスでテキストアイテムを配置して作っています。

AppleScript名:最前面の書類中のテキストアイテムの文字サイズが最大のもののテキストを求める.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/06/12
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

property NSMutableArray : a reference to current application’s NSMutableArray

tell application "Pages"
  tell front document
    set tmpList to every text item
    
if length of tmpList = 0 then return –テキストアイテムがない場合には処理終了
    
    
set szList to size of object text of every text item
    
set aMaxPoint to calcMax(szList) of me –最大の文字サイズを取得
    
    
–文字サイズが最大のテキストアイテムを抽出
    
set resList to object text of every text item whose size of object text is aMaxPoint
    
–> {"AppleScript"}
  end tell
end tell

on calcMax(aList as list)
  set nArray to (NSMutableArray’s arrayWithArray:aList)
  
set maxRes to (nArray’s valueForKeyPath:"@max.self")’s doubleValue()
  
return maxRes
end calcMax

★Click Here to Open This Script 

Posted in list | Tagged 10.14savvy 10.15savvy NSMutableArray Pages | Leave a comment

Pagesで書類中の最大文字サイズのパラグラフのテキストを抽出

Posted on 6月 12, 2020 by Takaaki Naganoya

Pagesでオープン中の最前面の書類から、最大文字サイズのパラグラフ(段落)のテキストを抽出するAppleScriptです。

Pages v10.0で縦組みのテキスト中心の書類を作っていて、そのタイトルに該当する部分のテキストを抽出したいと考えておりました。

Pagesでは、本文にテキストをベタ打ちしつつ、文字スタイルを適用していくワープロ的な作り方と、ボックスでテキストアイテムを配置して文字を入れていくDTP的な(?)作り方の2通りがあります(混在できます)。

ここでは、本文テキストベタ打ちで作っています。

本来であれば、各パラグラフに指定されたスタイルの名称を取得して、スタイル名が「タイトル」だったらタイトルと判定するのが他のアプリケーションでの処理ですが、Pagesにはスタイル名を取得する機能はありません。

そこで、書類中の全パラグラフの文字サイズを取得し、その最大値を求め、最大値の文字サイズを持つパラグラフを求めるようにしてみました。

こういう(↑)文字ボックスを配置して作成した書類では、本Scriptのアプローチではタイトルを取得できません。

AppleScript名:書類中の最大文字サイズのパラグラフのテキストを抽出.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/06/12
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

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

property NSMutableArray : a reference to current application’s NSMutableArray

tell application "Pages"
  tell front document
    tell body text
      –フォントサイズのみパラグラフ単位に取得
      
set szList to size of every paragraph
      
set aMaxPoint to calcMax(szList) of me –最大の文字サイズを取得
      
      
–文字サイズが最大のパラグラフを抽出
      
set resList to every paragraph whose size is aMaxPoint
      
–> {"テクノロジーが色彩(カラー)を決定している例は?"}
    end tell
  end tell
end tell

on calcMax(aList as list)
  set nArray to (NSMutableArray’s arrayWithArray:aList)
  
set maxRes to (nArray’s valueForKeyPath:"@max.self")’s doubleValue()
  
return maxRes
end calcMax

★Click Here to Open This Script 

Posted in list | Tagged 10.14savvy 10.15savvy NSMutableArray Pages | Leave a comment

Keynoteで選択中のスライドのタイトルを取得して改行区切りテキストに変換

Posted on 5月 8, 2020 by Takaaki Naganoya

Keynoteのselectionを利用して、複数選択中のスライドを取得した処理を書いてみました。

ウィンドウ左側でアウトライン表示されているスライド一覧で複数選択しているものを、順次タイトルを取得して改行コードをはさんで連結したテキスト化してクリップボードに内容を転送します。内容をテキストエディタに転送して加工するために作ったものです。

Keynote用のScriptは必要に迫られて書くことが多く、本Scriptも実際に必要に迫られて書いています。ほぼ書き捨てレベルの内容でもあり、各スライドからタイトルが取得できない(タイトルが存在しない)場合には対処していません。

マスタースライドの名称を取得してタイトルオブジェクトの有無を判定するとか、各スライド上のタイトルオブジェクトにエラートラップを仕掛けつつアクセスする(存在しない場合にはエラー発生するもトラップを仕掛けてあるので処理が中断しない)、とかいった実戦レベルのScriptも(別途)書いておきたいところです。

selectionが返してくるスライド(ページ)のリストは、GUI上で後ろ(スライド番号の大きい方)から連続選択しても、前(スライド番号の小さい)のほうから連続選択しても、結果は変わりませんでした。スライド番号が小さい方から大きい方へとソートされた状態で取得されます。

AppleScript名:選択中のスライドのタイトルを取得して改行区切りテキストに変換
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/05/08
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set tList to {}

tell application "Keynote"
  tell front document
    set aSel to selection
    
set aLen to length of aSel
    
if aLen < 2 then return
    
    
repeat with i in aSel
      tell i
        tell default title item
          set aTitleStr to object text
        end tell
        
        
set the end of tList to aTitleStr
      end tell
    end repeat
  end tell
end tell

set aStr to retArrowText(tList, return) of me
set the clipboard to aStr

–リストを任意のデリミタ付きでテキストに
on retArrowText(aList, aDelim)
  set aText to ""
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retArrowText

★Click Here to Open This Script 

Posted in list | Tagged Keynote | Leave a comment

Keynoteのselectionの使い方が判明

Posted on 5月 4, 2020 by Takaaki Naganoya

AppleScriptにおける「selection」という予約語は割と重要で、選択中のオブジェクトや選択中のテキストを特定したり、選択中のオブジェクトへの処理を行うといった、一歩踏み出した処理が行えます。

KeynoteのAppleScript用語辞書に「selection」が追加されたのは、2019年3月にリリースされたv9.0のこと。

「list of iWork item」を返してくると記載されていることから、スライド(ページ)上で選択中の各種iWork item(shapeとかimageとかtext itemなどの各種オブジェクト)の選択状態を取得できることが期待されたわけですが、実際に試してみるとAppleScript用語辞書のようにiWork itemsを取得できるわけではありませんでした(当時のガッカリ感が半端ない)。

ところが、些細なことからこのKeynoteのselectionが「何を」選択しているかを返すかが分かってきました。

この、ウィンドウ左側のアウトライン表示されている各スライド(ページ)。ここを複数選択した状態でselectionを実行すると、このスライドがlistで返ってくることがわかりました。

この動作を知らずに(KeynoteのAppleScriptの用語辞書を信用して)試すと、現在表示中のスライド(ページ)のオブジェクトがリストで返ってくるという動作になります。なので、このselectionは現在表示中のスライド(ページ)のオブジェクトを返す(超使えない)コマンドだと判断していました。

ウィンドウ内容の表示ポップアップから「Light Table」を選択すると、

各スライドのサムネールが一覧表示されますが、

ここで複数スライドを選択しても「selection」で選択状態を取得できるわけではないようです。

Keynoteに対するAppleScriptの処理で、スライド上の各種オブジェクトの位置やサイズを統一するようなものがありますが、そういう範囲で使うのであれば有効に使えるといったところでしょうか。

Posted in list | Tagged 10.14savvy 10.15savvy Keynote | Leave a comment

2D Listの各要素を逆順に

Posted on 4月 26, 2020 by Takaaki Naganoya

2D Listの各要素を逆順に入れ替えるAppleScriptです。

そのままreverse ofで逆順にすると、

set aList to {{1}, {2, 3, 4, 5, 6, 7}, {3, 4, 5, 6, 7, 8, 9}}
set bList to reverse of aList
--> {{3, 4, 5, 6, 7, 8, 9}, {2, 3, 4, 5, 6, 7}, {1}}

のようになりますが、これでは目的にかないませんでした。

ちょうど、Kamenokoのセル回転テーブルを反対方向に回転させたかったので、

--> {{1}, {7, 6, 5, 4, 3, 2}, {9, 8, 7, 6, 5, 4, 3}}

のような結果が欲しかったのでした。本ルーチンを実際に組み込んで、逆方向へのデータ回転を実現させました。

ただ、データ上で回転できているだけで視覚効果については別問題です。プレビュー画像を作成しにいくとメモリ上にゴミが残ったまま消えないとか、あんまり視覚効果を利用しにくい雰囲気がしていますけれども。

AppleScript名:2D Listの各要素を逆順に.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/04/26
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set aList to {{1}, {2, 3, 4, 5, 6, 7}, {3, 4, 5, 6, 7, 8, 9}}
set bList to reverse2DListEachItems(aList) of me
–> {{1}, {7, 6, 5, 4, 3, 2}, {9, 8, 7, 6, 5, 4, 3}}

on reverse2DListEachItems(aList)
  set newList to {}
  
repeat with i in aList
    set j to contents of i
    
set tmpJ to reverse of j
    
set the end of newList to tmpJ
  end repeat
  
  
return newList
end reverse2DListEachItems

★Click Here to Open This Script 

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

正方形セルの表データで指定セルに隣接するセルブロックを検出

Posted on 3月 11, 2020 by Takaaki Naganoya

正方形セルの表を形成する1次元配列上で、指定セルに隣接する指定データの入っているセルブロックを検出するAppleScriptです。

テストデータは11×11のサイズで作ってみました。本Scriptを作ることが最終目的ではないので、実戦投入はしていませんが、それなりに動いているようです。11セルの対象データを検出するのに、0.002秒ぐらい(10回実行時の平均値)。

本プログラムではセルアドレス=58のセルと隣接する「9」のデータが入っているセルのアドレスをすべて求めています。基準セルの8方向のセルアドレスを計算したうえでデータにアクセスして、「9」が入っているセルを検出。それらをまとめてすべての検出セルの8方向のアドレスを検査し、それ以上検出セル数が増加しない状態までループ処理を続けています。

本プログラムは本番プログラムを作るための習作だったので、ものすごくオーソドックスな組み方をしています。本番のプログラムでは、この「無駄に長い」処理を大幅に簡略化して3分の1ぐらいの長さになりました。

AppleScript名:findBlock2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/03/10
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

property dataWidth : 11
property dataHeight : 11
property dataMax : 121

property testData : {"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬
  "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬
  
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬
  
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬
  
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬
  
"1", "1", "9", "1", "1", "1", "1", "1", "1", "1", "1", ¬
  
"1", "9", "9", "9", "1", "1", "1", "1", "1", "1", "1", ¬
  
"1", "9", "9", "9", "9", "1", "1", "1", "1", "1", "1", ¬
  
"1", "9", "9", "9", "1", "1", "1", "1", "1", "1", "1", ¬
  
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬
  
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"}

set foundList to {58}

set prevFound to 1
repeat
  set foundList to findAllDirection(foundList) of me
  
set aLen to length of foundList
  
if aLen = prevFound then
    return foundList
  else
    copy aLen to prevFound
  end if
end repeat

return foundList
–> {58, 69, 68, 70, 80, 79, 81, 82, 91, 90, 92}

on findAllDirection(foundList)
  repeat with sCanCell in foundList
    
    
set nRes to findN(sCanCell) of me
    
set sRes to findS(sCanCell) of me
    
set eRes to findE(sCanCell) of me
    
set wRes to findW(sCanCell) of me
    
set nwRes to findNW(sCanCell) of me
    
set neRes to findNE(sCanCell) of me
    
set swRes to findSW(sCanCell) of me
    
set seRes to findSE(sCanCell) of me
    
    
if nRes is not equal to false then
      set newAddr to contents of (item 2 of nRes)
      
if newAddr is not in foundList then
        set the end of foundList to newAddr
      else
        set nRes to false
      end if
    end if
    
    
if sRes is not equal to false then
      set newAddr to contents of (item 2 of sRes)
      
if newAddr is not in foundList then
        set the end of foundList to newAddr
      else
        set sRes to false
      end if
    end if
    
    
if eRes is not equal to false then
      set newAddr to contents of (item 2 of eRes)
      
if newAddr is not in foundList then
        set the end of foundList to newAddr
      else
        set eRes to false
      end if
    end if
    
    
if wRes is not equal to false then
      set newAddr to contents of (item 2 of wRes)
      
if newAddr is not in foundList then
        set the end of foundList to newAddr
      else
        set wRes to false
      end if
    end if
    
    
if nwRes is not equal to false then
      set newAddr to contents of (item 2 of nwRes)
      
if newAddr is not in foundList then
        set the end of foundList to newAddr
      else
        set nwRes to false
      end if
    end if
    
    
if neRes is not equal to false then
      set newAddr to contents of (item 2 of neRes)
      
if newAddr is not in foundList then
        set the end of foundList to newAddr
      else
        set neRes to false
      end if
    end if
    
    
if swRes is not equal to false then
      set newAddr to contents of (item 2 of swRes)
      
if newAddr is not in foundList then
        set the end of foundList to newAddr
      else
        set swRes to false
      end if
    end if
    
    
if seRes is not equal to false then
      set newAddr to contents of (item 2 of seRes)
      
if newAddr is not in foundList then
        set the end of foundList to newAddr
      else
        set seRes to false
      end if
    end if
    
  end repeat
  
return foundList
end findAllDirection

—————————————

on findS(anAddress)
  copy anAddress to tmpAddr
  
set tmpAddr to incLine(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpCon to contents of item tmpAddr of testData
  
if tmpCon = "1" then return false
  
return {true, tmpAddr}
end findS

on findN(anAddress)
  copy anAddress to tmpAddr
  
set tmpAddr to decLine(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpCon to contents of item tmpAddr of testData
  
if tmpCon = "1" then return false
  
return {true, tmpAddr}
end findN

on findE(anAddress)
  copy anAddress to tmpAddr
  
set tmpAddr to incCell(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpCon to contents of item tmpAddr of testData
  
if tmpCon = "1" then return false
  
return {true, tmpAddr}
end findE

on findW(anAddress)
  copy anAddress to tmpAddr
  
set tmpAddr to decCell(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpCon to contents of item tmpAddr of testData
  
if tmpCon = "1" then return false
  
return {true, tmpAddr}
end findW

on findNW(anAddress)
  copy anAddress to tmpAddr
  
set tmpAddr to decLine(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpAddr to decCell(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpCon to contents of item tmpAddr of testData
  
if tmpCon = "1" then return false
  
return {true, tmpAddr}
end findNW

on findNE(anAddress)
  copy anAddress to tmpAddr
  
set tmpAddr to decLine(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpAddr to incCell(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpCon to contents of item tmpAddr of testData
  
if tmpCon = "1" then return false
  
return {true, tmpAddr}
end findNE

on findSW(anAddress)
  copy anAddress to tmpAddr
  
set tmpAddr to incLine(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpAddr to decCell(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpCon to contents of item tmpAddr of testData
  
if tmpCon = "1" then return false
  
return {true, tmpAddr}
end findSW

on findSE(anAddress)
  copy anAddress to tmpAddr
  
set tmpAddr to incLine(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpAddr to incCell(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpCon to contents of item tmpAddr of testData
  
if tmpCon = "1" then return false
  
return {true, tmpAddr}
end findSE

—————————————

on incLine(anAddress)
  if anAddress + dataWidth > dataMax then
    set anAddress to false
  else
    set anAddress to anAddress + dataWidth
  end if
  
return anAddress
end incLine

on decLine(anAddress)
  if anAddress – dataWidth < 1 then
    set anAddress to false
  else
    set anAddress to anAddress – dataWidth
  end if
  
return anAddress
end decLine

on incCell(anAddress)
  set tmpMax to anAddress div dataWidth
  
if ((anAddress + 1) div dataWidth) is not equal to tmpMax then
    set anAddress to false
  else
    if anAddress + 1 < dataMax then
      set anAddress to anAddress + 1
    else
      return false
    end if
  end if
  
return anAddress
end incCell

on decCell(anAddress)
  set tmpMax to anAddress div dataWidth
  
set tmp2Max to (anAddress – 1) div dataWidth
  
if anAddress – 1 > 0 then
    if (tmp2Max is equal to tmpMax) then
      set anAddress to anAddress – 1
    end if
  else
    set anAddress to false
  end if
  
return anAddress
end decCell

★Click Here to Open This Script 

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

Numbersの表の選択範囲をシーケンシャル番号で埋める

Posted on 3月 11, 2020 by Takaaki Naganoya

Numbersの最前面の書類で選択中の表の選択範囲を1からはじまるシーケンシャル番号で埋めるAppleScriptです。

Numbers書類のセルを埋めるのは、それなりにコストの高い(処理時間が長い)処理なので、数十とか百ぐらいの要素だと、このように悠長にループで埋めても大丈夫ですが、数千とか数万セルを相手にする場合には途方もない時間がかかります。

要素数が多い場合には、CSVのファイルを組み立ててオープンする処理方法をおすすめします(一瞬で終わるので)。

この手の処理は、ほぼ「書き捨て」で保存すらしないことが多いのですが、たまたま気が向いたので保存しておきました。

本ScriptはmacOS 10.14.6/10.15.3+Numbers v6.2.1、macOS 10.13.6+Numbers v6.2で動作確認しています。

AppleScript名:Numbersの表の選択範囲をシーケンシャル番号で埋める
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/03/10
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

tell application "Numbers"
  tell front document
    tell active sheet
      try
        set theTable to first table whose class of selection range is range
      on error
        display notification "Numbers: There is no selection"
        
return
      end try
      
      
tell theTable
        set aRes to value of cells of selection range
      end tell
      
      
set aLen to length of aRes
      
set newList to makeSequential1DList(aLen) of me
      
      
tell theTable
        set cList to cells of selection range
      end tell
      
      
repeat with i from 1 to aLen
        set anObj to contents of item i of cList
        
set aVal to contents of item i of newList
        
        
ignoring application responses
          set value of anObj to aVal
        end ignoring
        
      end repeat
    end tell
  end tell
end tell

on makeSequential1DList(itemLen)
  set outList to {}
  
repeat with i from 1 to itemLen
    set the end of outList to i
  end repeat
  
return outList
end makeSequential1DList

★Click Here to Open This Script 

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

Numbersで書類Aのすべてのシートの表1を、書類Bの現在のシートの表1にまとめる

Posted on 1月 21, 2020 by Takaaki Naganoya

Numbersでオープン中の複数の書類があったときに、書類Aのすべてのシートの表1を、書類Bの現在のシートの表1にまとめるAppleScriptです。

さすがに、機械的な作業すぎて手で行う気にはなれなかったので、ありもののScriptを利用して作ってみました。

こういう用途のために作っておいたライブラリ「choose multiple list」を利用しています。


▲データ取得元


▲データ集約先


▲ダイアログで「データ取得元」と「データ集約先」を選択

BridgePlus内蔵のFrameworkがmacOS 10.14/10.15に邪魔されて認識されない環境では動かせないかもしれません。このあたり、SIP解除するしかないと思わせるものがあります。

ライブラリで複雑な選択を行えるUI部品を作っておいたおかげで、これだけ込み入った動作を行うAppleScriptを書きましたが、Cocoaの機能はほぼ使っていません(getDataFromNumbersDocは作り置きしておいた、頻出ルーチンなので使いまわしています)。choose multiple listライブラリは、こういう用途のために作っておいたものであり、まさにそのぴったりな用途であったといえるでしょう。

AppleScript名:書類Aのすべてのシートの表1を、書類Bの現在のシートの表1にまとめる.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/01/20
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.7" — High Sierra (10.13) or later
use framework "Foundation"
use scripting additions
use bPlus : script "BridgePlus"
use mulList : script "choose multiple list"

script spd
  property allData : {}
end script

set (allData of spd) to {}

set {aName, bName} to getTargetDocNames() of me

–「データ取得元」のNumbers書類のすべてのシートの表1から2D Listでデータ取得
tell application "Numbers"
  tell document aName
    set sList to name of every sheet
    
repeat with i in sList
      set tmp2DDat to getDataFromNumbersDoc(aName, i) of me
      
set (allData of spd) to (allData of spd) & tmp2DDat
    end repeat
  end tell
end tell

set aHeight to length of (allData of spd)
set aWidth to length of item 1 of (allData of spd)

–「データ集約先」のNumbers書類の現在のシートの表1にまとめた2D Listを展開する(巨大すぎると時間がかかるので、CSV書き出ししてオープンするなどの別の方法を採るべき)
tell application "Numbers"
  tell document bName
    tell active sheet
      set tRes to make new table with properties {row count:aHeight + 1, column count:aWidth}
    end tell
  end tell
end tell

fillCurrentTable(bName, (allData of spd)) of me

–Numbersの書類の現在のシートを、指定の2次元配列でfillする
on fillCurrentTable(docName, aList)
  set aLen to length of aList
  
set aWidth to length of first item of aList
  
  
tell application "Numbers"
    tell document docName
      tell active sheet
        tell table 1
          repeat with i from 1 to aLen
            tell row (i + 1)
              set aRowList to contents of item i of aList
              
repeat with ii from 1 to aWidth
                tell cell ii
                  set aTmpData to contents of item ii of aRowList
                  
ignoring application responses
                    set value to aTmpData
                  end ignoring
                end tell
              end repeat
            end tell
          end repeat
        end tell
      end tell
    end tell
  end tell
end fillCurrentTable

–Numbersでオープン中の書類の名称一覧からデータ取得元とデータ集約先の書類名をダイアログで選択
on getTargetDocNames()
  tell application "Numbers"
    set nList to name of every document
  end tell
  
  
set selList to {nList, nList}
  
set tList to {"データ取得元", "データ集約先"}
  
  
set {aRes, bRes} to choose multiple list selList main message "各Numbers書類の役割を選択してください" sub message "「データ取得元」のデータを順次、「データ集約先」の表1に連結します" with title lists tList height 140 width 400 return type item contents without allow same items
  
return {aRes, bRes}
end getTargetDocNames

–Numbersでオープン中の書類の選択中のシートの表1からデータを取得して2D Listに
on getDataFromNumbersDoc(aDocName, sheetName)
  
  
load framework
  
  
tell application "Numbers"
    if (count (every document)) = 0 then return false
    
    
tell document aDocName
      if (count (every sheet)) = 0 then return false
      
      
tell sheet sheetName
        tell table 1
          set colCount to column count
          
set rowCount to row count
          
set headerCount to header row count
          
set footerCount to footer row count
          
          
set dList to value of every cell of cell range
        end tell
      end tell
      
    end tell
  end tell
  
  
–Convert 1D List to 2D List
  
set bList to (current application’s SMSForder’s subarraysFrom:dList groupedBy:colCount |error|:(missing value)) as list
  
set sItem to 1 + headerCount
  
set eItem to rowCount – footerCount
  
set cList to items sItem thru eItem of bList
  
  
return cList
  
end getDataFromNumbersDoc

★Click Here to Open This Script 

Posted in dialog GUI list | Tagged 10.13savvy 10.14savvy 10.15savvy Numbers | Leave a comment

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

Posted on 1月 19, 2020 by Takaaki Naganoya

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

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

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

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

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

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

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

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

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

★Click Here to Open This Script 

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

Post navigation

  • Older posts
  • Newer posts

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

Google Search

Popular posts

  • 開発機としてM2 Mac miniが来たのでガチレビュー
  • macOS 15, Sequoia
  • Pages本執筆中に、2つの書類モード切り替えに気がついた
  • Numbersで選択範囲のセルの前後の空白を削除
  • メキシカンハットの描画
  • Pixelmator Pro v3.6.4でAppleScriptからの操作時の挙動に違和感が
  • AppleScriptによる並列処理
  • Safariで「プロファイル」機能を使うとAppleScriptの処理に影響
  • macOS 15でも変化したText to Speech環境
  • AppleScript入門③AppleScriptを使った「自動化」とは?
  • デフォルトインストールされたフォント名を取得するAppleScript
  • macOS 15 リモートApple Eventsにバグ?
  • 【続報】macOS 15.5で特定ファイル名パターンのfileをaliasにcastすると100%クラッシュするバグ
  • Script Debuggerの開発と販売が2025年に終了
  • AppleScript入門① AppleScriptってなんだろう?
  • macOS 14で変更になったOSバージョン取得APIの返り値
  • NSObjectのクラス名を取得 v2.1
  • macOS 15:スクリプトエディタのAppleScript用語辞書を確認できない
  • 有害ではなくなっていたSpaces
  • Xcode上のAppleScriptObjCのプログラムから、Xcodeのログ欄へのメッセージ出力を実行

Tags

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

カテゴリー

  • 2D Bin Packing
  • 3D
  • AirDrop
  • AirPlay
  • Animation
  • AppleScript Application on Xcode
  • Beginner
  • Benchmark
  • beta
  • Bluetooth
  • Books
  • boolean
  • bounds
  • Bug
  • Calendar
  • call by reference
  • check sum
  • Clipboard
  • Cocoa-AppleScript Applet
  • Code Sign
  • Color
  • Custom Class
  • date
  • dialog
  • diff
  • drive
  • Droplet
  • exif
  • file
  • File path
  • filter
  • folder
  • Font
  • Font
  • GAME
  • geolocation
  • GUI
  • GUI Scripting
  • Hex
  • History
  • How To
  • iCloud
  • Icon
  • Image
  • Input Method
  • Internet
  • iOS App
  • JavaScript
  • JSON
  • JXA
  • Keychain
  • Keychain
  • Language
  • Library
  • list
  • Locale
  • Localize
  • Machine Learning
  • Map
  • Markdown
  • Menu
  • Metadata
  • MIDI
  • MIME
  • Natural Language Processing
  • Network
  • news
  • Noification
  • Notarization
  • Number
  • Object control
  • OCR
  • OSA
  • parallel processing
  • PDF
  • Peripheral
  • process
  • 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年6月
  • 2025年5月
  • 2025年4月
  • 2025年3月
  • 2025年2月
  • 2025年1月
  • 2024年12月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年6月
  • 2024年5月
  • 2024年4月
  • 2024年3月
  • 2024年2月
  • 2024年1月
  • 2023年12月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年6月
  • 2023年5月
  • 2023年4月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年12月
  • 2019年11月
  • 2019年10月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年5月
  • 2018年4月
  • 2018年3月
  • 2018年2月

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

メタ情報

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

Forum Posts

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

メタ情報

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