Archive for the 'OmniGraffle' Category

2012/10/07 Skimでオープン中のPDFの現在のページの内容をOmniGraffleにペースト

オープンソースのPDFビューワー「Skim」でオープン中のPDFの表示中のページの内容をそのままOmniGraffleの現在表示中のページ(canvas)にペーストするAppleScriptです。

現在、PDFビューワーのうちScriptableなものといえばAdobe AcrobatとSkim。Acrobatはインストールしてもいいことがあまりないように(個人的に)感じるので、ほぼ知り合いにはSkimのインストールをお願いしています。Mac OS X標準添付のプレビュー.appは(そのままでは)AppleScriptからはコントロールできないので、Skimはおすすめです。

本AppleScriptはSkimでオープン中のPDFの、現在表示中のページの内容を取得して……

skim_to_omni1.png

OmniGraffleの現在表示中のページ(Canvas)にその内容をペーストします。

skim_to_omni2.png

Skimには、指定の座標内の内容を取得する「grab」コマンドがあるので、取得した内容をそのままOmniGraffleに持って行けばいいだろうかと考えて一度試してみたのですが……思ったようには動かず、結局地道に「Grabした内容を一度ファイルに書き出して、OmniGraffleに書き出したPDFを読み込む」というやり方に落ち着きました。

喫茶店でコーヒー1杯飲むぐらいの時間で作ったので、処理自体はかなり適当です。一時的にTemporary Items Folderに書き出したPDFファイルのゴミ捨て処理なども行っていません。現在表示中のページのみを処理するようにしてありますが、AppleScript的に一括処理を行うのであれば、Skimで表示中のPDFのすべてのページをループで処理してOmniGraffleにインポートするように書き換えるとよいでしょう。

スクリプト名:Skimでオープン中のPDFの現在のページの内容をOmniGraffleにペースト

set outFol to (path to temporary items from system domain) as string
set cName to do shell script “/usr/bin/uuidgen”

tell application “Skim”
  tell document 1
    tell current page
      set bList to bounds –{Left, Top, Right, Bottom} —> {0, Height, Width, 0}
      
set anImage to grab for bList –as PDF
    end tell
  end tell
end tell

set bbList to {contents of third item of bList, contents of second item of bList}

set target_file to outFol & cName
write_to_file(anImage, target_file, false) of me

makeShapeWithProperty(missing value, target_file, {0, 0}, bbList, “”, true) of omniGroupScriptLib

–指定画像ファイルを現在のドキュメントにインポートする
–Omni Groupの配布しているScriptから、関係ないルーチンとプロパティを削除してほぼそのまま使用
script omniGroupScriptLib
  
  
on makeShapeWithProperty(onCanvas, myFile, aPositionList, aSizeList, aURL, outLineFlag)
    using terms from application “OmniGraffle 5″
      tell application “OmniGraffle 5″
        tell document 1
          tell canvas 1
            set theShape to make new shape at front of graphics with properties {origin:aPositionList, thickness:0.5, fill:no fill, draws stroke:outLineFlag, size:aSizeList, draws shadow:false, autosizing:overflow}
            
            
set url of theShape to aURL
            
            
getPicture(theShape, myFile) of me
            
            
–後からこれらの属性をセットするのがミソ
            
set image sizing of theShape to stretched –ここが重要!!!
            
set size of theShape to aSizeList
            
            
return theShape
          end tell
        end tell
      end tell
    end using terms from – OmniGraffle
  end makeShapeWithProperty
  
  
  
– make the shape - I can’t get the import construct to work - so I make a shape and set its fill with the image.
  
on makeShape(onCanvas, myFile)
    using terms from application “OmniGraffle 5″
      tell application “OmniGraffle 5″
        tell onCanvas
          set theShape to make new shape at front of graphics with properties {origin:{0, 0}, thickness:0.0, fill:no fill, draws stroke:false, image scale:1, size:{20, 20}, draws shadow:false}
          
getPicture(theShape, myFile) of me
          
return theShape
        end tell
      end tell
    end using terms from – OmniGraffle
  end makeShape
  
  
– Get the dropped image, get it’s size and set it as a fill to the shape, and some (adjustable) settings.
  
on getPicture(theShape, myFile)
    set filePath to (myFile) as string
    
set posixPath to POSIX path of file filePath
    
try
      tell application “Image Events”
        launch
        
set this_image to open filePath
        
set the props_rec to the properties of this_image
        
copy (dimensions of props_rec) to {myX, myY}
        
close this_image
      end tell
    end try
    
    
using terms from application “OmniGraffle 5″
      tell application “OmniGraffle 5″
        ignoring application responses
          set image of theShape to posixPath
          
set image sizing of theShape to manual
          
set image scale of theShape to 0.5 ——-Retina Displayなので
          
set image offset of theShape to {0, 0}
          
set size of theShape to {myX, myY}
          
–select theShape
        end ignoring
      end tell
    end using terms from
  end getPicture
  
  
return theShape
  
end script

–ファイルの追記ルーチン「write_to_file」
–追記データ、追記対象ファイル、boolean(trueで追記)
on write_to_file(this_data, target_file, append_data)
  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 write_to_file

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2012/08/22 OmniGraffleで日本語版と英語版の画面キャプチャを並べた書類を作成する

2012/08/07 iPhoneアプリをAppleScriptからコントロール

iPhoneアプリ(iOSアプリ)をAppleScriptからコントロールできるメドが立ちました。実際にAppleScriptからコントロールできています。

最初にお断りしておきますが……これは、「iPhoneアプリがiPhone実機で動いているところをAppleScript経由でコントロールする」という話ではありません。だいたい、AppleEventの仕組みが存在しないiOSに対してOS X側からネットワークごしにリモートAppleEventを投げ、応答があるわけがありません。

iphone11.jpg

Mac OS X上で稼働するiOSシミュレータ上で動くアプリをAppleScriptからコントロールした、ということです。確認はOS X 10.8+Xcode 4.4+iOSシミュレータ v5.1(272.21)で実施しました。

冷静になって考えれば、CocoaベースのアプリケーションであるiOSアプリが、特定のアプリ(iOSシミュレータ)の特定のウィンドウ上で稼働しているというのがiOSシミュレータの動作状態です(当然、例外はあると思います)。iOSアプリの作り方にもよりますし、普遍性がどの程度あるのかは保証のかぎりではありません。ただ、自分が関わっているiOSアプリケーションに対してコントロールを試みた、という話です。

この状態は、とくに変わったものではなく、一般的なCocoaアプリケーション内の1ウィンドウ内の各種GUI Elementに対してのアクセス……というとらえ方ができます。

とくに、技術的に困難な可能性はないと判断し、実際に試してみたら……当然のようにできました。

実際に、AppleScriptからiOSアプリケーションの画面上の情報を取得したり、特定のボタンをタップしたり……という操作を行えています(値の設定はかなり無理)。

自分としては、開発中の大規模なiOSアプリの画面スナップショット(画面数が多いので仕様書用の画像作成が大変)をひととおり自動作成するような自動処理を考えています。当然、書き出したあとは仕様書の中に貼り込んだ画面を最新のものにAppleScriptで自動で貼り替えることになります。このあたりは、日常茶飯事です。

よくも悪くも、「最高到達点」がその程度の処理内容にすぎないので、iOSアプリの開発資料の作成の手間を減らしたいとか、そういう「差し迫った必要性」がなければ、ほとんどのMac/iPhoneユーザーには関係のない話ではあります。

