はじめに
繁忙期も佳境になり、仕事に忙殺されております。
しかしだからこそ、スクリプトという享楽に打ち込んでしまうのもまた必然…。
それはさておき、できそうだなと思って取り組んでこなかったスクリプトができてしまったので紹介したいと思います。
以前東京のDTP勉強会(2017年10月21日開催回)で登壇させていただいたときに紹介した、保存バージョンをチェックするスクリプトがありました。ご存知ない方はこちらで↓。
スライド(PDF)
配布資料(PDF)
そのスクリプトは、ファイルを開いた際に、ファイルを保存したときに記録されたバージョン表記と、今現在実際に動作させているInDesignのバージョンを比較し、それが一致しなければその旨の警告を出すというものでした。これは警告を出すものの、ファイル自体は開きます。
というか、ファイルを開くという動作の間にファイル情報を調べる処理を仕込んだだけで、実際にはアプリケーションの動作に何も手を挟みません。
また、こういった「保存バージョンを確認して開く」手助けをしてくれるアプリケーションが実はもうあります。Macであればものかのさんの「Glee」、Winであればお〜まちさんの「open_the_indd」があります。どちらも拡張子の関連付けをおこない、Finder(エクスプローラ)上でダブルクリックするだけで、保存されたInDesignのバージョンでファイルを開くことができるという素晴らしいアプリケーションです。
で、これから紹介するスクリプトは、あくまでInDesignで動作するスクリプトです。なのでFinderでダブルクリックしてもバージョンを選んで開いてくれたりはしません。
その代わり、これらのアプリケーションを介さない方法でファイルを開いても(InDesignにファイルをドラッグ、もしくは右クリックから開くInDesignを指定など)、水際で開くバージョンを確認することができます。
挙動としては、一旦「違うバージョンのInDesignで開こうとしているけど、本当に開いていいんだよね?」という確認をします。それでも「いいよ、開いて!」とゴーサインを出してから初めて開くようにするものです。
動作画面
まずは百聞は一見に如かずということで、動作をGIFにしましたのでご覧ください。
ここで「はい」(InDesignのバージョンによってはYes)を選択するとファイル開き、「いいえ」(もしくはNo)を選択するとファイルを開く動作を中断します。要するにファイルを開きません。
見かけの動作としては本当にこれだけなので、派手さはまったくありませんw
コード
#targetengine versionChecker2 app.addEventListener ("beforeOpen", function (e){ //XMPメタデータを読み書きするライブラリ //このXMPtoolライブラリについては、Ten A先生の記事 //https://goo.gl/oEg2QE //より拝借しました。詳細はこちらの記事をご参照ください。 var XMPtool = { ns : "hoge", prefix : "fuga:",//custom metada f : new Object(), read : function(prop){//read exist custom metadata. if(xmpLib==undefined) var xmpLib = new ExternalObject('lib:AdobeXMPScript'); var xmpFile = new XMPFile(this.f.fsName, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_READ); var xmpPackets = xmpFile.getXMP(); var xmp = new XMPMeta(xmpPackets.serialize()); return xmp.getProperty(this.ns, prop).toString(); }, write : function(prop, val){ //argumetns{prop:String/property of custom metadata, val1:String/value} if(xmpLib==undefined) var xmpLib = new ExternalObject('lib:AdobeXMPScript'); var xmpFile = new XMPFile(this.f.fsName, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_UPDATE); var xmp = xmpFile.getXMP(); var mt = new XMPMeta(xmp.serialize()); XMPMeta.registerNamespace(this.ns, this.prefix); mt.setProperty(this.ns, prop, val); if (xmpFile.canPutXMP(xmp)) xmpFile.putXMP(mt); xmpFile.closeFile(XMPConst.CLOSE_UPDATE_SAFELY); } } XMPtool.ns = "http://ns.adobe.com/xap/1.0/"; //XMP name space XMPtool.f = File(e.fullName); var creatorTool = XMPtool.read("CreatorTool"); //read "CreatorTool" from XMPfile //取得したCreatorToolから必要な部分を正規表現で抽出 var createdVer = creatorTool.match(/((CC( [0-9\.]+)*)|(CS)?[0-9\.]{1,3})/)[1]; //保存バージョンを[表示バージョン名, メジャーバージョン数値]に変換する var myVerLib; switch (createdVer){ case "3.0": myVerLib = ["CS", 3]; break; case "4.0": myVerLib = ["CS2", 4]; break; case "5.0": myVerLib = ["CS3", 5]; break; case "6.0": myVerLib = ["CS4", 6]; break; case "7.0": myVerLib = ["CS5", 7]; break; case "7.5": myVerLib = ["CS5.5", 7.5]; break; case "CS6": myVerLib = ["CS6", 8]; break; case "CC": myVerLib = ["CC", 9]; break; case "CC 2014": myVerLib = ["CC2014", 10]; break; case "CC 2015": myVerLib = ["CC2015", 11]; break; case "CC 2017": myVerLib = ["CC2017", 12]; break; case "CC 13.0": myVerLib = ["CC2018", 13]; break; default: myVerLib = ["判別できないバージョン", 0]; } //現在開いているInDesignのバージョンのメジャーバージョン(CS5.5は7.5とする) var appVer = (parseFloat(app.version) === 7.5)? 7.5: parseInt(app.version, 10); //メジャーバージョンチェック if (myVerLib[1] !== appVer){ if (!confirm (myVerLib[0]+"で保存されたデータです。開いてよろしいですか?")){ e.preventDefault(); return; } } });
そこそこ長いのでjsxファイルを末尾に用意してあります。コピペではなくダウンロードしたい方はそちらをご利用ください。
説明など
勉強会のときのスクリプトと話が行ったり来たりで申し訳ないのですが、勉強会で紹介したスクリプトはafterOpen
イベントを利用していました。つまり、ファイルを開いた後でスクリプトを実行し、開いているDocument
オブジェクトからメタデータを読み込むという手法でした。
ですが今回は開く前に確認ダイアログを出したかったので、beforeOpen
イベントを使いました。
ここで最初のつまづきがあったのですが、イベントの引数にDocument
オブジェクトが入ってこないのです。
app.addEventListener ("beforeOpen", function (e){
冒頭にあるイベントリスナーを定義する部分ですが、このe
にイベントのトリガーとなったものが入ってくるのがイベントスクリプトの仕組みです。勉強会のときのスクリプトはafterOpen
イベントだったので、この引数にはDocument
オブジェクトやLayoutWindow
オブジェクトが入っていました。
ですが今回の引数のe.target
を調べてみたところ、Application
オブジェクトだったのです。
これから開こうとしているファイルをどのように取得すればいいやら…と思って、Adobe自動化総合フォーラムにこのことを書き込んでみました。
で、やっぱりTen A先生にご教示いただきましたw
そう、e.fullName
でファイルパスが取れる!
そこからFile
オブジェクトで実際のファイルを特定できた!
…
というところまでは良かったのです…。
勉強会のスクリプトは、Document
オブジェクトからmetadataPreferences
プロパティにアクセスして保存バージョンを取得しました。今回はFile
オブジェクトからメタデータにアクセスしなくてはならなかったのです(File
オブジェクトにmetadataPreferences
プロパティはありません)。
仕方なく、
for (key in fileObj) $.writeln(key + ": " + fileObj[key]);
とかってやってプロパティを調べようと思ったんですけど、結果は
何もコンソールに取得できない…。久しぶりに絶望を味わった瞬間…。
気を取り直して、File
オブジェクトのメタデータ、つまりXMPにアクセスする方法を調べると、あったのです。それも超便利なライブラリとして。
またかよ! またTen A先生かよ!www
ってまじで思いました。本当にありがとうございます。冒頭のXMPtool
の部分は記事からほとんどそのまま拝借しています。
ということで、僕のコードはその下からです。
XMPtool.ns = "http://ns.adobe.com/xap/1.0/"; //XMP name space XMPtool.f = File(e.fullName); var creatorTool = XMPtool.read("CreatorTool"); //read "CreatorTool" from XMPfile
XMPにアクセスするにはname spaceの指定が必要なのでそれを与えます。続いてイベントの引数からファイルを特定してFile
オブジェクトとします。これをもとにXMPからCreatorTool
の部分を読み込みます。簡単すぎて笑っちゃいますね。これで保存バージョンを取得できました。
あとは勉強会のときのスクリプトとほとんど変わりません。
//取得したCreatorToolから必要な部分を正規表現で抽出 var createdVer = creatorTool.match(/((CC( [0-9\.]+)*)|(CS)?[0-9\.]{1,3})/)[1];
正規表現で必要な部分だけを抽出します。この正規表現も、InDesignのバージョン表記に合わせて適宜書き換えていく必要がありますので注意してください。この正規表現はCS3〜CC2018(13.x)まで対応しています。
//保存バージョンを[表示バージョン名, メジャーバージョン数値]に変換する var myVerLib; switch (createdVer){ case "3.0": myVerLib = ["CS", 3]; break; case "4.0": myVerLib = ["CS2", 4]; break; case "5.0": myVerLib = ["CS3", 5]; break; case "6.0": myVerLib = ["CS4", 6]; break; case "7.0": myVerLib = ["CS5", 7]; break; case "7.5": myVerLib = ["CS5.5", 7.5]; break; case "CS6": myVerLib = ["CS6", 8]; break; case "CC": myVerLib = ["CC", 9]; break; case "CC 2014": myVerLib = ["CC2014", 10]; break; case "CC 2015": myVerLib = ["CC2015", 11]; break; case "CC 2017": myVerLib = ["CC2017", 12]; break; case "CC 13.0": myVerLib = ["CC2018", 13]; break; default: myVerLib = ["判別できないバージョン", 0]; }
ここでswitch文を使って、XMPから得られた保存バージョン情報の部分をふるいにかけています。ただCS2以下はもう面倒くさいので「判別できないバージョン」として一括りにしてしまいました^^;;
//現在開いているInDesignのバージョンのメジャーバージョン(CS5.5は7.5とする) var appVer = (parseFloat(app.version) === 7.5)? 7.5: parseInt(app.version, 10);
現在動作しているInDesignのバージョンを取得しています。CS5.5なんて中途半端なのがいなければ、
parseInt(app.version, 10);
だけで済んだのですよ?
//メジャーバージョンチェック if (myVerLib[1] !== appVer){ if (!confirm (myVerLib[0]+"で保存されたデータです。開いてよろしいですか?")){ e.preventDefault(); return; } }
最後にそれぞれのバージョンを比較し、バージョンが違う場合はダイアログを出して確認します。その上でやっぱりやめた! ということであれば、
e.preventDefault();
このメソッドを使ってファイルを開こうとする動作を終了させます。このメソッド自体は、勉強会のスクリプトの3つめ、PDF書き出し前チェックリスト表示でも紹介したものです。
こうして、無事に「保存バージョンをチェックして、開く前に確認し、開きたくなければそのまま開かない」ってスクリプトができあがりました。
ダウンロード
このスクリプトファイルはこちらからどうぞ。
startup scriptの使い方がわからない方は、記事先頭の勉強会のスライドを見てください^^/
そんなこんなでTen A先生に大変お世話になったスクリプトですが、こんなこともできるInDesignのスクリプトは最高に面白いですね。