Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
品質を担保するInDesignスクリプト
Search
Yusuke S.
October 21, 2017
Technology
0
310
品質を担保するInDesignスクリプト
2017年10月に東京のDTP勉強会で登壇した際のセッションスライド。
Yusuke S.
October 21, 2017
Tweet
Share
More Decks by Yusuke S.
See All by Yusuke S.
InDesignのスクリプトを使い倒そう!
uskes
0
980
[page2020] スクリプトで未然に防ぐInDesignの不具合と作業ミス
uskes
1
2.1k
GAS for DTPer -- はじめの一歩
uskes
1
450
Other Decks in Technology
See All in Technology
Amazon Bedrock Knowledge basesにLangfuse導入してみた
sonoda_mj
2
290
OSSの実装を参考にBedrockエージェントを作る
moritalous
2
330
最近のSRE支援ニーズ考察 | sogaoh's LT @ Road to SRE NEXT@札幌
sogaoh
PRO
1
170
AIエージェント元年@日本生成AIユーザ会
shukob
1
280
MLflowはどのようにLLMOpsの課題を解決するのか
taka_aki
0
160
開発者体験を定量的に把握する手法と活用事例
ham0215
0
150
JAWS FESTA 2024「バスロケ」GPS×サーバーレスの開発と運用の舞台裏/jawsfesta2024-bus-gps-serverless
ma2shita
3
420
Ruby on Railsで持続可能な開発を行うために取り組んでいること
am1157154
3
190
20250304_赤煉瓦倉庫_DeepSeek_Deep_Dive
hiouchiy
2
150
アウトカムを最大化させるプロダクトエンジニアの動き
hacomono
PRO
0
110
QAエンジニアが スクラムマスターをすると いいなぁと思った話
____rina____
0
220
マーケットプレイス版Oracle WebCenter Content For OCI
oracle4engineer
PRO
3
550
Featured
See All Featured
How GitHub (no longer) Works
holman
314
140k
BBQ
matthewcrist
87
9.5k
A designer walks into a library…
pauljervisheath
205
24k
Fireside Chat
paigeccino
35
3.2k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Embracing the Ebb and Flow
colly
84
4.6k
Documentation Writing (for coders)
carmenintech
69
4.6k
StorybookのUI Testing Handbookを読んだ
zakiyama
28
5.5k
How to Ace a Technical Interview
jacobian
276
23k
Designing on Purpose - Digital PM Summit 2013
jponch
117
7.1k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
33
2.8k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.2k
Transcript
1 品質を担保する InDesignスクリプト 事故を未然に防ぐデータづく りのお手伝い
2 Twitter: @Uske_S 印刷会社にてInDesignでページ物の組版、 および製版業務を行いなが ら、 社内のスクリプト制作窓口業務を兼務。 好きが高じて趣味がスクリ プトになっており、 Twitterやブログでスクリプトを公開したり検証したり
している。 横田さんと共に 「DTPerのスクリプトもくもく会」 を運営。 DTPab DTPerのスクリプトもくもく会
3 目標設定 目標・仕様の確定 コーディ ング・デバッグ チャート図の作成 完成 納期 投入できるリソースの考慮 スクリプト作成のフロー 1
4 スクリプト作成のフロー 2 やってみよう ! すごーい ! たーのしー ! つかう おく
らいり
5 このセッションの目標 品質を担保するスクリプトとは 事故の潜在的・顕在的な要素を取り除く、 そのための確認作業を手助けするスクリプト 作業環境に合わせて、 サンプルスクリプトを カスタマイズできるようになる
6 メニュー ▪startup scriptについて理解する ▫イベン トについて ▫バージョンチェック ▫ログファイルの書き出し ▫PDFを書き出し前のチェックリス ト
7 startup script について 1 Scriptsフ ォルダの中にstartup scriptsフォルダを作成。 この中に置かれたスクリプトは、 InDesignが起動する度に 自動的に読み込まれて実行される。
8 任意のフ ォルダへのエイリアスを入れておく とGood。 startup scriptsはInDesignが起動した際に読み込まれるので、 スクリプトを修正したり中身を出し入れした場合は InDesignを再起動する必要がある。 startup script
について 2
9 下のスクリプトをstartup scriptsフ ォルダに入れてInDesignを起動する と、 それと同時に実行される。 起動と自動で実行できる=実行し忘れの防止 helloWorld.jsx 1 alert("Hello
World!"); startup script について 3
10 メニュー ▫startup scriptについて理解する ▪イベントについて ▫バージョンチェック ▫ログファイルの書き出し ▫PDF書き出し前のチェックリスト
11 イベントについて イベントに割り当てるスクリプトは自動的に (目的のイベントが発生し たときに) 実行される点が異なります。 =スクリプトパネルからダブルクリ ックしなく てよい イベントにスクリプトを割り当てるには、
eventListenerというスクリプ トオブジェクトを使用します。 =eventListenerに登録すれば、 イベントの度に呼び出されるスクリプ トになる 〔Adobe InDesign CS6 スクリプティ ングガイド p.126より引用〕
12 #targetengine スクリプトを動作させるレイヤーのようなもの (必須) 。 何も指定しない場合は 「main」 になるが、 eventListenerは 「main」
で は動作しない。 addEventListener ( [イベントタイプ] , [関数or File] ) eventListenerを仕込むメソ ッ ド (必須) 。 どんなイベン トで発動させたいか、 発動した場合はどんな処理を行うか を記述する。 イベントについて
13 メニュー ▫startup scriptについて理解する ▫イベン トについて ▪バージョンチェック ▫ログファイルの書き出し ▫PDF書き出し前のチェックリスト
14 思わず違うバージョンで開いてしまった… いく らGleeを使っていても、 アプリケーションを指定して ドキュメン トを開いた場合はそれまで。 そもそもWindowsの場合……
15 というわけで 誤って違うバージョンで ドキュメン トを開いてしま っても このスクリプトで気付こう !
16 デモンストレーション ドキュメン トを保存したInDesignのバージョンと 現在開いているInDesignのバージョンを表示する
17 afterOpen_versionCheck1.jsx 1 #targetengine "versionChecker" 2 app.addEventListener("afterOpen", function (ev){ 3
if (parseInt(app.version, 10) >= 7 && 4 ev.target.constructor.name === "Document") return; 5 var curDoc = ev.target.parent; 6 var createdVer = curDoc.metadataPreferences.creator; 7 alert("保存バージョン:"+createdVer+"\rアプリバージョン:"+app. version); 8 }); 基本形はこんな感じ。 これだとち ょ っと使いづらい。 保存バージョンのチェック
18 デモンストレーション 開いたドキュメン トの保存バージョンと InDesignのバージョンが違う場合だけ警告を出す
19 afterOpen_versionCheck2.jsx 保存バージョンのチェック ver2 targetengineの指定。 addEventListenerメソ ッ ドに、 イベン トと関数を指定する。 関数には自動的に発動したイベントが入るので、
受け取りたい場合は 任意の文字列を指定する (今回は 「event」 とした) 。
20 afterOpen_versionCheck2.jsx 保存バージョンのチェック ver2 afterOpenイベントのCS5以降での処理。 何もしないと関数が2回実行されてしまうので、 それを回避する。 parseInt (文字列, 基数) …文字列を基数に合わせて数値型に変換。
event.target.constructor.name…eventで渡されたオブジェクトが何 者かを調べる。 この条件式がtrueになればreturnとなり、 関数が終了する。
21 afterOpen_versionCheck2.jsx 保存バージョンのチェック ver2 eventオブジェク トから、 Documentオブジェク トを捕まえる。 ※上の行でDocumentの場合は除外しているため。 なぜ除外するのかについては (時間があれば)
後述。 event.target.constructor.name === "Document"が真にならない場 合はLayoutWindowであり、 そのparent (親) がDocumentとなる。
22 afterOpen_versionCheck2.jsx 保存バージョンのチェック ver2 ドキュメン トのメタデータからcreatorプロパティを参照して、 以下の正規表現でバージョン表記部分を抽出する。 /((CC( [0-9\.]+)*)|(CS)?[0-9\.]{1,3})/ 今後のバージョン表記次第では書き換える必要がある。 ※InDesignCS以前のデータではメタデータが参照できないため、
if (!creator){ … } はそのための例外処理。 CC〜CC 2018まで対応 CS〜CS6に対応
23 afterOpen_versionCheck2.jsx … 保存バージョンのチェック ver2 switch文でメタデータから取得した文字列を分岐し、 配列に代入。 case "メタデータから抽出した文字列 " :
myVerLib = ["表示させたいバージョン表記 ", バージョンの値 ]; break; 今後のバージョンに合わせて上記書式でdefault文の前に書き足す。
24 afterOpen_versionCheck2.jsx 保存バージョンのチェック ver2 以下の条件分岐を条件 (三項) 演算子で1行に記述している。 if (parseFloat(app.version) === 7.5)
var appVer = 7.5; else var appVer = parseInt(app.version, 10); ※このような半端なバージョンが登場したら追加する必要があるかも? parseFloat (文字列) …文字列を数値型 (浮動小数点) に変換する。 parseIntと違って、 基数は指定する必要はない。
25 afterOpen_versionCheck2.jsx ドキュメントの保存バージョンとアプリケーションが一致しない場合に 警告を表示する。 また、 2つめのif文 if (myVerLib[1] !== 0)
で、 表示する文字列を変えている (先のswitch文でどのケースにも当て はまらなかった場合) 。 保存バージョンのチェック ver2
26 メニュー ▫startup scriptについて理解する ▫イベン トについて ▫バージョンチェック ▪ログファイルの書き出し ▫PDF書き出し前のチェックリスト
27 今月何ページ組んだっけ… 原価管理・労務管理に 判型やページ数を記録しておきたいけど 手作業だと面倒で…
28 トラブル発生 ! でも発生場所が曖昧… どういう経緯でトラブルが起きたか、 作業元を確認する術がない…
29 というわけで InDesignで作業ログを書き出し、 原価管理や労務管理、 トラブル対応に役立てよう !
30 デモンストレーション ドキュメン トの保存と同時に ログファイルを書き出す
31 exportLogFile.jsx 先程のスクリプトは第二引数に直接関数を記述したが、 今回は別々の イベン トで同じ関数を呼び出したいので、 関数名を指定して呼び出す。 ログファイル書き出し
32 exportLogFile.jsx main関数の内部 ログとして書き出したい内容を、 頭から順にpushしていく。 event.eventType…どのイベン トで呼ばれたか event.timeStamp…タイムスタンプ $.os…OSとそのバージョン app.version…頻出のアプリケーション
(InDesign) のバージョン decodeURI (myDoc.fullName) …ドキュメン トのパス ログファイル書き出し
33 exportLogFile.jsx main関数の内部 afterSaveイベン トが呼ばれたときのオプション。 myDoc.pages.length…ドキュメン トのページ総数 docPref.pageSize…ドキュメン トの判型 myRound(docPref.pageWidth)…ページ幅
(小数第2位で四捨五入) myRound(docPref.pageHeight)…ページ高さ (同上) ログファイル書き出し
34 exportLogFile.jsx main関数の内部 afterExportイベン トが呼ばれたときのオプション。 event.format…書き出しフ ォーマッ ト decodeURI (event.fullName)
…書き出し先のフルパス もしイベン トを増やしてオプションを追加したい場合は、 else if (event.eventType === " [イベント] "){ … } とする。 ログファイル書き出し
35 exportLogFile.jsx main関数の内部 末尾にあるexportLog関数を呼んでいる。 引数は順に [ログのフルパス] , [ログに書き出す内容] , [区切り文字]
作業者単位でログを書き分けたい場合は、 exportLog ("~/desktop/saegusa.txt", myLogText, "\t"); などとすると、 作業者別にログを分けることが可能。 ログファイル書き出し
36 exportLogFile.jsx myRound関数 小数第2位で四捨五入する関数。 Math.round (値) …値を四捨五入して、 最も近似の整数を返す Math.roundメソ ッ
ドは整数しか返さないので、 2桁スライド (*100) して 四捨五入し、 改めて桁数を戻している。 value = Math.round (value*100) 100 ログファイル書き出し
37 exportLogFile.jsx exportLog関数 new File ( [ファイルパス] ) …新し く
ファイルオブジェク トを作成 File.open ( [モード] ) …r、 w、 e、 aの4種類から指定 r:read (読み込みのみ) 、 w:write (新規書き込み) 、 e:edit (読み書き) a:append (読み書き、 ファイルの最後にカレン トポジションが移る) 今回はファイルの最後に書き加えたいのでappendとした。 ログファイル書き出し
38 メニュー ▫startup scriptについて理解する ▫イベン トについて ▫バージョンチェック ▫ログファイルの書き出し ▪PDF書き出し前のチェックリスト
39 チェックリストはあるけど… 時々忘れて後でまとめてチェックすることがある、 とはさすがに言えない…。 そもそもチェックすることが目的になって、 本来の確認作業が疎かになっていないか?
40 というわけで PDFを書き出す前に チェックリストを表示して、 すべての項目をしっかり忘れずにチェックしよう !
41 デモンストレーション PDF書き出し前に チェックリストを表示する
42 このスクリプトの利点 1. 仕事ごとにリストを使い分けられる 2. リス トの修正が容易 (InDesignの再起動が不要) 書き出し前チェックリスト ち
ょ っぴりデモンストレーション
43 注意点 InDesign CS4以降でしか機能しない。 ファイルメニューの 「書き出し」 コマンドを監視しているため、 PDF書き 出しプリセッ トからプリセッ
トを直接選んで書き出す場合には対応でき ない。 カスタマイズ スクリプト自体はほとんどカスタマイズする余地なし。 リス トとして読み込むtxtファイルの名前は任意に変更可能。 ////////ファイル名 var listFile = "checklist.txt"; //←ここを変更 書き出し前チェックリスト
44 myCheckList.jsx 25 ev.preventDefault(); //イベントを強制中断させるメソッド 26 27 //リストの読み込み 28 var
listAry = []; 29 var myList = tgtListFile.open('r'); 30 while (!tgtListFile.eof) listAry.push(tgtListFile.readln()); 31 tgtListFile.close(); リス トファイルを開き、 listAryに1行ずつ配列として追加していく。 File.eofは、 ファイルを読み込んでいるカレントポジションがファイルの 末尾に来るとtrueを返す。 File.readln()メソ ッ ドは、 ファイルを1行ずつ読み出す。 書き出し前チェックリスト
45 myCheckList.jsx 40 for (var i=0; i<listAry.length; i++) myDlgItems.push (add('checkbox',undefined,listAry[i]));
41 myDlgItems.push (add ('button', undefined, "書き出し")); … 44 myDlgItems[myDlgItems.length-1].onClick = function (){ … } myDlgItemsには、 ダイアログの子要素を格納している。 一番最後にボタンを追加しているので、 myDlgItems.length-1がそのボ タン。 これのonClickプロパティに関数を与えてボタン動作を実装。 書き出し前チェックリスト
46 myCheckList.jsx 45 var checkFlag = 0; 46 for (var
i=0; i<myDlgItems.length-1; i++) checkFlag += (0+myDlgItems[i].value); 47 if (checkFlag === (myDlgItems.length-1)){ … } リス トが全てチェックされたかどうかを判別する。 真偽値を数式に入れると (0+myDlgItems[i].value) 、 trueであれば1、 falseであれば0を返すことを利用している。 最後の条件文では、 myDlgItems.length-1 (この1はボタンの分) と、 リ ストのtrueの合計値を比較している。 書き出し前チェックリスト
47 myCheckList.jsx 49 app.menuActions.itemByName ("$ID/Export...").eventListeners. itemByName("myCheckList").remove(); 50 app.menuActions.itemByName ("$ID/Export...").invoke(); 51
var myEv = app.menuActions.itemByName ("$ID/Export..."). addEventListener ("beforeInvoke", myCheckList); 52 myEv.name = "myCheckList"; myCheckListという名前のイベントリスナーを一旦消し (remove) 、 改 めて書き出しコマンドを実行する (invoke) 。 その上でもう一度イベン トリスナーを登録し直す。 消して登録し直すという一見回り くどい方法を採っているが、 そうしない とinvokeした時点で改めてチェックリストが呼ばれてしまう。 書き出し前チェックリスト
48 おまけ
49 おまけ afterOpenイベン トをそのまま使うと、 イベン トリスナーが2回呼ばれることになる。 その仕組みと対処法。
50 yourName.jsx 1 #targetengine "yourName" 2 app.addEventListener ("afterOpen", function (ev){
3 alert("瀧くん…"); 4 }); afterOpenイベン トをそのまま利用するだけだと2回実行される。 イベントリスナー afterOpen ち ょ っぴりデモンストレーション
51 なぜ 2 回呼ばれたのか? 「ドキュメン トを開く」 ことと 「ウィ ンドウとして開かれる」 ことを別々に認
識するため (InDesign CS5からの仕様) 。
52 yourNameAtOnce.jsx 1 #targetengine "yourName" 2 app.addEventListener ("afterOpen", function (ev){
3 if (parseInt(app.version, 10) >= 7 && 4 ev.target.constructor.name === "Document") return; 5 alert("瀧くん…"); 6 }); parseInt(app.version, 10) >= 7 …InDesignのバージョンがCS5以上の場合 ev.target.constructor.name === "Document" …開かれた対象がDocumentの場合 (ちなみに、 2回目はLayoutWindowで呼ばれている) 1 度だけ実行する afterOpen イベント
53 ▫startup scriptで、 実行忘れをなく そう ▫ イベン トリスナーを使うと、 アイディア次第で様々な制御が可能に ▫
環境に合わせたカスタマイズで 手間を省いて品質を上げよう まとめ