ただし、アプリ上のひととおりの画面のスナップショットを、仕様書上の画面番号を付けて指定フォルダに自動で保存できるとなれば、これは相当に便利です。

追記;予定していた仕様のものは、ひととおりできました。AppleScriptObjCでさらっと作って、便利に使えそうです。

2012/07/21 OmniGroup、Omni Graffle 5.4.1でAppleScript系のバグを修正

omnigraffle.png

OmniGraffleを駆使し、AppleScriptでワークフローを自動化して効率的に作業をしていたところに、バグ入りのOmniGraffle 5.4が公開され、しばらくその手の作業がストップしていました(仕事にならない)。

いいかげんしびれを切らして、Beta版でも公開されていないかとOmniGroupのWebを見に行ったところ……

OmniGraffleの5.4.1Betaが(ページの下の方に)ダウンロードできるようになっていました。同ページ上の修正点(Version 5.4.1 Release Candidate Bug Fixes)を読むと、

・Fixed a typo in the AppleScript Dictionary.
・Fixed a regression where the text:size attribute was not being respected in AppleScript.
・Fixed a regression where it was no longer possible to use AppleScript to save as various filetypes.

とあり、無事なんとかワークフローの自動化を復旧できそうです。

ちなみに、上記の修正点のうちTypoというのは、

omni2.png

のことです(左:5.4、右:5.4.1rc)。この件に関していえば、Scriptingに実害はありません。

v5.4.1は、おそらくOS X 10.8 Mountain Lionのリリースと同時に公開されるものと思われます。

2012/06/06 OmniGraffle 5.4へのアップデートはまだ様子見

stopomni.png

OmniGraffleをAppleScriptからコントロールしてワークフローの自動化を行っている方は、まだ最新版のv5.4にアップデートしないことを強くおすすめします。

OmniGraffle v5.3からv5.4にアップデートしたところ、save命令のフォーマット指定でエラーが出るようになってしまいました。ちなみに、両バージョンのAppleScript用語辞書に違いは見られません。

スクリプト名:OmniGraffle 5.4でsave命令の形式指定がおかしくなった
set outFile to choose file name “Select New Filename”
set outFilePOSIXpath to POSIX path of outFile

tell application “OmniGraffle 5″
  tell current export settings
    set area type to selected graphics
    
set draws background to false
    
set export scale to 1
    
set include border to false
    
set resolution to 1.0
  end tell
  
  
set aDoc to document 1
  
  
save aDoc as “PNG” in POSIX file outFilePOSIXpath
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

上記のサンプルプログラムは、OmniGraffleのキャンバス上で選択中のオブジェクトを指定ファイル名および指定パスに、PNG形式で書き出しを行うものですが、v5.3で動いていたものがv5.4で動かなくなってしまいました。

error.png

OmniGroupにはバグレポート済みですが、v5.4へのアップデートは問題が解決されるまで様子見のほうがよいでしょう。

個人的には、ものすごく困っています。仕様書の自動更新とか、さまざまなAppleScriptでワークフローを自動化してきたもので。ほんとーに困ります。v5.3に戻したいです。

後日談:

2日ほどたって、OmniGroupのSupport Ninja部隊から報告内容をFileしておいたという報告が来ました。優先順位としてはRetina Mac対応とかOS X 10.8対応とかの方が上になるんでしょうけれど、AppleScriptの命令修正も早急に対応していただきたいところです。

2011/12/12 選択中のボックスを表に再構成する

OmniGraffleで作成した表をいったん分解して、バラバラにした状態のものを再度「表」に再構成するAppleScriptです。

まずは、OmniGraffle上で表を作成するところから……

tbl1.jpg

完成時のサイズの見当をつけるために、ダミーのボックスをOmniGraffle上で作成し、選択状態にしておく。

tbl2.jpg

Numbers上に表に入れるデータを入力して、表に入れるデータの範囲を選択状態にしておく。

tbl3.jpg

NumbersのデータからOmniGraffle書類上に表を作成するAppleScriptを実行し、OmniGraffle上で表を作成。

tbl4.jpg

いったん作成した「表」を「グループ解除」コマンドで……

tbl5.jpg

再度、バラバラに。

この状態で、本AppleScriptを実行すると……

tbl6.jpg

表の縦、横のセル数をダイアログで聞いてくるので、それに対して適切に入力すると……

tbl7.jpg

ふたたび、表に戻すことができます。このサンプルがやっつけで作ったもののためか、ヘッダー行が入れ替わっていますが……実際に作業で再編集した表は、表の下に新規行を追加するパターンがほとんどでした。

スクリプト名:選択中のボックスを表に再構成する
–選択中のボックスを表に再構成する
tell application “OmniGraffle 5″
  tell front window
    set aSel to selection
    
    
–ここ、計算で誤差を無視して縦x横のオブジェクト数をカウントするとベスト
    
set aText to (text returned of (display dialog “縦x横のセル数を入力” default answer “2×2″))
    
set aRes to divideYxX(aText) of me
    
if aRes = false then
      display dialog “入力内容に誤りがありました。” buttons {“OK”} default button 1 with icon 1
      
return
    end if
    
    
try
      assemble aSel table shape aRes
    end try
    
  end tell
end tell

–「YxX」の形式の文字列を、{Y,X}のように数字のリストにして返す
on divideYxX(aStr)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to “x”
  
set tList to every text item of aStr
  
set AppleScript’s text item delimiters to curDelim
  
  
copy tList to {item1, item2}
  
try
    set item1 to item1 as integer
    
set item2 to item2 as integer
  on error
    return false
  end try
  
  
return {item1, item2}
  
end divideYxX

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/12/06 Numbersで選択中のデータをもとにOmniGraffleの選択中のグラフィックのサイズで表作成

Numbers上で選択中のデータをもとに、OmniGraffleで選択中のグラフィックのサイズの表を作成するAppleScriptです。

Numbersのテーブル上で表を作成する対象のデータを選択しておきます。OmniGraffleの最前面の書類上で、四角のボックスを作成して選択状態にしておきます。

この状態で本AppleScriptを実行すると、OmniGraffle上で四角のボックスを削除したうえで、起点やサイズなどを参考にしつつ表を作成します。

スクリプト名:Numbersで選択中のデータをもとにOmniGraffleの選択中のグラフィックのサイズで表作成
property cellYohakuPoint : 3 –セル内の余白(上下/左右を同値で指定)
property textPointSize : 12 –セル内の文字サイズ(ポイント数)
property textFontName : "HiraKakuProN-W3" –セル内のフォント
property headerFillCol : {0.901961, 0.901961, 0.901961} –ヘッダー行の塗り色(うすいグレー)

–Numbersの選択範囲からデータを取得する(Excel-Like Nested List Format)
set aList to retExcelLikeStyleDataFromNumbersSelection() of me

set heightOfList to length of aList –データの高さ(行数)を取得
set widthOfList to length of first item of aList –データの幅(列数)を取得

–Omni Graffleの選択オブジェクト情報を取得
tell application "OmniGraffle 5"
  tell front window
    set aSel to selection
    
set aaSel to first item of aSel
    
    
set {xSize, ySize} to size of aaSel
    
set {xOrigPos, yOrigPos} to origin of aaSel
    
    
delete aaSel –位置指定用のオブジェクトを削除
    
  end tell
end tell

