DTPab

DTPにまつわるあれこれ

スクリプトを開発・運用する際に気をつけていること

はじめに

InDesignJavaScript教室(IDJS教室)が終わり、参加者の方々は四苦八苦しながらスクリプト開発を始めたり、先生の用意した問題集に取り掛かっていることと思います。
改めて、スクリプト開発時の注意点をまとめてみました。開発工程での注意点だけではなく、できあがったスクリプトの運用において僕が注意しているところも併記しました。
開発したスクリプトには、性格というか、どういう処理を行うかという大まかな方向性があるはずです(文字を検索置換するもの、オブジェクトの属性を調べるもの、といったものです)。このようなスクリプトの「性格」にもよるので、以下に挙げるものすべてを気にかける必要はありません。目安と思っていただければ。

環境的な前提

まず前提として、僕の開発環境についてざっと書いておきます。これはいわゆるマシンスペックとかOSとかではなく、業務で開発するスクリプトをどのような環境で開発しているかという、どちらかというと社内環境みたいなものです。

OSによらないスクリプト

職場にはWindowsユーザーとMacユーザーがおり、僕は基本的にどちらかのOSでしか動かないというものは作りません。

バージョンに限定されないスクリプト

入稿データを受ける印刷会社という性格上、InDesignIllustratorはかなり広範なバージョンを扱います。全部のスクリプトがそうではないですが、特にインフラ系のスクリプトはほぼすべてのバージョン(CS3以降)で動作することが求められます。
そうではない、ちょっとした作業を自動化するようなものについてはだいたいCS6かCC2017等で動作確認しています。

ユーザーフレンドリー

僕がスクリプト開発の担当に据わるまでは、割と「スクリプトの中身を少し調整して、ユーザーが自分用にカスタマイズして使う」ことを前提としたスクリプトが多かったです。
僕はこれに異を唱えて、もっとユーザーフレンドリーなスクリプトにしようと呼びかけています。というのも、スクリプトがなんだかよく分からいというひとはそもそも「ちょっと書き換える」ことにハードルが高く感じてしまうことがあります。また、誰かがちょっと改変したスクリプトが別の誰かに渡り、そのスクリプトが改変されてまた誰かに渡り…、最終的には大元のスクリプトではなく誰かに改変されたそうしたスクリプトが大きな顔をして存在していることがあります。スクリプトに手を加えた場合は当然名前を変えるべきなのですが、それはユーザーに委ねられており、結果として「同じ名前だけど変更日時が違う、だけど何が変わったか一見しただけではわからない」というスクリプトが数多く爆誕するのです。
そのため、最近は「改変することを前提としたスクリプト」の開発を控えてもらうよう、社内の開発陣に呼びかけています。
そのためにScriptUIを実装しやすくするライブラリ*1を用意したり、外部ファイル(jsonファイルなど)と連携しやすくなるライブラリを用意したりしています。
僕自身はScriptUIでそこそこ遊んでいるし、JSONも普通に読み書きするライブラリを入れているので全然困ってないのですがw

スクリプト開発・運用の際に気をつけていること

だいたい以上のような環境で僕はスクリプトを開発しています(もちろん個人で趣味で作っているものは自由気ままですがw)。ではこうした前提に立って、以下に僕が実務で使うスクリプトの開発・運用の際に気をつけていることを順不同で挙げてみます。

【開発面】

  • 誰が開発した責任を負うのか明確にする
  • 最小限の労力で最大の効果を目指す
  • 動作条件を細かく想定する
  • スクリプトでしか再現・実現できないアプリケーションの穴を利用しない
  • 例外処理は必要最小限に抑える
  • 規模の大小にかかわらず、必ずデバッグを工程に含める
  • スクリプトが処理の途中で終わってしまうことも想定する

【運用面】

  • スクリプトはあくまでアプリケーションを操作している
  • 不具合の原因がバグなのか仕様なのかを明確にする
  • 起きた不具合をそのままにしない

簡単にそれぞれを説明します。

誰が開発した責任を負うのか明確にする

これはもうそのままです。
誰が開発したかを明確することで、何かあったときに対応しやすくなります。

最小限の労力で最大の効果を目指す

