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
330
品質を担保するInDesignスクリプト
2017年10月に東京のDTP勉強会で登壇した際のセッションスライド。
Yusuke S.
October 21, 2017
Tweet
Share
More Decks by Yusuke S.
See All by Yusuke S.
InDesignのスクリプトを使い倒そう!
uskes
0
1k
[page2020] スクリプトで未然に防ぐInDesignの不具合と作業ミス
uskes
1
2.1k
GAS for DTPer -- はじめの一歩
uskes
1
470
Other Decks in Technology
See All in Technology
成長し続けるアプリのためのテストと設計の関係、そして意思決定の記録。
sansantech
PRO
0
130
Delegating the chores of authenticating users to Keycloak
ahus1
0
160
Yahoo!しごとカタログ 新しい境地を創るエンジニア募集!
lycorptech_jp
PRO
0
130
SEQUENCE object comparison - db tech showcase 2025 LT2
nori_shinoda
0
150
ビズリーチが挑む メトリクスを活用した技術的負債の解消 / dev-productivity-con2025
visional_engineering_and_design
3
7.9k
IPA&AWSダブル全冠が明かす、人生を変えた勉強法のすべて
iwamot
PRO
2
180
AI専用のリンターを作る #yumemi_patch
bengo4com
6
4.3k
関数型プログラミングで 「脳がバグる」を乗り越える
manabeai
2
200
【Oracle Cloud ウェビナー】インフラのプロフェッショナル集団KELが考えるOCIでのソリューション実現
oracle4engineer
PRO
1
100
united airlines ™®️ USA Contact Numbers: Complete 2025 Support Guide
flyunitedhelp
1
420
改めてAWS WAFを振り返る~業務で使うためのポイント~
masakiokuda
2
270
整頓のジレンマとの戦い〜Tidy First?で振り返る事業とキャリアの歩み〜/Fighting the tidiness dilemma〜Business and Career Milestones Reflected on in Tidy First?〜
bitkey
3
17k
Featured
See All Featured
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.7k
A Modern Web Designer's Workflow
chriscoyier
695
190k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Faster Mobile Websites
deanohume
307
31k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
130
19k
How STYLIGHT went responsive
nonsquared
100
5.6k
Fireside Chat
paigeccino
37
3.5k
GraphQLとの向き合い方2022年版
quramy
49
14k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
6
310
Six Lessons from altMBA
skipperchong
28
3.9k
The World Runs on Bad Software
bkeepers
PRO
69
11k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.4k
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で、 実行忘れをなく そう ▫ イベン トリスナーを使うと、 アイディア次第で様々な制御が可能に ▫
環境に合わせたカスタマイズで 手間を省いて品質を上げよう まとめ