–表のセルの大きさを計算する
set xStep to xSize / widthOfList
set yStep to ySize / heightOfList

–テーブル用のオブジェクトリスト
set tObjList to {}

tell application "OmniGraffle 5"
  tell canvas of front window
    
    
repeat with y from 1 to heightOfList
      repeat with x from 1 to widthOfList
        
        
set aText to contents of item x of item y of aList
        
        
–Numbersの表の空きセルからデータを取ったときに数値の0.0が返る現象への対策
        
if aText = 0.0 then
          set aText to ""
        end if
        
        
set tmpXpos to xOrigPos + ((x - 1) * xStep)
        
set tmpYpos to yOrigPos + ((y - 1) * yStep)
        
        
–セルを作成する
        
if y = 1 then
          –ヘッダー行の場合にはセル内を指定色で塗る
          
set aCellObj to make new shape at end of graphics with properties {fill:solid fill, fill color:headerFillCol, draws shadow:false, size:{xStep, yStep}, side padding:cellYohakuPoint, thickness:0.25, autosizing:vertically only, vertical padding:cellYohakuPoint, origin:{tmpXpos, tmpYpos}, text:{text:aText, font:textFontName, size:textPointSize}}
          
        else
          –通常行はセル内を塗りつぶさない
          
set aCellObj to make new shape at end of graphics with properties {fill:no fill, draws shadow:false, size:{xStep, yStep}, side padding:cellYohakuPoint, thickness:0.25, autosizing:vertically only, vertical padding:cellYohakuPoint, origin:{tmpXpos, tmpYpos}, text:{text:aText, font:textFontName, size:textPointSize}}
          
        end if
        
        
set the end of tObjList to aCellObj
        
      end repeat
    end repeat
    
    
–セルを表に合成する
    
assemble tObjList table shape {heightOfList, widthOfList}
    
  end tell
end tell

–Numbersで選択範囲を縦に区切ったリストを返す
on retExcelLikeStyleDataFromNumbersSelection()
  
  
tell application "Numbers"
    tell document 1
      tell sheet 1
        tell table 1
          set selList to value of every cell of selection range –選択範囲のデータを取得
          
          
set selName to name of selection range –選択範囲のrange情報を取得
          
set {s1, s2} to parseByDelim(selName, ":") of me
          
          
–始点の情報を取得する
          
set s1Row to (address of row of range s1) as integer
          
set s1Column to (address of column of range s1) as integer
          
          
–終点の情報を取得する
          
set s2Row to (address of row of range s2) as integer
          
set s2Column to (address of column of range s2) as integer
          
          
–選択範囲の情報を取得する
          
set selHeight to s2Row - s1Row + 1 –高さ(Height of selection range)
          
set selWidth to s2Column - s1Column + 1 –幅(Width of selection range)
          
        end tell
      end tell
    end tell
  end tell
  
  
set aLen to length of selList
  
set aaLen to selHeight
  
  
set bList to {}
  
repeat with i from 1 to aaLen
    set aHoriList to {}
    
    
repeat with ii from 1 to selWidth
      set j1 to ii + (i - 1) * selWidth
      
set tmpCon to contents of item j1 of selList
      
      
set aClass to class of tmpCon
      
if aClass = number or aClass = integer or aClass = real then
        set tmpCon to tmpCon as integer
      end if
      
      
set the end of aHoriList to tmpCon
    end repeat
    
    
set the end of bList to aHoriList
  end repeat
  
  
return bList
  
end retExcelLikeStyleDataFromNumbersSelection

on parseByDelim(aData, aDelim)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set dList to text items of aData
  
set AppleScript’s text item delimiters to curDelim
  
return dList
end parseByDelim

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/12/06 最前面のドキュメントの全Canvas上のグラフィックがそれぞれグループ化されていないかチェック。されていなければグループ化

OmniGraffleで、最前面のドキュメントの全Canvas(ページ)上のグラフィックがそれぞれグループ化されているかを確認するAppleScriptです。

グループ化されていない場合には、強制的にグループ化します。

スクリプト名:最前面のドキュメントの全Canvas上のグラフィックがそれぞれグループ化されていないかチェック。されていなければグループ化
tell application "OmniGraffle 5"
  tell front document
    set cList to every canvas
    
set nList to name of every canvas
  end tell
  
  
–書き出し対象のドキュメントを特定する
  
set curDoc to document of front window
  
  
–ドキュメント内のすべてのCanvas(ページ)
  
repeat with i in nList
    set j to contents of i
    
    
set aRes to checkAGroupInCanvas(j, curDoc) of me
    
    
–グループ化され切っていないCanvasがあったらグループ化
    
if aRes = false then
      –表示を切り替えてグループ化      
      
set canvas of front window to canvas j of curDoc
      
      
tell canvas of front window
        assemble every graphic –これでグループ化
      end tell
    end if
    
  end repeat
  
end tell

–指定ドキュメントの指定Canvas上のグラフィックがグループ化されていないか(1つになっていないか)チェックして返す
on checkAGroupInCanvas(aCanvasName, curDoc)
  tell application "OmniGraffle 5"
    tell canvas aCanvasName of curDoc
      set gList to every graphic
      
      
set gLen to length of gList
      
      
if gLen > 1 then
        return false
      else if gLen = 1 then
        return true
      end if
      
    end tell
  end tell
end checkAGroupInCanvas

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/12/06 通常版のOmniGraffleでProfessional版でしか作れない「表」を作る

OmniGraffleで、Professional版でしか作れない「表」を作成するAppleScriptです。

AppleScript用語辞書を調べてみたら、OmniGraffleとOmniGraffle Professionalでは差がないことが判明。GUIがないだけで、中身は存在するようでした。

そこで、OmniGraffle Professionalの試用版を利用して表の作成AppleScriptを作成し、それをOmniGraffle用にtellブロックだけ書き換えてみたら……問題なく動きました。

作れますね、表。

スクリプト名:通常版のOmniGraffleでProfessional版でしか作れない「表」を作る
–通常版のOmniGraffleでProfessional版でしか作れない「表」を作る
tell application “OmniGraffle 5″
  tell canvas of front window
    make new shape at end of graphics with properties {fill:no fill, draws shadow:false, size:{197.499985, 18.0}, side padding:0, thickness:0.25, autosizing:vertically only, vertical padding:0, origin:{103.000008, 46.0}, text:{text:“ああああああ”, font:“HiraKakuProN-W3″}}
    
make new shape at end of graphics with properties {fill:no fill, draws shadow:false, size:{197.500015, 18.0}, side padding:0, thickness:0.25, autosizing:vertically only, vertical padding:0, origin:{300.5, 46.0}, text:{text:“いいいいい”, font:“HiraKakuProN-W3″}}
    
make new shape at end of graphics with properties {fill:no fill, draws shadow:false, size:{197.499985, 18.0}, side padding:0, thickness:0.25, autosizing:vertically only, vertical padding:0, origin:{103.000008, 64.0}, text:{text:“ うううううう”, font:“HiraKakuProN-W3″}}
    
make new shape at end of graphics with properties {fill:no fill, draws shadow:false, size:{197.500015, 36.0}, side padding:0, thickness:0.25, autosizing:vertically only, vertical padding:0, origin:{300.5, 64.0}, text:{text:“えええええええええええええええええええええええええええええ”, font:“HiraKakuProN-W3″}}
    
    
assemble (graphics -4 through -1) table shape {2, 2}
  end tell
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/12/06 現在表示中のCanvasに存在しているラインのうち青いものに影を付ける