行おうとしている処理を、一つのスクリプトですべて対応しようとすると多大な労力が必要になることがあります。労力=開発コストです。
100の開発コストをかけて100点の結果を実現するよりも、50の開発コストで80点の結果を実現できたほうが効率がいい、ということです。こういうケースは少なからずあります。特に自動組版のような規模の大きなものであれば、100%をスクリプトで処理するより、どこかを人の手に委ねたほうが安全で効率がいい場合があるのです。

動作条件を細かく想定する

動作するアプリケーション、そしてそのバージョンだけでなく、ドキュメントを開いているか、選択しているオブジェクトの有無、選択しているオブジェクトの種類、特定の要素のオブジェクトがドキュメントにあるか…などなど、スクリプトが実行される条件をできるだけ絞り、それらがすべて満たされていないと動作しないという動作条件を必ず用意します。
動作条件がある程度特定できると、単純にスクリプトで条件分岐する手間が省けます。また、想定外の処理を考えなくて良くなります。不具合の出にくいスクリプトになりますし、そうやって動作条件をしっかり設定すると、スクリプトが途中で止まっても、想定していたエラー処理が表示されているのかそうでないのかで、もともと想定内の動作条件外だったのか、未想定の事態なのかの線引にもなります。
ネットで無料配布するようなものでは、そこまで明確に動作条件を書き込まない場合もあります。

スクリプトでしか再現・実現できないアプリケーションの穴を利用しない

例えば、空白文字にルビを振ることがスクリプトでは実現できます。このような、いわゆる「アプリケーションの穴」を利用しないほうがいいです。なぜなら、そのスクリプトがないと作業できない環境がそこでできあがってしまうからです。
よほどの事情がない限り、InDesignのUI上で実現できないようなこと(実際にはあんまりありませんが)はスクリプトでやるべきではありません。

例外処理は必要最小限に抑える

自動で処理を実行した後、スクリプトが「やりすぎてしまった」ことをユーザーが手直しするようなスクリプトは作るべきではありません。 例えばテキストの中のカンマを読点に変換するスクリプトを書いたとします。スクリプトを実行したら「1,500円」という文字列が「1、500円」となってしまった、というようなケースです。これを「あとで手で直せばいいや」ということを許容してしまうようなスクリプトは僕は許しませんw
この例は単純ですからなんとでもなりそうですが、そういったスクリプトで達成しようとした目的に対する例外処理は、本当に必要なものだけ対応し、あとはスクリプトでは処理しない、というほうが無難です。
先述の開発コストとも絡むのですが、やりすぎるスクリプトは作るべきではない、ということです。

規模の大小にかかわらず、必ずデバッグを工程に含める

これはもう当たり前のことですが、必ずデバッグします。特に誰かに使ってもらう、自分の環境とは違うマシン環境で動作する可能性がある場合は、スクリプトを多角的に検証する必要があります。必要に応じて複数名でデバッグしたり、OS別に自分で試したりします。基本的に「作ったから自由に使ってくださいね」というふうに配ったものは、完璧ではないにしろ想定しうるエラーをすべて潰してあるべきです。
そうは言っても、運用中に見つかる不具合も当然あります^^;;
それとネットで無料で配布するようなスクリプトだと、細かくデバッグしない場合も多いです(最低限はしますよ??)。

スクリプトが処理の途中で終わってしまうことも想定する

特にイベントスクリプトなど、ユーザーの意思にかかわらず実行するスクリプトであれば強く意識したいところです。
動作したスクリプトが何らかの理由で警告もなく中断される場合があります。そういうときに、ドキュメント上に印刷されては困るオブジェクトが描画されたままになっていたり、ドキュメントの設定が本来とは違う設定に変更された状態になっていたりすると、ユーザーは何も気づかずそのデータで作業を続けることになりかねません。マジで事故ります
そのために、途中でスクリプトが中断してしまっても大丈夫かどうかスクリプトのフローを検討したり、開発時のメモやスクリプトコメントアウトなどで「どういう処理を行っているか」を記述しておくことも検討します。

スクリプトはあくまでアプリケーションを操作している

