ごんれのラボ

iOS、Android、Adobe系ソフトの自動化スクリプトのことを書き連ねています。

テキストのアウトライン

過去のエントリにアップしたAppleScriptだとうまくいかない事例があったので修正版を新しくこのエントリにアップします。

ことの顛末は一昨日Twitterのフォロワーさんから「10.6+IllustratorCS4だとうまく起動しない」と報告を受けたことに端を発します。

最初は個体差か何かかと思って私とものかのさんとフォロワーさんとの間で試行錯誤してたのですが、あかつきさんから「10.6+IllustratorCS4だとアプリ形式はうまく動かない」と教えていただき、なんじゃそりゃー、と。

試しに家のMacminiで試したら動かない(書いたときはMacBook(10.5.8)だったのです)。

それでものかのさんが暫定版を書いてくれたものの「あとはこうちゃんがアプリ形式でうまく動かせたら完璧だね!」と宿題を投げてくれたもんだから、昨日必死こいて書きましたよ(^^;

まず、過去に書いたAppleScriptがこれ(ちなみに10.6+IllustratorCS4じゃなきゃ動くんです…)

--実行型

on run

tell application "Adobe Illustrator"

activate

display dialog "文字をアウトライン化します"

set myDoc to document 1

my creatOutline(myDoc)

display dialog "終了"

end tell

end run

--ドラッグ&ドロップ型

on open thisList

display dialog "文字をアウトライン化して、ドキュメントを上書き保存します"

repeat with k in thisList

tell application "Adobe Illustrator"

activate

open k

set myDoc to document 1

my creatOutline(myDoc)

tell myDoc

close with saving

end tell

end tell

end repeat

tell application "Finder"

activate

display dialog "終了"

end tell

end open

on creatOutline(myDoc)

tell application "Adobe Illustrator"

activate

tell myDoc

--<処理1>レイヤーのロックを外す

--ロックされてるレイヤーを変数に(フィルタ参照形式)

set lockedLayer_list to every layer whose locked is true

--ロックされたレイヤー分繰り返す

repeat with a from 1 to count of lockedLayer_list

set currentLayer to item a of lockedLayer_list --処理用に代入

set locked of currentLayer to false --ロックを外す(Tellしなくてもofで繋げればワンライナーできる)

end repeat

--<処理2>非表示レイヤーを表示

--非表示のレイヤーを変数に(フィルタ参照形式)

set visibleFalseLayer_list to every layer whose visible is false

--ロックされたレイヤー分繰り返す

repeat with a from 1 to count of visibleFalseLayer_list

set currentLayer to item a of visibleFalseLayer_list --処理用に代入

set visible of currentLayer to true --レイヤーを表示状態に(Tellしなくてもofで繋げればワンライナーできる)

end repeat

--<処理3>ロックを外してアウトライン化

--グループ化されてても関係なくテキストフレームの処理ができるみたい

set TexrFrame_list to every text frame --Document内のText Frameをリスト化

repeat with a from 1 to count of TexrFrame_list

set currentFrame to item ((count of TexrFrame_list) - a + 1) of TexrFrame_list --indexの大きい方から逆順で処理

set locked of currentFrame to false --ロックを外す

convert to paths of currentFrame --テキストのアウトライン化

end repeat

--<処理4>非表示レイヤーを非表示に

--非表示のレイヤーを変数に(フィルタ参照形式)

--元々非表示だったレイヤー分繰り返す

repeat with a from 1 to count of visibleFalseLayer_list

set currentLayer to item a of visibleFalseLayer_list --処理用に代入

set visible of currentLayer to false --レイヤーを非表示状態に(Tellしなくてもofで繋げればワンライナーできる)

end repeat

end tell

end tell

end creatOutline

とりあえず上記AppleScriptの怪しいところにdisplay dialog入れて検証。

どうやら取り出したフルパスをIllustratorからopenするところでこけている模様。

これはon runとon open ~の両方でダメみたい。

なんじゃそりゃー。

ファイルを開けないんじゃなんもできんがな。

ちょっとくじけかけたところで「そだ、Finderからopenすれないいんじゃね?」と思いつく。

書いてみたらちゃんと開いた。

でもよく考えたらIllustratorと関連づけされてないファイル(windowsで書き出されたepsとか)はプレビューで開いちゃうからダメじゃん…。

むーーーー。

ムキになってググってたら「open ~ using application file フルパス」でアプリケーションを指定して開けることを知った。

じゃあ次は起動しているIllustratorのフルパスを取得しようってんで、またもググる。

そしたらSyetem Eventsにtellして起動しているプロセスのプロパティを取得できることを知った。

最初はググったときに使われてたプロパティでIllustratorを特定してたんだけど、10.4ではそのプロパティが定義されてなかったのでクリエータータイプで特定するようにした。

過程でOSのバージョンで分岐も考えたんだけどやめた。

そして、ついでに起動してなかったらスクリプトを終了する処理も追加。

勝手にIllustratorを起動されても気持ち悪いしね。

続いて過去のエントリのコメントで要望のあった別名保存処理も加えてみた。

別名保存だとepsだaiだと処理をわけないといけなかったので、デスクトップにスクリプトを起動したときの時刻名のフォルダを作成して、そこに処理するファイルを複製させてみた。

家だと大容量のファイルがなかったので、実際に数百MBのファイルを処理させたらうまくいかないかもだけど、そのときは自分で書き直してください。

set folName to my makeBackFol(thisList)をエスケープして、最後のdisplay dialogのfolNameを消せば、とりあえず動くはず。

もひとつ要望のあったアピアランスの分割は、AppleScriptから制御できないようなので実装できず。

----追記

Twitterで突っ込まれたので訂正。

Illustratorには「アピアランスの分割」の予約語はないけど、GUIスクリプティングで実行できると思う。

GUIスクリプティングについてはこちらに詳細が載っています。

けどすべてのIllustratorのバージョンで「アピアランスの分割」という名称か、そもそも同じメニュー項目かどうかっていうのも分からないし、調べるのは面倒です。

あとGUIスクリプティングにはマシン側の環境設定もいじる必要がありますし、動作も決して早くはなかったと思います。

なので、今回は実装しません。

興味のある方はご自分で書いて実装してみるのもありだとは思いますが。

----追記終わり

で、完成したのがこれ。

(*

SnowLeopard上のAdobe Illustrator CS4ではアプリ形式のAppleScriptの中の「on ~」がうまく動作しない。

つまり「on run」の実行形式、「on open ~」で始まるドロップレット形式のAppleScript内でのopenが動作しないということ。

そのためSystem EventsにTellして起動しているAdobe Illustratorのフルパスを取得して

そのフルパスをFinderに渡して「Adobe Illsutratorでファイルを開く」とすることによって回避した。

*)

--実行型--monokanoさんの書いたものを流用

on run

activate

display dialog "文字をアウトライン化します"

--Illustratorの起動してるかチェック

set illPath to my runAICheck()

if illPath is "" then --パスの有無を見て起動してるかどうか判断

activate

set buttonPush to display dialog "Adobe Illustratorを起動してから実行してください" buttons {"OK"} default button "OK"

if button returned of buttonPush is "OK" then return

end if

activate

tell application "Adobe Illustrator"

if not (exists document 1) then

-- 開いているドキュメントがない

-- ファイル選択ダイアログ表示

set thisList to choose file with prompt "Illustratorファイルを選択してください(複数選択可)" with multiple selections allowed without invisibles

--バックアップする処理へ

set folName to my makeBackFol(thisList)

repeat with k in thisList

tell application "Finder"

--using application file ~ で「与えたフルパスのアプリケーションで開く」となる

open k using application file illPath

end tell

set myDoc to document 1

my creatOutline(myDoc)

close myDoc with saving --上書き保存

end repeat

display dialog "終了しました。バックアップファイルはデスクトップにあるフォルダの「" & folName & "」の中にコピーしました"

else

--開いているドキュメントがある

--最前面のドキュメントだけやる

activate

set myDoc to document 1

my creatOutline(myDoc)

-- 上書き保存しない

display dialog "終了しました。保存はしてません"

end if

end tell

end run

--ドラッグ&ドロップ型

on open thisList

--Illustratorから開くためにFinderを通す

tell application "Finder"

display dialog "文字をアウトライン化します"

--Illustratorの起動してるかチェック

set illPath to my runAICheck()

if illPath is "" then --パスの有無を見て起動してるかどうか判断

activate

set buttonPush to display dialog "Adobe Illustratorを起動してから実行してください" buttons {"OK"} default button "OK"

if button returned of buttonPush is "OK" then return

end if

--バックアップする処理へ

set folName to my makeBackFol(thisList)

repeat with k in thisList

--using application file ~ で「与えたフルパスのアプリケーションで開く」となる

open k using application file illPath

tell application "Adobe Illustrator"

activate

set myDoc to document 1

my creatOutline(myDoc)

tell myDoc

close with saving

end tell

end tell

end repeat

activate

display dialog "終了しました。バックアップファイルはデスクトップにあるフォルダの「" & folName & "」の中にコピーしました"

end tell

end open

--メイン処理

to creatOutline(myDoc)

tell application "Adobe Illustrator"

activate

tell myDoc

--<処理1>レイヤーのロックを外す

--ロックされてるレイヤーを変数に(フィルタ参照形式)

set lockedLayer_list to every layer whose locked is true

--ロックされたレイヤー分繰り返す

repeat with a from 1 to count of lockedLayer_list

set currentLayer to item a of lockedLayer_list --処理用に代入

set locked of currentLayer to false --ロックを外す(Tellしなくてもofで繋げればワンライナーできる)

end repeat

--<処理2>非表示レイヤーを表示

--非表示のレイヤーを変数に(フィルタ参照形式)

set visibleFalseLayer_list to every layer whose visible is false

--ロックされたレイヤー分繰り返す

repeat with a from 1 to count of visibleFalseLayer_list

set currentLayer to item a of visibleFalseLayer_list --処理用に代入

set visible of currentLayer to true --レイヤーを表示状態に(Tellしなくてもofで繋げればワンライナーできる)

end repeat

--<処理3>ロックを外してアウトライン化

--グループ化されてても関係なくテキストフレームの処理ができるみたい

set TexrFrame_list to every text frame --Document内のText Frameをリスト化

repeat with a from 1 to count of TexrFrame_list

set currentFrame to item ((count of TexrFrame_list) - a + 1) of TexrFrame_list --indexの大きい方から逆順で処理

set locked of currentFrame to false --ロックを外す

convert to paths of currentFrame --テキストのアウトライン化

end repeat

--<処理4>非表示レイヤーを非表示に

--非表示のレイヤーを変数に(フィルタ参照形式)

--元々非表示だったレイヤー分繰り返す

repeat with a from 1 to count of visibleFalseLayer_list

set currentLayer to item a of visibleFalseLayer_list --処理用に代入

set visible of currentLayer to false --レイヤーを非表示状態に(Tellしなくてもofで繋げればワンライナーできる)

end repeat

end tell

end tell

end creatOutline

--元ファイルをバックアップする処理

to makeBackFol(thisList)

tell application "Finder"

--バックアップファイルのコピー用にデスクトップに現在時刻名のフォルダを作成する

set dPath to desktop as text --デスクトップのパス取得

set folName to (do shell script "date '+%Y-%m-%d %H-%M-%S'") --現在時刻取得

set backFol to make new folder at dPath with properties {name:folName} --デスクトップにフォルダ作成

set label index of backFol to 2 --ラベルを付ける

repeat with i in thisList

duplicate i to backFol --デスクトップのbackFolに複製する

end repeat

return folName

end tell

end makeBackFol

(*--OSのバージョンで分岐を考えたけどやめた

to osVerCheck()

--OSのバージョンを取得

set v1 to system attribute "sys1" -->10(Tigerなら)

set v2 to system attribute "sys2" -->4(Tigerなら)

--set v3 to system attribute "sys3"-->11(Tigerなら)

set v to {v1, v2} as string --104(Tigerなら)

end osVerCheck

*)

--Illustratorが起動しているかチェック

to runAICheck()

tell application "System Events"

try --Illustratorが起動していたら

--起動しているアプリケーションの中からIllustratorを探してフルパスを取得している

set illPath to file of first item of (every process whose creator type is "ART5")

return illPath

on error --起動してなかったら空の変数を返す

set illPath to ""

return illPath

end try

end tell

end runAICheck

検証にお付き合いいただいたフォロワーさん、ものかのさん、あかつきさん、ありがとうございました。

----2011.12.20追記

スクリプトをDLできるようにしました。

Illustratorのテキストをアウトライン