OmniGraffleで、現在表示中のCanvasに存在しているラインのうち青いものだけに影を付けるAppleScriptです。

矢印だけに影を付けるとか、さまざまなフィルター参照が使えると便利なことでしょう。

スクリプト名:現在表示中のCanvasに存在しているラインのうち青いものに影を付ける
tell application “OmniGraffle 5″
  tell canvas of front window
    tell (every line whose stroke color is equal to {0.0, 0.0, 1.0}) –フィルタ参照で青いものだけ抽出
      set draws shadow to true
    end tell
  end tell
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/12/06 リンクつき目次を作成する v1

OmniGraffleで、リンクつき目次を作成するAppleScriptです。

目次を作るAppleScriptで、単なるテキストベースの目次を作成できました。

この、目次は単に「ページ数、タブ、タイトル、改行」の組み合わせで構成されているものですが、これを1行ごとに独立したオブジェクトに分解して、テキストを突っ込み、各ページへのリンクを埋め込みます。

OmniGraffle書類の状態では、あまりご利益はありませんが……OmniGraffleからPDFに書き出せば、リンクが有効な目次つきのPDFになるわけで、けっこう有用です。

スクリプト名:リンクつき目次を作成する v1
–選択中のテキストボックスの内容を行単位で分割して、それぞれを単独のテキストボックスに細分化して、
–「ページ番号 各ページのタイトル」と仮定してページ番号を取り出し、各ページにリンクを張る

tell application "OmniGraffle 5"
  
  
–選択中のテキストボックスの情報を取得
  
tell front window
    –選択中のオブジェクトを取得
    
set aSel to selection
    
if aSel = {} then return
    
set aaSel to first item of aSel
    
    
–選択中のオブジェクトの各種情報を取得する
    
set aText to text of aaSel
    
set {xSize, ySize} to size of aaSel –結果はPointで返る
    
set {xPos, yPos} to origin of aaSel –結果はPointで返る
    
    
set aFontName to font of text of aaSel
    
set aFontSize to size of text of aaSel
    
    
set aText to text of aaSel
    
    
delete aaSel –選択しておいたテキストボックスを削除する
    
  end tell
  
  
–Canvasの大きさを取得(目下、とくに意味なし)  
  
tell canvas of front window
    set {xCanvasSize, yCanvasSize} to page size –結果はPointで返る
    
–> {1155.0, 783.0}
  end tell
  
  
  
set aList to paragraphs of aText
  
set paraCount to length of aList
  
  
  
–書類および各Canvasの情報を取得する
  
set targDoc to document of front window
  
set canvasList to every canvas of targDoc
  
  
–行単位の部品のサイズを計算する
  
set aXsize to xSize
  
set aYsize to ySize / paraCount
  
  
–行単位でループ
  
set aCount to 0
  
repeat with i in aList
    set j to contents of i
    
    
if length of j > 1 then –改行のみの行をスキップ(手作業をしていると先頭とか終末に不意に入ってしまうことがある。それを無視する処理)
      
      
–テキスト各行の冒頭に数字でページ数が振ってあるものと想定
      
set pNum to first word of j
      
set linkTargCanvas to contents of item (pNum as number) of canvasList
      
      
–座標計算
      
set tmpX to xPos
      
set tmpY to yPos + (aYsize * aCount)
      
      
–テキストボックス(自称)を作成(OmniGraffleにそんなオブジェクトはない。みんな図形)
      
tell canvas of front window
        set aShape to make new shape at end of graphics with properties {stroke color:{0.0, 0.0, 0.0}, thickness:0, fill:no fill, draws shadow:false, origin:{tmpX, tmpY}, size:{aXsize, aYsize}, text:{text:j, font:aFontName, size:aFontSize, alignment:left}}
        
        
–jumpは、shapeを作成したあとで指定する必要があった(作成時にpropertyで一緒に突っ込むと無視された)
        
set (jump of aShape) to linkTargCanvas
      end tell
      
    end if
    
    
set aCount to aCount + 1
    
  end repeat
  
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/12/06 Canvasの大きさを取得(Pointで返る)

OmniGraffleで、現在表示中のCanvasの大きさを取得するAppleScriptです。

結果は、Pointで返ります。

スクリプト名:Canvasの大きさを取得(Pointで返る)
tell application "OmniGraffle 5"
  tell canvas of front window
    set {xCanvasSize, yCanvasSize} to page size –結果はPointで返る
    
–> {1155.0, 783.0}
    
  end tell
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/12/06 選択中のテキストから情報を取得

OmniGraffleで、選択中のテキストから情報を取得するAppleScriptです。

om30.jpg

スクリプト名:選択中のテキストから情報を取得
tell application "OmniGraffle 5"
  tell front window
    set aSel to selection
    
set aaSel to first item of aSel
    
    
set aText to text of aaSel
    
–> "ぴよ〜"
    
    
set {xSize, ySize} to size of aaSel
    
–> {427.0, 216.0}
    
set {xPos, yPos} to origin of aaSel
    
–> {173.785186767578, 144.184143066406}
    
    
set aFontName to font of text of aaSel
    
–> "HiraKakuProN-W3"
    
set aFontSize to size of text of aaSel
    
–> 144.0
  end tell
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/12/03 OmniGraffleで各ページに用意したtitleから、目次を作成する

OmniGraffleで、各ページ(Canvas)上に用意したtitleから、目次を作成するAppleScriptです。

OmniGraffleで仕様書を作成したときに、目次の自動生成も行えないと不便です。しかし、OmniGraffleにはタイトル用の専用オブジェクトなどという便利なものはありません。

そこで、なければ自分で勝手に作ってしまおうというわけです。

各ページ(Canvas)上に「URL」に「title」という文字を指定したテキストのオブジェクトを配置し、そこに各ページの題名を入れておくことにしました。これを(勝手に)タイトル用のオブジェクトとみなすことにしました。

本AppleScriptはこの各ページのtitleの文字列を読み取ってページ数と組み合わせて目次のテキストデータをクリップボードに転送します。以前にKeynote用に作成しておいたものをほぼそのままOmniGraffle用に転用しています。