ここからはエラーなく動作するスクリプトができたとして、それを運用する段階で気をつけていることです。
まず、スクリプトInDesignやIllustartorなど、アプリケーションを操作しているということを忘れないでください(ESTKでFileオブジェクトのみを扱うスクリプトなどは別です)。言い方を変えると、動作しているアプリケーションの機能を利用しているということです。
例えば、InDesignで検索置換を利用して段落スタイルを変更する処理を考えます。

f:id:uske_S:20180705215324p:plain

この画像では、「あいうえお」という文字列に段落スタイル「hoge」があたっています。う、え、おの3文字はオーバーライドで色を変更しています。これを検索置換を利用して段落スタイル「fuga」をあてる処理をスクリプトで書いたとしましょう。結果はどうなるでしょうか。

f:id:uske_S:20180705215340p:plain

オーバーライドで色を変えていた部分の設定が解除されました。これは検索置換パネルを利用して段落スタイルを置換しているためです。要するに、検索置換パネルで検索置換した結果がこうなるので、スクリプトでそれを利用しても当然そうなるということです。
仮に「実はオーバーライドは維持したかった」ケースだと、これでは困るわけです*2
このように、スクリプトでは動作するアプリケーションの機能を利用するため、その仕様に沿うということです。そのためアプリケーションの細かい動きまでしっかり理解しておかないと、想定外の事態に陥ることがあります。

不具合の原因がバグなのか仕様なのかを明確にする

これは先程の内容とも重なるのですが、スクリプトが想定外のエラーを起こしたとき、それがアプリケーションのバグによるものなのか、仕様なのかは必ず明確にする必要があります。それによってその後の対応が変わるためです。
スクリプトを実行したらアプリケーションのバグで想定外のエラーが起きたというとき、そのフローではスクリプトが作れない可能性があります。そうなると、当初目標としていた達成目標を変更したり、違うフローで実行したりという、当初の仕様を大きく変更する事態になります。
一方、もともとそういう動作をする機能だということがわかっていれば、最初からその機能を避けて実装したり、むしろそれを利用したりすることもできます。
先の例で言えば、オーバーライドを解除して段落スタイルを変更したいなら検索置換を利用すればいいですし、そうでなければ検索置換ではなく、単純に段落スタイルを変更する処理を利用すればいいのです。

起きた不具合をそのままにしない

これは当然と思うかもしれません。しかし言い方を変えて「偶然の成功をそのままにしない」と考えてもらってもいいです。
スクリプトはあくまで理論的に計算した結果を遅滞なく間違いなく実行する処理機構です。なので「理由はわからないけど、プロパティをこう変更するとうまくいく」というような処理のブラックボックスを作ってはいけません。
ただ、「こうするとうまくいかないから一旦この処理を挟む」みたいな、スクリプト実行上の不具合(というかバグ)もゼロではありません。そのためのバッドノウハウも少なからず存在します。
しかし、目指すべきは理詰めの処理です。
そのためにアプリケーションの各機能がどういう振る舞いをするのか、それをスクリプトで実行して同じ結果になるのか、そういったことを正確に把握していく必要があります。特に新しい機能を利用する場合は要注意です。

まとめ

結局のところ、スクリプトを作るということはアプリケーションの各機能に精通する必要があるし、新しいバージョンのアプリケーションが出る限り、そこに際限はないです。
見方を変えると、アプリケーションがひと通り使えないと、スクリプト開発には相当のリスクと労力がかかります。アプリケーションの動作がひと通り理解できていれば、仮にスクリプトが意図しない不具合で止まったとしても迅速に対応できます。
スクリプトの開発にはかなりの労力を必要としますが、普段使用しているアプリケーションの細かい挙動にもぜひ目を光らせてほしいです。

ということで、今回はスクリプト開発・運用の際に自分が気をつけていることを自戒も込めて書いてみました。
これからスクリプトを開発していく方々の一助になれば幸いです。
それでは、良いスクリプトライフを!^^/

*1:実際には関数をひとつだけ記述したjsxinc形式の別のスクリプトです。このような単機能のスクリプトを#includeしていつでも呼び出せるように環境を整えています。

*2:ちなみに、オーバーライドを維持したまま段落スタイルを変えたい場合は、段落スタイルパネルで「別の段落スタイルを設定する」という方法で処理するとオーバーライドは維持できます。