スクリプト名:各ページに用意したtitleから、目次を作成する
set separatorC to “(” –「(1/3)」の形式で連番を振っている場合の最初のカッコを書いておく。ここでは、全角カッコを想定

–OmniGraffleでオープン中のドキュメントが存在するかを確認
tell application “OmniGraffle 5″
  set wCount to count every window –本来ならdocumentオブジェクト経由で確認したいところだが、OmniGraffleのdocumentの仕様がおかしい
  
if wCount = 0 then
    display dialog “ドキュメントがオープンされていません” buttons {“OK”} default button 1 with icon 1
    
return
  end if
end tell

–OmniGraffleの各最前面のドキュメントの各Stencilのタイトル(URLが”title”になっているもののtext)を取得する
set aList to retIndexDataFromFrontDocument() of me

–各タイトルにすでに「(1/2)」のようなナンバリングが行われていたらナンバリング部分を削除する
set newList to {}

repeat with i in aList
  set j to contents of i
  
  
set aPos to offset of separatorC in j
  
if aPos is not equal to 0 then
    set j to text 1 thru (aPos - 1) of j
  end if
  
  
set the end of newList to j
end repeat

–目次を作成する
set sPage to 3 –ページ数カウンタ
set curItem to second item of newList
set newList2 to items 3 thru -1 of newList

set outList to {{2, curItem}} –出力用データ

repeat with i in newList2
  set j to contents of i
  
  
if j = curItem then
    –何もしない
  else
    set curItem to j
    
set the end of outList to {sPage, j}
  end if
  
  
set sPage to sPage + 1
  
end repeat

set aText to retItemDelimedAndParagraphDelimedText(outList, tab, return) of me
set the clipboard to aText

–最前面のドキュメントからインデックス用データを取得する
on retIndexDataFromFrontDocument()
  
  
tell application “OmniGraffle 5″
    tell front document
      set cList to every canvas
      
      
set pCount to 1
      
set pList to {}
      
      
repeat with i in cList
        set j to contents of i
        
        
tell j
          set gList to (every graphic whose url is “title”)
          
          
if gList is not equal to {} then
            set aGraphic to contents of first item of gList
            
set aText to text of aGraphic
          end if
        end tell
        
        
–set the end of pList to {pCount, aText}
        
set the end of pList to aText
        
        
set pCount to pCount + 1
        
      end repeat
    end tell
  end tell
  
  
return pList
  
end retIndexDataFromFrontDocument

–入れ子のリストを、アイテム間のデリミタとパラグラフ間のデリミタを指定してテキスト化
–というか、入れ子のリストをタブ区切りテキストにするのが目的
on retItemDelimedAndParagraphDelimedText(aList, itemDelim, paragraphDelim)
  set aText to “”
  
  
repeat with i in aList
    set aStr to retDelimedText(i, itemDelim) of me
    
set aText to aText & aStr & paragraphDelim
  end repeat
  
  
return aText
end retItemDelimedAndParagraphDelimedText

on retDelimedText(aList, aDelim)
  set aText to “”
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retDelimedText

–OmniGraffleですべてのWindowを表示状態に
on exposeEveryWindow()
  tell application “OmniGraffle 5″
    tell (every window whose miniaturized is true)
      set miniaturized to false
    end tell
  end tell
end exposeEveryWindow

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/12/02 OmniGraffleで仕様書中の画面キャプチャを自動更新する v3

2011/12/01 OmniGraffleで選択中のグラフィックのサイズを50%にする

OmniGraffleで、選択中のグラフィック(ひとつ)のサイズを50%に縮小するAppleScriptです。

グラフィックのサイズ変更はできても、文字を同様に処理できないところにOmniGraffleの深い闇を感じます。

スクリプト名:OmniGraffleで選択中のグラフィックのサイズを50%にする
tell application "OmniGraffle 5"
  tell front window
    set aSel to selection
    
set aaSel to contents of (first item of aSel)
    
    
set {aWidth, aHeight} to size of aaSel
    
set size of aaSel to {aWidth / 2, aHeight / 2}
    
  end tell
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/12/01 OmniGraffleで選択中のテキストとグラフィックのペアから、グラフィックのURLにテキストを入れる

OmniGraffleでテキストとグラフィックのペアを選択しておくと、テキストの内容をグラフィックのURLに代入するAppleScriptです。

資料の上で画面図(グラフィック)と識別子(テキスト)を並べて配置することが多いわけですが、だったらその文字情報をそのままグラフィックのURLに突っ込めると便利だろう、ということで作成したものです。

og40.jpg

このように、テキストとグラフィックの組み合わせを選択状態にしておいて、本Scriptを実行。

og41.jpg

グラフィックのURL欄にテキスト情報が代入されます。

スクリプト名:OmniGraffleで選択中のテキストとグラフィックのペアから、グラフィックのURLにテキストを入れる

tell application "OmniGraffle 5"
  tell front window
    set aSel to selection
    
    
if length of aSel is not equal to 2 then
      display dialog "選択中のアイテムが2つ(テキストとグラフィックのペア)ではありません" buttons {"OK"} default button 1
      
return
    end if
    
    
    
set bList to {}
    
set tLabel to ""
    
set tObj to ""
    
    
repeat with i in aSel
      set aText to (text of i)
      
      
if aText is not equal to "" then
        set tLabel to aText
      else
        set tObj to (contents of i)
      end if
      
      
set the end of bList to (aText is not equal to "")
    end repeat
    
    
    
if bList = {true, false} or bList = {false, true} then
      set url of tObj to tLabel
    end if
    
  end tell
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/12/01 OmniGraffleで指定名称の書類の現在表示中のCanvas上から、URLつきの画像(Solid)の情報を集める

OmniGraffleで、指定名称(名称の一部を指定してマッチング)の書類の、現在表示中のCanvas上から、URLつきの画像(Solid)の情報を集めるAppleScriptです。

書類上の全Canvasを処理するプログラムも有益ですが、現在表示中とか現在選択中のものだけ処理するという処理もまた有益なことが多いです。

オブジェクトのURL欄に識別用の文字列(URLではないもの)を入れておいて、各オブジェクトの個体識別を行うという手段はよく使います。そのために、URLを抜き出してみたり、特定のURLが仕込まれているオブジェクトを検索してみるという処理は、オブジェクトに仕込んだURLがGUI側から検索や置換などを行えないだけに、AppleScriptで書いておく必要性の高いものです。

スクリプト名:OmniGraffleで指定名称の書類の現在表示中のCanvas上から、URLつきの画像(Solid)の情報を集める
set aDocNameStrOrig to “機能定義書”
set aDocNameStr to retADocWhichContainsStr(aDocNameStrOrig) of me

set urlList to getCanvasNoAndURLFromEachSolidOnlyFromCurrentCanvas(aDocNameStr) of me
–> {{graphic id 66 of canvas id 50 of document “機能定義書v4.graffle” of application “OmniGraffle 5″, “D210″}, {graphic id 4 of canvas id 50 of document “機能定義書v4.graffle” of application “OmniGraffle 5″, “title”}, {graphic id 86557 of canvas id 50 of document “機能定義書v4.graffle” of application “OmniGraffle 5″, “D210″}}

–指定名称の書類の現在表示中のCanvas上から、URLつきの画像(Solid)の情報を集める
on getCanvasNoAndURLFromEachSolidOnlyFromCurrentCanvas(aDocNameStr)
  
  
–指定名称の書類のWindowを取得
  
set aWin to retAWindowByDocumentName(aDocNameStr) of me
  
  
tell application “OmniGraffle 5″
    set aSel to name of canvas of aWin
  end tell
  
  
  
  
tell application “OmniGraffle 5″
    tell document aDocNameStr
      
      
set urlList to {}
      
      
tell canvas aSel
        set s1List to {}
        
set sList to every solid
        
        
repeat with ii in sList
          
          
set jj to contents of ii
          
set uDat to url of jj
          
          
try
            
            
if uDat is not equal to missing value then
              set s1List to {jj, uDat}
              
set the end of urlList to s1List
            end if
            
          end try
          
        end repeat
        
      end tell
      
      
    end tell
    
    
return urlList
    
  end tell
  
end getCanvasNoAndURLFromEachSolidOnlyFromCurrentCanvas

–指定ドキュメント名称を持つWindowを返す
on retAWindowByDocumentName(aDoc)
  set wResList to {}
  
  
tell application “OmniGraffle 5″
    –可視状態で指定名称のドキュメントのウィンドウを返す(AppleScript特有のフィルタ参照処理)
    
set wList to every window whose visible is true and name of document of it is equal to aDoc
    
set wLen to length of wList
    
    
if wLen = 1 then
      –取得されたWindow数が1の場合 (通常処理)
      
return contents of first item of wList
      
    else if wLen > 1 then
      –取得されたWindow数が1以上の場合 (リカバリできなくもないエラー処理)  
      
return contents of first item of wList
      
    else
      –完全にエラー
      
return false
      
    end if
    
  end tell
end retAWindowByDocumentName

–オープン中の書類のうち、指定の文字を含むものの書類名を返す
on retADocWhichContainsStr(aStr)
  tell application “OmniGraffle 5″
    set dList to every document whose name contains aStr
    
if dList = {} then return “”
    
    
set tmpDocName to name of first item of dList
    
    
return tmpDocName
  end tell
end retADocWhichContainsStr

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/11/30 OmniGraffleですべてのWindowを表示状態に

OmniGraffleの書類のWindowをすべてDockから引きずり出すAppleScriptです。

WindowがDockに格納した状態ではエラーになる処理がいくつか(Windowへのアクセスなど)見られたので、エラー回避のためにDockからWindowを引きずり出す処理を書いてみました。

スクリプト名:OmniGraffleですべてのWindowを表示状態に
exposeEveryWindow() of me

–OmniGraffleですべてのWindowを表示状態に
on exposeEveryWindow()
  tell application "OmniGraffle 5"
    tell (every window whose miniaturized is true)
      set miniaturized to false
    end tell
  end tell
end exposeEveryWindow

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/11/30 OmniGraffleのAppleScriptがらみのバグ

OmniGraffleをいろいろ調べているうちに、AppleScriptがらみでいくつかバグを見つけてしまいました。

(1)documentのpropertiesを取得するとエラーに

OmniGraffleのAppleScript用語辞書には、以下のようにdocumentに「properties」という属性値があって、各属性をひとまとめにして取り出せる「はず」なのですが……
og30.jpg

実際にプログラムに書いて試してみるとエラーになります。

スクリプト名:OmniGraffleでdocumentのpropertiesを取得する
tell application “OmniGraffle 5″
  properties of front document
end tell

–> error “OmniGraffle 5 でエラーが起きました:AppleEvent のハンドラで誤りが起きました。” number -10000

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

(2)起動直後、何も書類をオープンしていない状態でdocumentを取得すると、stencilやtemplateが返ってくる

しかも、これらの書類を見分けるための属性値がないため、pathでも取得して切り分けるしかありません。こんな仕様、世界広しといってもこのOmniGraffleだけでしょう。これは、バグですね。

スクリプト名:OmniGraffleで起動直後にドキュメント情報を取得する
tell application “OmniGraffle 5″
  set dList to every document
end tell

–> {document “iOS UI iPhone.gstencil” of application “OmniGraffle 5″, document “48×48.gtemplate” of application “OmniGraffle 5″, document “Notes.gtemplate” of application “OmniGraffle 5″, document “Lines.gtemplate” of application “OmniGraffle 5″, document “仕様書(横型A3)” of application “OmniGraffle 5″, document “Circles.gtemplate” of application “OmniGraffle 5″, document “Blank.gtemplate” of application “OmniGraffle 5″, document “Chart2.gtemplate” of application “OmniGraffle 5″, document “Chart3.gtemplate” of application “OmniGraffle 5″, document “Chart1.gtemplate” of application “OmniGraffle 5″, document “Basic.gtemplate” of application “OmniGraffle 5″, document “Clouds.gtemplate” of application “OmniGraffle 5″, document “Chalkboard.gtemplate” of application “OmniGraffle 5″, document “機能定義書v4.graffle” of application “OmniGraffle 5″}

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

(3)WindowをDockにしまった状態で実行するとエラーになる命令がある

OmniGraffleに対してコントロールを行うAppleScriptを実行する場合には、すべてのWindowをDockから引き出さないとプログラムを正しく実行できない可能性があります。これについては、他のアプリケーションでも見かけたことがあるので、いちがいにOmniGraffle固有のバグとはいえないかもしれません。

(4)オブジェクトの位置を指定できるが、取得できない

グラフィックオブジェクトをプログラムから生成して、image offsetで座標を指定することはできるのですが、取得ができません。

(5)特定の属性値へのアクセスを行うのに、ネスティングだとエラーになるケースがある

「xxx of xxx of xxx……」と、属性値へのアクセスを1行に記述すると大丈夫なのに、tellブロックのネスティングで記述するとエラーになる例が(Windowのcanvasなど)いくつか見られます。

3日さわって、もうこのぐらい出てきているということは……

2011/11/29 OmniGraffleで画面設計図のCanvas名称をクリーニングする

OmniGraffleで、「画面設計図」をファイル名に含む書類の中のCanvas名をクリーニングするAppleScriptです。

クリーニングといっても、処理内容はかんたんなものです。改行文字などの制御文字が入っていないか、あるいはアルファベット/数字/一部の記号「以外の」文字が入っていないかをチェックし、入っていればCanvas名から削除します。

スクリプト名:OmniGraffleで画面設計図のCanvas名称をクリーニングする
tell application “OmniGraffle 5″
  set dList to every document whose name contains “画面設計図” –ここは、好きに変えてください
  
set aDoc to first item of dList
  
  
tell aDoc
    set cNameList to name of every canvas
  end tell
  
  
–各Cnavas名称でAlphabet & Numeric  の文字レンジを越えるものをチェック
  
set wrongList to {}
  
set wCount to 0
  
repeat with i in cNameList
    set j to contents of i
    
set aRes to checkAN(j) of me
    
if aRes = false then
      set the end of wrongList to j
      
set wCount to wCount + 1
    end if
  end repeat
  
  
if wCount > 0 then
    display dialog (wCount as string) & “箇所のCanvas名称にゴミが入っているので、クリーニングを行います” buttons {“OK”} default button 1
  else
    return
  end if
  

  
repeat with i in wrongList
    set j to contents of i
    
set rStr to correctAN(j) of me
    
    
set name of canvas j of aDoc to rStr
  end repeat
end tell

–与えられた文字列をAlphabet & Numericの範囲に強制する
on correctAN(aKeyword)
  set cList to characters of aKeyword
  
set newStr to “”
  
  
repeat with i in cList
    set j to contents of i
    
set aRes to checkAN(j) of me
    
if aRes = true then
      set newStr to newStr & j
    end if
  end repeat
  
  
return newStr
  
end correctAN

–与えられた文字列がAlphabet & Numericの範囲内にあるかどうかチェック
on checkAN(aKeyword)
  set anList to {“0″, “1″, “2″, “3″, “4″, “5″, “6″, “7″, “8″, “9″, “a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”, “l”, “m”, “n”, “o”, “p”, “q”, “r”, “s”, “t”, “u”, “v”, “w”, “x”, “y”, “z”, “.”, “_”, “-”, “+”, “=”}
  
set aKeyword to aKeyword as Unicode text
  
set aKeyword to aKeyword as string
  
set kList to characters of aKeyword
  
repeat with i in kList
    ignoring case
      if i is not in anList then
        return false
      end if
    end ignoring
  end repeat
  
return true
end checkAN

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/11/29 OmniGraffleで選択中の2つのグラフィックで、数字が大きいURLを持つものから小さいものにimageとURLをコピー

OmniGraffleで選択中のグラフィック間で、片方の画像の内容とURLをもう片方のグラフィックにコピーするAppleScriptです。

OmniGraffle上で個別のオブジェクトを識別するには、URLにユニークな文字列を入れておいてフィルター参照で抽出するというやりかたがオーソドックスなやり方のようです。

そもそもOmniGraffleではオブジェクトの座標値や大きさをAppleScript側から取得できないので、指定オブジェクトに一番近接する座標に存在するオブジェクトを取ってくる、というInDesignやIllustratorでは鉄板のやり方が使えません。

そのため、すでに存在しているグラフィックのサイズと位置を生かして別のグラフィックを配置するという操作も、かなり面倒です。画面から操作するのであれば、OmniGraffle書類上にグラフィックをドラッグ&ドロップして、もともと存在しているグラフィックの場所まで移動させ、サイズを調整するということになります。

単純作業であるうえにめんどくさいので、作業軽減のために最後の調整ステップを手作業で行わなくてすむようにしてみました。

画面上に、オリジナルの画像と新しい画像を配置し、それぞれにURLが(あらかじめ)指定してある状態で、オリジナルのURLのほうが小さい値になるように調整。たとえば、オリジナルのURLが「A10」で、新しい画像は「A300」だとすれば、「オリジナルのURLのほうが小さい値」であるといえます。

この状態で本AppleScriptを実行すると、新しい画像からimage属性を読み出して、オリジナルの画像オブジェクトに突っ込みます。これだけで、画像の内容のコピーが完了。あとは、URLもコピーしておきます。

説明すると長いですが、動作は割とシンプルなのでいろいろ試してみると分ると思います。個人的には、めちゃめちゃ役立っています。

スクリプト名:OmniGraffleで選択中の2つのグラフィックで、数字が大きいURLを持つものから小さいものにimageとURLをコピー

tell application “OmniGraffle 5″
  tell front window
    set aSel to selection
    
    
if length of aSel is not equal to 2 then
      display dialog “2つのグラフィックを選択してください”
      
return
    end if
    
    
set aList to {}
    
    
repeat with i in aSel
      set j to contents of i
      
set anItem to {j, url of j}
      
set the end of aList to anItem
    end repeat
    
    
–URLでソート
    
set bList to shellSortListAscending(aList, 2) of me
    
    
set Item1 to contents of first item of bList
    
set Item2 to contents of second item of bList
    
    
    
–URLが新しい(数字が大きい)ものから、古いものにイメージとURLをコピー
    
set aImage to image of (contents of first item of Item2) –取り出して
    
set image of (contents of first item of Item1) to aImage –イメージをコピー
    
    
set url of (contents of first item of Item1) to (contents of second item of Item2) –URLもコピー
    
  end tell
end tell

–シェルソートで入れ子のリストを昇順ソート
on shellSortListAscending(a, keyItem)
  set n to length of a
  
set cols to {1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1}
  
repeat with h in cols
    if (h (n - 1)) then
      repeat with i from h to (n - 1)
        set v to item (i + 1) of a
        
set j to i
        
repeat while (j h) and ((contents of item keyItem of item (j - h + 1) of a) > (item keyItem of v))
          set (item (j + 1) of a) to (item (j - h + 1) of a)
          
set j to j - h
        end repeat
        
set item (j + 1) of a to v
      end repeat
    end if
  end repeat
  
return a
end shellSortListAscending

–シェルソートで入れ子のリストを降順ソート
on shellSortListDecending(a, keyItem)
  set n to length of a
  
set cols to {1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1}
  
repeat with h in cols
    if (h (n - 1)) then
      repeat with i from h to (n - 1)
        set v to item (i + 1) of a
        
set j to i
        
repeat while (j h) and ((contents of item keyItem of item (j - h + 1) of a) < (item keyItem of v))
          set (item (j + 1) of a) to (item (j - h + 1) of a)
          
set j to j - h
        end repeat
        
set item (j + 1) of a to v
      end repeat
    end if
  end repeat
  
return a
end shellSortListDecending

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/11/29 OmniGraffleでcanvas名一覧を取得する

OmniGraffleで最前面の書類のCanvas(ページ)名称一覧を取得するAppleScriptです。

ここのところ、OmniGraffle相手に巨大なAppleScriptばかり作っていましたが、案外こんなシンプルなものが役立ったりしています。

スクリプト名:OmniGraffleでcanvas名一覧を取得する
tell application "OmniGraffle 5"
  tell front document
    set nList to name of every canvas
  end tell
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/11/28 OmniGraffleで表示中のCanvasを切り替えてループし、各Canvasの表示倍率を設定する

OmniGraffleで、現在表示中のドキュメントのすべてのCanvasに一律で表示倍率を設定するAppleScriptです。

表示倍率は、1.0で100%、2.0で200%です。

スクリプト名:OmniGraffleで表示中のCanvasを切り替えてループし、各Canvasの表示倍率を設定する
set zoomNum to 1.5 –1で100%

tell application "OmniGraffle 5"
  set aDoc to document of front window
  
  
tell aDoc
    set cList to every canvas
  end tell
  
  
repeat with i in cList
    set j to contents of i
    
set canvas of front window to j –表示中のCanvasを切り替える
    
    
tell front window
      set zoom to zoomNum
    end tell
  end repeat
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/11/28 OmniGraffleで表示中のCanvasを切り替えてループし、各Canvasの表示倍率を取得する

OmniGraffleで、現在表示中のドキュメントのすべてのCanvasの表示倍率を取得するAppleScriptです。

スクリプト名:OmniGraffleで表示中のCanvasを切り替えてループし、各Canvasの表示倍率を取得する
tell application “OmniGraffle 5″
  set aDoc to document of front window
  
  
tell aDoc
    set cList to every canvas
  end tell
  
  
set zList to {}
  
  
repeat with i in cList
    set j to contents of i
    
set canvas of front window to j –表示中のCanvasを切り替える
    
    
tell front window
      set the end of zList to zoom
    end tell
  end repeat
end tell

zList

–> {1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 0.907243788242, 0.907243788242}

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/11/28 OmniGraffleで指定ドキュメントのWindowを求める v2

OmniGraffleで指定ドキュメントのWindowへの参照を取得するAppleScriptです。

OmniGraffleでは、指定ドキュメント中の表示Canvasの切り換えは、Windowの下のcanvasを書き換えることで実現するのですが、その際に指定ドキュメントのWindowがどのWindowかを調べておく必要があります。

ドキュメントのWindowについては簡単に調査できるのですが、特定ドキュメントのWindowを調べる際にはOmniGraffle自体にそれを意識した機能が実装されていないため、ちょっとだけ苦労しました。

スクリプト名:OmniGraffleで指定ドキュメントのWindowを求める v2
set aDocName to “仕様書のつもり”
set wRes to retAWindowByDocumentName(aDocName) of me
–> window id 967 of application “OmniGraffle 5″

–指定ドキュメント名称を持つWindowを返す
on retAWindowByDocumentName(aDoc)
  set wResList to {}
  
  
tell application “OmniGraffle 5″
    –可視状態で指定名称のドキュメントのウィンドウを返す(AppleScript特有のフィルタ参照処理)
    
set wList to every window whose visible is true and name of document of it is equal to aDoc
    
set wLen to length of wList
    
    
if wLen = 1 then
      –取得されたWindow数が1の場合 (通常処理)
      
return contents of first item of wList
      
    else if wLen > 1 then
      –取得されたWindow数が1以上の場合 (リカバリできなくもないエラー処理)  
      
return contents of first item of wList
      
    else
      –完全にエラー
      
return false
      
    end if
    
  end tell
end retAWindowByDocumentName

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/11/28 指定名称のOmniGraffle書類中に、urlListで示した名称のCanvasが存在するかを取得する v2

OmniGraffleで、指定の書類中に指定したCanvasが存在しているかをチェックするAppleScriptの高速処理版です。

AppleScriptの処理速度を向上させる場合には、アプリケーションとの通信回数を最低限に抑えることが一番有効です。この場合には、OmniGraffleに指定書類中のCanvasの存在確認を行うさい、アプリケーションに逐一確認してもらうのではなく、Cnavasの名称をすべて取得して、取得したデータを相手に処理を行うことで処理速度を向上させています。

さすがにCanvasが3枚ぐらいでは速度差は分らないところですが、これが10倍とか100倍になってくると段違いの高速処理を体感できます。

スクリプト名:指定名称のOmniGraffle書類中に、urlListで示した名称のCanvasが存在するかを取得する v2

set urlList to {"A101", "A102", "A103", "A104"}
set aDocNameStr to "画面設計図"

set aRes to getExistenceOfEachCanvasName(urlList, aDocNameStr) of me
–> {true, true, true, false}

–指定名称のOmniGraffle書類中に、urlListで示した名称のCanvasが存在するかを取得する v2
on getExistenceOfEachCanvasName(urlList, aDocNameStr)
  set eList to {}
  
  
tell application "OmniGraffle 5"
    tell document aDocNameStr
      set cList to name of every canvas –最初にCanvas名称リストを一気に取得してアプリケーションとの通信頻度を下げる
    end tell
  end tell
  
  
–以下、ただのリスト内の存在確認演算(速い)
  
repeat with i in urlList
    set aURL to contents of i
    
set aExist to (aURL is in cList)
    
    
set the end of eList to aExist
  end repeat
  
  
return eList
  
end getExistenceOfEachCanvasName

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/11/28 指定名称のOmniGraffle書類中に、urlListで示した名称のCanvasが存在するかを取得する

OmniGraffleで、指定の書類中に指定したCanvasが存在しているかをチェックするAppleScriptです。

指定名称のドキュメントの中に、リストで指定したCanvas(ページ)が存在しているかをチェックします。

たとえば、「A101」「A102」「A103」の各Cnavasを持つ書類「画面設計図」があったとして、

og20.jpg

この書類に対して、リスト{”A101″, “A102″, “A103″, “A104″}で確認を行うと、「A104」だけは存在していません。本AppleScriptでこの書類に対して処理を行うと、存在しているCanvasはtrue、存在していないCanvasについてはfalseを返します。

仕様書内のURLつきオブジェクトの情報を取得して、それが「画面設計図」(それぞれの画面図を1ページ(Canvas)ごとに入れて管理しておくOmniGraffle書類)に存在しているかどうかチェックを行うために作成しました。

スクリプト名:指定名称のOmniGraffle書類中に、urlListで示した名称のCanvasが存在するかを取得する

set urlList to {“A101″, “A102″, “A103″, “A104″}
set aDocNameStr to “画面設計図”

set aRes to getExistenceOfEachCanvasName(urlList, aDocNameStr) of me
–> {true, true, true, false}

–指定名称のOmniGraffle書類中に、urlListで示した名称のCanvasが存在するかを取得する
on getExistenceOfEachCanvasName(urlList, aDocNameStr)
  tell application “OmniGraffle 5″
    tell document aDocNameStr
      set eList to {}
      
      
repeat with i in urlList
        set aURL to contents of i
        
set aExist to exists canvas aURL
        
        
set the end of eList to aExist
      end repeat
      
    end tell
  end tell
  
  
return eList
end getExistenceOfEachCanvasName

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/11/28 OmniGraffleで指定文字を名前に含むドキュメントをオープンしているかチェック

OmniGraffleで、指定文字を名前に含む書類をオープンしているかをチェックするAppleScriptです。

複数の書類を対象にして処理を行うさい、処理対象となる書類については、ファイル名すべてを指定しておく場合もありますが……一部のキーワードだけ含んでいればそれでよしとする場合もあります。そうした、処理の柔軟性を持たせるために作成したAppleScriptです。

スクリプト名:OmniGraffleで指定文字を名前に含むドキュメントをオープンしているかチェック
set dRes to getExistenceOf2Docs("画面設計図", {"仕様書", "機能設計"}) of me
–> {document "画面設計図" of application "OmniGraffle 5", document "仕様書のつもり" of application "OmniGraffle 5"}

–OmniGraffleで指定文字を名前に含むドキュメントをオープンしているかチェック
–とくにエラーチェックなどは行っていないレベルの部品
on getExistenceOf2Docs(aName, bNameList)
  –bNameListの要素数が2であることを前提として処理。それ以外は考慮しない
  
set bName to contents of first item of bNameList
  
set cName to contents of second item of bNameList
  
  
tell application "OmniGraffle 5"
    set d1List to every document whose name begins with aName –画面設計図
    
set d2List to every document whose name contains bName or name of it contains cName –仕様書か機能定義書
    
    
if ((length of d1List) = 1) and ((length of d2List) = 1) then
      return {first item of d1List, first item of d2List}
    else
      return {false, false} –オープンしていない場合
    end if
  end tell
end getExistenceOf2Docs

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/11/28 OmniGraffleで指定書類からURLつきの画像の情報を集める

OmniGraffleで、指定書類からURLつき画像の情報を集めるAppleScriptです。

基本的に、OmniGraffleで現在の書類からURLつきの画像の情報を集めるScriptに修正を行ったもので、「現在の最前面にオープンしている書類」ではなく名称でドキュメント名を指定して処理を行えるようにしたものです。

AppleScriptで最前面のドキュメントに対して操作を行うケースは多いですが、複数の書類をオープンして処理を行う場合には、最前面に切り替えていられない場合もあるので、このように柔軟にアクセスできるようテストを行っておく必要があります。

スクリプト名:OmniGraffleで指定書類からURLつきの画像の情報を集める
set gRes to getCanvasNoAndURLFromEachSolid("仕様書のつもり") of me

–> {{1, graphic id 3 of canvas id 1 of document "仕様書のつもり" of application "OmniGraffle 5", "A101"}, {2, graphic id 3 of canvas id 2 of document "仕様書のつもり" of application "OmniGraffle 5", "A102"}, {3, graphic id 3 of canvas id 3 of document "仕様書のつもり" of application "OmniGraffle 5", "A103"}}

–指定名称の書類から、URLつきの画像(Solid)の情報を集める
on getCanvasNoAndURLFromEachSolid(aDocNameStr)
  tell application "OmniGraffle 5"
    tell document aDocNameStr
      set cCount to count every canvas
      
      
set urlList to {}
      
      
repeat with i from 1 to cCount by 1
        tell canvas i
          set s1List to {}
          
set sList to every solid
          
          
repeat with ii in sList
            
            
set jj to contents of ii
            
set uDat to url of jj
            
            
try
              
              
if uDat is not equal to missing value then
                set s1List to {i, jj, uDat}
                
set the end of urlList to s1List
              end if
              
            end try
            
          end repeat
          
        end tell
      end repeat
      
    end tell
    
    
return urlList
    
  end tell
  
end getCanvasNoAndURLFromEachSolid

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に