2010年12月10日

テンプレートファイルのプレイスホルダに文字列を埋め込んでは保存する、というスクリプト

とある業務に関連して、画像領域の文字列だけが違うというダミーデータを数十点作る必要があった。手で作るのは耐え難いので、Illustrator用のスクリプトを作ってみた。

ということで出来たのが、InDesign Hacking with JavaScriptの「Illustrator用スクリプト」の「dialogCloning.jsx」。

テンプレートファイルとなるファイル(これは.epsでも.aiでもよい)には、文字列を置き換えたい場所(プレイスホルダ)にたとえば「LABEL01」のように入れておく。ほかにもあるなら「LABEL02」、「LABEL03」、…のように作っていけばいい。

プレイスホルダに何を入れるかの情報は、ここではマップファイルと呼んでいるファイルに記述する。内容はこんな感じ。文字エンコーディングはUTF-8を使い、列の区切りはタブ1文字を使う。

FILE	LABEL01	LABEL02
fig1.eps	図1のダミー	白地に青
fig2.eps	図2のダミー	青地に白
fig3.ai	図3のダミー	紅白

最初の行は以降の行のためのプレイスホルダ設定を行うもので、その列の値の代入先のプレイスホルダを指定する。ここではLABEL01には2列目の値が、LABEL03には3列目の値が入ることになる。1列目のFILEは単に無視されるものなので何でもよいのだけど、わかりやすくするためにこういう名前にしておいた。

2行目以降で、「保存ファイル名」「LABEL01を置き換える文字列」「LABEL02を置き換える文字列」を列挙していく。ファイル名には.epsか.aiを利用でき、スクリプトのほうではこれを見て保存方法を変えるようになっている。

プレイスホルダが1個しかないなら単に3列目を消せばよいし、もっとあるなら列を増やせばよい。行頭に#記号を入れると、その行はコメントとして無視される。

保存先のフォルダを用意したら、Illustrator上でテンプレート用ファイルを開いた状態で、スクリプトを呼び出す。ファイルの保存先、マップファイルの指定を行ったら、あとはプレイスホルダ部の置き換えと保存が次々と繰り返され、出来上がり。30個でも40個でも全部お任せできる(マップファイルも自分は半自動で作っていた)。

仕組みとしては、テンプレートファイルの全ストーリーを検索しては文字列置換、別名で保存を終えたらまたテンプレートファイル(ファイル名は最初に記憶するようにしている)を開いて……というだけの単純なもの。IllustratorSaveOptionsとEPSSaveOptionsの情報がCS3だとヘルプウィンドウに出てこないね。

2009年03月27日

XML要素から独立テキストフレーム/インラインテキストフレームを作る、続く/続きアイコンを付ける

InDesign+XMLによる自動組版で作られた書籍も実績を重ねて10冊以上となりました。それぞれは構成もスタイルもまちまちですが、処理系のライブラリ化、抽象化を進めることで1冊ごとの対応の時間、作業時間は着実に短縮できてきています。

ただ、大半のお客様にとっては、その組版がXML処理で自動生成されたものであるのかあるいは手で1つずつ積み上げたものであるのかといったことはどうでもよいことであり、成果物である紙(あるいはPDF)の見栄えが直接の評価対象です。修正要望の中には自動組版で処理するには辛いものも多いのですが、手作業修正を経験し、その流れを自動化することを試み実装する、という繰り返しによって自動組版の機能を向上できたのもまた事実です(とはいえ終盤でちゃぶ台返しは本当に辛いので勘弁してください…)。

ということで、最近実装したものを2つご紹介。ソースコードはInDesign Hacking with JavaScriptにあります。CS3用です。CS4は環境がないので不明です。

1つはコラムなどの処理のためのスクリプトライブラリlibProcessXMLmakeBlock.jsxです。指定のXML要素から独立またはインラインのテキストフレームを作ります。前にもこの実装はしたのですが、当時のものはバギーで不具合も多いものでした。今回のものも完全ではありませんが(たとえばフレームに移動された側のXMLドキュメントの該当箇所に、空行1行が残ってしまう)、今後わりと応用が効きそうです。呼び出しはこんな感じ。

#include "libProcessXMLmakeBlock.jsx"
var obj = new Object; // パラメータ格納用のオブジェクト
  // 適用するオブジェクトスタイル。getObjectStyleByNameはlibCommon.jsxライブラリのもの
obj.objectStyle = getObjectStyleByName(app.activeDocument, "コラム");
  // フレームの幅。0なら自動
obj.width = 0;
  // インラインフレーム化するか。インラインはまだバギーかも
obj.inline = false;
  // ドキュメントオブジェクト、XPath、パラメータオブジェクトを指定して実行
MakeBlock(app.activeDocument, "//column", obj);

過去のライブラリAPIではパラメータを引数にずらずら並べていたのですが、リファクタリングなども面倒なので、Objectクラスをハッシュ風に使うようにしています。今後のスクリプトでは基本的にこのスタイルで進めていきます。XMLを探すのもCS3から使用できるglue codeを使うようにしてみました。でもなんかglue codeかネイティブのXPath探索にバグがあるような気がします。glue code版のXML呼び出しは確かに速度的には悪くないのですが、コールバックのコードのデバッグが困難で、XPathの問題も解明できていません(CS4だと直ってるとかなバグかも)。InDesign CS3の機能制限を避けるべく必死なコードも一部あります。

もう1つは表やコードリストなどがページをまたぐときに「続く」などのアイコンを入れられるようにするlibProcessXMLforContinuous.jsx。まだ開発途上ですが、このスクリプトで手作業の量はだいぶ軽減できています。手だと忘れやすいところですしね。

#include "libProcessXMLforContinuous.jsx"
var obj = new Object; // パラメータ格納用のオブジェクト
  // 配置するレイヤー。nullの場合には現在選択中のレイヤー。存在しない場合は作成される
obj.layername = "続く/続き";
  // 前側ページに配置するファイルオブジェクト。nullの場合は配置しない。placeできるオブジェクトならなんでもよい?
obj.nextostyle = File("tuduku.eps");
obj.nextostyle = getObjectStyleByName(app.activeDocument, "続く"); // 画像オブジェクトスタイル
obj.nextoffset = [0, 0, 0, 0]; // 基本配置位置(現時点では版面右下)からのオフセット
  // 後側ページに配置するファイルオブジェクト
obj.tofile = File("tuduki.eps");
obj.toostyle = getObjectStyleByName(app.activeDocument, "続き");
obj.tooffset = [0, 0, 0, 0]; // 現時点では基本配置位置は版面左上
 // 右ページで分かれる場合にのみ配置するか(現時点では左閉じのみ想定)
obj.spread = false;

// ドキュメントオブジェクト、XPath、パラメータを指定して実行
processXMLforNextToIcon(app.activeDocument, "//codelist", obj);

配置位置が版面基準なのがちょっとナニなんですが、最下段を調べるのは実はけっこう難しい。ページのlinesの最後を見てそのベースラインを…という感じなのですかね。ただそれが表だったりするとまた困難だったりするわけですが。

では、Happy InDesigning!

2009年03月15日

最近の書籍作りのプロセス(2)

前回に引き続き。

先端的な書籍制作にチャレンジし続けている hisashimさん もたびたび言及されているように、ソフトウェア開発のプロセスやツールは、書籍制作にも効果的に応用できます。 中でも、バージョン制御システム(VCS)は欠かせぬツールです(制作にかかわる人たちすべてが広く利用するようになれば、書籍作りはもっと楽に・スピーディーになるのですが)。

VCSは、あるプロジェクトにかかわる電子的なデータのすべてを「リポジトリ」という場所に蓄え、そこになされる追加・変更・削除などをすべて追跡可能にするものです。ソフトウェア開発では主要な対象データはソースコードになるわけですが、書籍制作では原稿(翻訳なら原書原稿と翻訳後原稿の両方)、差し込む画像、アイコン、組版データ、台割、企画書、目次案、方針議事録といったいろいろなものになるでしょう。

VCSを導入することで、作業者全員が常に最新の状態のファイル群を得られ、進捗も明確になり、どのような変更が加えられたのかも明示されます。リポジトリがインターネットに公開されていれば、場所を選ばずアクセスして作業にかかれます。
VCSの概略図
FTPや宅ふぁいる便は不要となり、ファイル名で必死に区別することもなく、ちゃんと執筆や編集が仕事をしているかもバレ(これは一長一短かもしれませんが…)、過去の作業内容を確認したり変更が気にいらなくなったら元に戻してやり直すこともできるわけです。作業環境のマシンが壊れて再インストールや別のマシンで作業という羽目になったとしても(佳境の時期によくあることです)、リポジトリから取得し直すだけで何も失うことなくすぐに作業を再開できます。

VCSといってもCVS、Subversion、Mercurial、git、Darcs、BitKeeper、Bazaar、Visual SourceSafeなどいろいろありますが、フリー・OSを問わない・メジャーという点でいうとSubversionかgitのどちらかとなるでしょう。 Subversion/gitそれぞれ特徴がありますが、個人的経験からいえば書籍制作全体として採用するにはSubversionのほうが以下の観点で勝っているかなと思っています。

  • 比較的単純な構成で直観的な操作なので、知識背景のさまざまな関係者に用語や概念を説明する際にそれほど苦労しない。
  • Windowsにはエクスプローラ統合のクライアント「TortoiseSVN」があり、日本語化されていて、情報も豊富。(ちなみにgitクライアントTortoiseGitというのがあります)
  • たいていのUNIX/Linux系の人は使用に慣れている。
  • MacOS X Leopard以降にはプリインストールされている(管理者権限のない環境でもすぐに使用開始できるし、インストールするための説得も不要)。
  • リポジトリの最新内容を普通のWebブラウザでも参照してファイル取得できる。WebDAVでファイルを追加変更することも可能。
  • コマンドのヘルプが日本語で出る(Leopardのはまだ駄目だったっけ?)。
  • リポジトリが1つなので、最新版の置き場所が明確であり、(単一障害点ともなり得るが)バックアップも容易。

私のかかわる書籍制作では、1人作業にせよグループ作業にせよ作業データをSubversionリポジトリに登録するようにしています。自動組版用のツールも全部Subversionリポジトリ内なので、組版環境を構成したい場合もすぐに展開可能です。リポジトリを格納しているサーバーは、離れた場所も含めて数箇所にデータをバックアップするようにしています。

ソフトウェア開発においては、Subversionのリポジトリ内は主となる開発進捗を管理するトランク(trunk、幹)と、そこから枝分かれして別の追加開発を行う複数のブランチ(branch、枝。開発成果はいずれトランクにマージ(合流)される)に分かれて使われることが多いのですが、書籍制作では枝分かれして実験するような場面はなく(書籍原稿の文字づらを変更して何かが壊れるということはないですし)、ややこしくなるだけなので、通常はトランクのみを使用します。ただ、組版データもある場合には、著者や編集担当者に組版データを渡してもしょうがないので、組版用のブランチを用意しています。よって、リポジトリ内の構成は次のようになります。

https://Subversionサーバ/svn/書籍/trunk (著者・監訳者・編集者・出版社向けのトランク)
https://Subversionサーバ/svn/書籍/branches/indesign (InDesign組版用ブランチ)

著者や編集者らはtrunkを取得して使用、組版環境はindesignブランチを取得して使用するというわけです。覚えておくべきSubversionの機能としては、チェックアウト・更新・追加・削除・コミットの5つで十分でしょう。あとは復帰・競合解決・移動(リネーム)・コピーを理解すればほぼ用は足りると思います。

差分を表示したり過去のバージョンを取得したりするには、Subversionの機能を使うよりも、TracというWikiと課題追跡をセットにしたシステムを使うと便利です。こちらももともとはソフトウェアプロジェクト向けですが、デフォルトでは行単位でしか差分表示してくれない(標準diffコマンド以外のものを使うという手もありますが)Subversionに比べてTracでは差分をわりとがんばって文字単位で出してくれたり、log -v相当のファイル変更をわかりやすく一覧できたりといったSubversion支援機能を提供しており、制作にあたってのメモをWikiに書いたり、出版までに解決しておくべきTODOを課題として登録するといった使い方もできます。InDesignファイルはバイナリなので「差分」は出せませんが、それでも過去の作成バージョンをいちいち別ファイル名で「人が」区別することなく機械的に管理できるだけでも十分役立ちます。

これらSubversionリポジトリとTracに加えて、quickmlという簡易メーリングリスト(作業者間の連絡のほか、Subversionコミットでの変更通知が届きます)をセットにした、(「bookforge」とまでは言えませんが)書籍制作プロジェクト環境のホスティングを勤務先で提供しています。ご興味あればご一報ください(ついでに編集なり組版なりでお仕事をくださるのがベストです :) )。git、Marcurial、Darcsも(がんばれば)対処できると思います。

2009年03月09日

最近の書籍作りのプロセス(1)

いろいろな経緯があって、昨年から編集という業務だけでなくこのblogセクションにもあるようにAdobe InDesignを中心に据えたXML組版業務にも関わるようになっています(幼少からのコンピュータ、大学でUnix/LaTeX/SGML、最初の会社でPerl/SGML/XML/Webプログラミング、今の会社でEmacsマクロ/Ruby、もう10年以上になるDebianとフリーソフトウェアとオープンソースソフトウェアへのかかわり、と蓄積してきた知識が今になって集大成化してきたというのは不思議な感じもありますね)。

LaTeXを知る身からすると、高価にもかかわらず旧来のDTPソフトのおそろしいほどの手作業っぷり、まさに1ページ1ページを絵のように作っているのを見て愕然としていたわけですが、最近はDTPソフトも機能が向上してきてだいぶ作業者に優しく、機械処理にも優しいものになってきたと思います。特にAdobeのDTPソフトInDesignはXML処理やJavaScriptエンジンが塔載されて、ようやく機械組版が私にとっても現実味を帯びてきました。

バッチ組版処理ではLaTeXが最強だと思いますが、LaTeXのマクロや入力は常人には理解不能で標準的な書籍制作プロセスには採用し難いものがあります。原著がTeXでタグを活かさないと死ぬとか、著者なり編集なりが入稿青焼きまで責任を持ってやってくれるとかではない限りはまず敬遠されます。私の務めている(株)トップスタジオは編集プロダクション会社なので、データも組版レイアウト(テンプレート)もお客様のご希望合わせであり、定型フォーマットでのシステムを組むわけにもいきません。とはいえ、これまで同様にちまちまと手で作っているのでは、コストの安いところに根こそぎ持っていかれることはほぼ確実であり、各社バッチ的な組版を検討、あるいは実装を始めているところではないかと思います。

TeXに比べると、InDesignならDTPオペレータも馴染んでおり、新たな機能を使用するための教育コストはずっと低く済みます。導入するシステムの下地にはXMLがあるにしても、そこにかかわる作業者ができるだけそれを意識しないような仕組みにしておけば、既存知識+α程度で作業を進めることができます。

最近私が制作にかかわっている書籍は、納期的に厳しいとかデザインに凝りすぎということがなければ、InDesign+XMLでの機械組版で行うようにしています(『独習Java第4版』『OpenVZ徹底入門』『zsh最強シェル入門』『独習Javaサーバサイド編』『Windows Server 2008オフィシャルマニュアル』『独習Visual Basic 2008』『SQL Server 2008ビギナーズガイド』)。最近の書籍は立ち上げのみを私が担当し、本格的に始動してからの作業はほかの方々が担えるようになっています。

さて、私の構築した機械組版におけるステップは次のようになっています。

  1. 著者または編集者が簡易タグ付け。生のXMLは人間には見るに耐えないフォーマットであり、特にXML内の改行が重要な役割を果たすInDesignにおいてはますますひどい文書となります。そのため、この時点の作業者は扱いやすく読みやすい簡易タグでマークアップしていきます。現在は別記事でいつか紹介する予定のReVIEWという拡張可能なフォーマットを採用しています。見出しやキャプションの連番処理、相互参照といったミスや面倒を生みがちな処理はReVIEWの機能に任せることができます。Emacsと秀丸向けのエディタモードを作りました。
  2. 画像については従来同様にPhotoshopなりIllustratorなりで変換したり作成したりします。画像についてはスクリプトで一括のグレースケール化・適正リサイズ化・DPI変更をするようにしています。Illustrator(eps)向けには「4色になってる」「RGBだった」といった印刷事故を防ぐためにlgrepベースのチェッカースクリプトをかけるようにしています。
  3. 簡易タグ→XML変換。これはバッチです。簡易タグがいかにXMLに変換しやすいかが肝となります。ReVIEWフォーマット→XML変換自体はすでにReVIEWに実装されています。
  4. InDesignのテンプレートをXMLタグに合わせたり、XMLタグを構造に応じてテンプレートのスタイルに合わせたり。これはDTPオペレータとプログラマーの協業です。InDesignのXMLでは段落スタイル、文字スタイル、表スタイル、表セルスタイルを直接割り当てられます。オブジェクトスタイルはあとでJavaScriptでXMLを検査して適用します。現システムの単一障害点ですが、RubyのREXMLを使用したライブラリの充実を進めており、実装しなければならないコードはだいぶ短くなってきました。変換はRubyが動けば、たとえばLinuxに限らずMacOS Xでも動作するので、MacOS X環境であれば制作工程全部を1台で実施することも可能。
  5. テンプレートとXML変換部が完成したら本番のXMLを読み込ませ、スタイルの自動適用をします。これだけでもかなりの作業を軽減できますが、さらにオブジェクトスタイルの設定、脚注処理などもJavaScriptで自動化します。実行はメニュー形式でDTPオペレータが簡単に扱えるようにしています。
  6. ページの調整や長体処理などは通常のDTPオペレーションと同じです。InDesignで全部をバッチ処理でがんばろうとするのは無理というのが私の行き着いた結論でした。こういうお仕事では、あきらめどきの見極めが重要です。注文の多い書籍ではこの作業はそれなりに時間がかかりますが、手組みほどはかからない、かな?
  7. XMLと機械処理にとってガンなのがテキスト中にフレームを挿入して別ドキュメントをさしこむという、コラムなどによく使われるインラインテキストフレームなのですが、機械組版ではこれを極力排除して、代わりに下のレイヤーに枠やアミなどを描画しています。ページがこれ以上動かないと判断した段階でJavaScriptを実行して、XML要素の起点・終点情報からこのレイヤー描画を行うわけです。柱もこの段階でXML情報を基に作ります。実行は先と同様にメニュー形式なので、DTPオペレータが操作します。
  8. これでひととおりDTPは終わりで、Postscript出力→DistillerでPDFを生成します。InDesignの直接PDF出力はタグが含まれているとカーニングがおかしくなるという不具合が少なくともCS2,CS3にはあるので、入稿まですべてこの手順で作成するPDFを使うことになります(よってデータ入稿限定のお仕事にも使えないですね)。
  9. 目次作成はXML情報とInDesignのページ情報の双方からひっぱってXMLを生成させます。InDesignの段落スタイルベースの抜き出しはどうも怪しいことがありますし(順序が変わったりする)、XML生成版なら適当にスタイルを後処理で加えることができるというメリットがあります。
  10. 権利表記や奥付などの機械でやっても大してメリットのないところは手組みで組んでしまいます。
  11. 索引は簡易タグのときに埋め込んでおいたものをInDesignファイルから拾い出すこともできますし、別途テキストで作っておくこともできます。いずれにせよ、作ったテキストをmendexkを応用したCGIプログラムに通して索引XMLを生成します。本文のPDF内のテキストとgrepで照合するような仕組みも用意して、漏れやズレの大まかなチェックにも役立てています。
  12. 台割については簡易なテキストファイルから必要なチェック、Excelファイルへの変換をこなすようなCGIプログラムを作成して利用しています。ただその印刷についてはOpenOfficeもGnumericも必要となるマージン調整が面倒すぎるので、Microsoft Excelで印刷せざるを得ないというのが若干不満ではあります。

ごはんが食べられなくなると困るので全部を公開するわけにはいきませんが、時間のあるときに各手順などについてもう少し詳細を説明していく予定です。

2008年07月11日

幅に合わせて強制改行

InDesignにおいて、欧文で書かれた段落は、テキストフレームの横幅を越えた場合、手近で見つけた単語間スペースを使って勝手に改行します。左寄せにしてもスペースの幅が動的にならないだけで、この挙動は変わりません。この挙動で困るのは、プログラムリストや画面実行例などです。これらでは文字を「単語」扱いすることにはあまり意味がありません。右側がガタガタになって見栄えが悪くなるだけです。

で、今まさに、「横幅がほとんどない2段組書籍で、プログラムコードがイッパイ、折り返し部分には送り記号を付けたい」という素材があるわけです。次期バージョンのCS4では単語を無視しての版面での折り返しができるようになるらしいのですが、ここにはCS3しかないですし、手で適正な位置を探して送り記号を入れて強制改行して……というのはDTPオペレータを発狂させることになりかねません。

幅に入る文字数はわかっているので原稿テキストレベルで改行してしまうことも一応可能ではありますが、原稿テキストのコードをあとで使いたくなったときに「使えない」ものになってしまいますし、非生産的なのでこれも避けたいところです。

ということで、silentBreakLine.jsxというのを作ってみました(ファイル名と中の関数名がマッチしてないや…)。InDesign Hacking with JavaScriptに置いています。CS3のみで確認しています。ファイル内のoffset、postfix、stylesをドキュメントに合わせて適当に修正して実行すると、全ストーリーを探して、特定の段落スタイルの段落が2行以上にわたっている場合には、フレームの幅(正確にはそこからオフセット値を引いた値)で送り記号と強制改行を挿入します(送り記号を空文字列にすれば強制改行のみになります)。本来はダイアログを用意するところかもしれませんが、当面困っているDTPオペレータにとっての利便性を考えて静的指定としました(libCommon.jsxを使うべきところもコピペコードとしています)。バグは多分ありますが、テストした限りではわりとマットーに動いているようです。

また、この機会にsilent*で始まるダイアログなしで実行するスクリプト群を公開してみました。基本的にはlib*なライブラリのコールで構成されています。

[update 2008.7.11] テキストフレームが選択されているときには、そのフレームのストーリーだけを処理するようにしてみました(選択されていないときにはすべてのストーリー)。また、オーバーフローしているときに処理をしようとするとエラーになってしまうので、例外を投げてその時点でそのストーリーの処理を打ち切るようにしました。

2008年05月16日

libExtendTextFrame.jsx

あいかわらず手作業だとうんざりしそうなところを機械化すべく努力中。そのうちこいつらのせいで失職しそうですが(笑)。

InDesign Hacking with JavaScriptにlibExtendTextFrame.jsxというのを追加しました。

main-contentという名前の付いた連続テキストフレームをチェックして、ページの頭が特定の空行スタイルで始まっている空行の場合、その前のページのテキストフレームの下段を下げて収めるようにします。

ただ、行の「高さ」は段落スタイルのポイント値で導けはするものの、その前の行で下段スペースを入れるようになっている場合は対処できないですね…。広げてみてまだ不足ならもうちょっと広げてみる、といった試行錯誤ルーチンも必要かも。ただ強制改頁みたいなときには注意がいりますが。

そのほかの作業としては、CS3でDocumentOffsetが1始まりから0始まりに変わっていたため、柱生成スクリプトを修正しました。こういうキーになるパラメータを変えるってのは勘弁してほしい…。あと、ToolkitのInDesignCS3オンラインヘルプの構造体まわりはなんかいろいろ名前とか違ってる気がします。PDFドキュメントはまだかなぁ。

2008年05月12日

dialogGrayScale.jsx

Photoshop向けのスクリプトも作り始めました。Hacking InDesign with JavaScriptのページから同様にダウンロードできます。

第一弾として、指定のフォルダの中の画像をグレースケール化および指定のmm幅以上のもののリサイズを行ってepsを吐き出すスクリプトを書いてみました。CS3で動作確認しています。 JavaScriptでのダイアログ周りはInDesignとPhotoshopで全然違うんですね…。

そういえばひどいハメだったのですが、InDesignの直接PDF出力をXMLタグ付きドキュメントに対して行うと、タグの境目でフォントを変えるときに文字詰めがぶっ壊れます。これはCS3になっても治っていません。

こちらではわりと前に把握していてDistillerを通さないとダメというのはわかっていたものの、これまで社内ではタグ付きテキストでのデータ入校はなかったために印刷所側で問題が出たことがなく印刷所のほうも経験したことがなかったようで、やり取りでいろいろトラブることになりました。印刷所はPDFで面付けしてるようなので結局PDF入校で回避することに。今後もXML形式のものはDistillerで変換してPDF入校という方針が安全そうです。

2008年05月02日

InDesign CS3対応作業

業務上必要になったこともあり、CS3スタンダード版を購入しました。

InDesignまわりもいろいろ変わってスクリプトも修正が必要になっています。InDesign Hacking with JavaScriptの公開スクリプトライブラリについてはぼちぼちと手を入れています。APIのversionで「2,3」と表記されているものはCS2およびCS3に対応したものです。今後の開発物についてはCS3をメインターゲットにしたものになるかと思います。

以下ざっとインプレッション。

  • 画面まわりがCS2からけっこう変わっていて慣れるまで時間がかかった。
  • XMLの処理が大幅に強化されたようだ。コールバック的なXMLルールを追加してプロセスをぼんと走らせてXpathに従った処理、とかできる。無駄にがんばってた処理をこれで書き直す予定。
  • xmlElement.storyOffsetが数値ではなくinsertionPointになった。ストーリーオフセット数値を取りたいときにはinsertionPoint.indexを使えばよいようだ。
  • search()での置換が廃止された。findTextPreferences/findChangeTextOptionsおよびchangeTextPreferencesを駆使して設定し、changeText()で実際の変換を実行する。includeMasterPagesを設定しないとマスターページは検索されない罠、とか。
  • InDesign CS3のJavaScriptリファレンスPDFがない…。早く出しておくれ。
  • clearObjectStyleOverrides()でオブジェクトのオーバーライドを一発解除できるようになった。これまでtry catchで必死にやっていたのでこれは嬉しい。
  • JavaScriptデバッガツールのToolkitが機能アップ。タブスタイルを止めてしまったのが残念だけど、InDesign上で実行したものをデバッグできる(前のバージョンではInDesignメニュー上で呼び出したのはToolkitからは追えなかった)、#includeでほかのファイルを取り込んでいる場合も追跡できる、リファレンスPDFがない代わりにオブジェクトツリーとヘルプでいろいろ調べられる。
  • テーブルのスタイルが加わった。これまでどうにも使いにくかったテーブルも、これで少しマシになるかもしれん(でも、出版社の要求されるテーブルのスタイルって結局段落でやったほうがずっと楽なことが多い…)。
  • スクリプトのサブツリーおよびユーザースクリプトディレクトリがわかりやすく利用できるようになった。

2008年02月22日

特殊文字処理、リナンバリング

あいかわらずInDesign Hacking with JavaScriptの作業にいそしんでいます。

InDesign側では強制改ページや1/4スペースなどのいろいろな特別な文字を入れることができるのですが、XMLではそのような表現ができません(一部はエンティティで可能ですが、必要なものほどそういうのが用意されていない…)。流し込みで済ませる上ではこういった見栄え操作もできるだけ元テキスト内に含めておきたいので、XMLインストラクションに埋め込まれたデータを拾って特殊文字化するライブラリ(libProcessXMLforSpecialCharacters.jsx)を書きました。

XML側ではこんな感じですね。「dtp」というパラメータ名の値にInDesign JavaScriptのSpecialCharacters enumerationで定義されている名前を全部小文字で書く。

<p>ほげほげ</p>
<?dtp pagebreak?><p>もげもげ...

あとはライブラリを次のように呼び出せば、インストラクションの直前に該当の特殊文字が挿入されます。

processXMLforSpecialCharacters(app.activeDocument, app.activeDocument.xmlItems);

もう1つ作ったのは、段落の自動連番機能の支援です。InDesignには連番機能が一応あるのですが、これはタグ構造ではなくて連続する同一段落スタイルかどうかで判断されちゃっています。このため、たとえば1番の説明の途中でコード例を挟んだりすると、2番目のものの番号が「2.」になるはずがリセットされて「1.」に戻ってしまうと。番号を単にテキスト化して編集するという手もありますがミスを招きやすそうです。ということで、スクリプトlibProcessXMLforRenumbering.jsxを作成。たとえばHTML風にol要素の中にli要素で各番号リスト項目が入っている場合、次のような感じになります。

processXMLforRenumbering(app.activeDocument.xmlItems, "ol", "li");

ロジックとしてはわりあい単純で、リストブロック要素を発見したらその中で項目となる要素を探していって、同じ項目要素が続いているならそのまま継続して番号を控えておき、別のものが挟まったら次に項目要素が来たときにその段落のnumberStartAtを変更するというものです。番号の前のほうで連番が変わったときには再度スクリプトを実行する必要があります。

2008年02月13日

item()とitemByRange()の謎

InDesign Hacking with JavaScriptのほうはぼちぼちとライブラリを追加/リファクタリングを進めています。今のところはまだ安定期ではないため、関数引数もわりあい頻繁に変わってたりします。

最近は側注対応(libSidenote)やツメ見出し対応(libSidemarker。本当は英語では何ていうんですかね。手近な洋書にはそもそもそういうデザインのがないんですが)を行い、そこそこ実用になっています。

さて、CS3ではすでに修正が行われていそうなことですが、少なくともCS2ではitem()とitemByRange()の挙動が妙に使いにくくて困ったものです。どちらもあるラベルまたはXML要素(属性)を検索してヒットしたものを返すのですが、

  • xmlAttributes.item("id")としたとき、idという属性がある場合にはその属性のXMLAttributeオブジェクトが返る。idという属性がなくてもXMLAttributeオブジェクトが返る。でもそのXMLAttributeオブジェクトが使える(プロパティを取れる)かどうかは調べることができない。アクセスして例外が起きて初めてわかるので、えらく使いにくい。
  • itemByRangeは2つの引数を取る。ある1つのものを探したいときには同じものを指定する。つまり、xmlAttributes.itemByRange("id", "id")という感じ。取れなかったときにはnullが返る。取れたときには、XMLAttributeの微妙な配列が返る。微妙というのは、たとえばこれをvar a = xmlAttributes...で取っても、aは配列ではなくてXMLAttributeオブジェクトになる。パラメータを取りたければa.name[0]とかする。テキストフレームのgeometricBoundsを取りたいというときも、textFrames.itemByRange("main", "main")[0].geometricBoundsのようにしたいんだけど駄目で、textFrames.itemByRange("main", "main").geometricBounds[0]。

まぁこういうのはInDesignのオブジェクト構成ではままあるようです。そういえば、スタイルのオーバーライドを解除するのをスクリプトからできないんですかね。placeXMLするとスタイルがオーバーライドされてしまうので、現状ではオブジェクトスタイルプロパティ経由で1つずつ適用し直すという不格好な方法をとっています。

2008年01月26日

「InDesign Hacking with JavaScript」

作成しているスクリプトを公開するために、「InDesign Hacking with JavaScript」というページを用意しました。

当然ながら、JavaScript で Adobe のシリアルをぶっこ抜き……じゃなくて、スクリプトでいじり回ろうというのがこの「Hacking」(ハッキング) という言葉に込められています。

第一弾として、いくつかのライブラリスクリプトを公開しました。Windows の CS2 および Mac OS X の CS2 では検証しています。CS3 では TextFrames の代わりに TextFrame を返すメソッドがいくつかあるようなので、その場合にはスクリプトを適宜変更する必要があるでしょう。

「ライブラリ」の名のとおり、関数 (本来はメソッドでしょうが、クラス化していないのであえて関数と呼んでおきます) の集合なので、実際の利用では関数を呼び出すスクリプトのコードを別途作成する必要があります。ある程度 JavaScript に慣れている方なら容易かとは思いますが、業務に影響のない範囲で (コード自体の公開に差し障りがあるわけではないのですが、まだ作業非公開の書籍が透けて見えるとまずいかもしれないので)、ダイアログベースのものやコマンドベースのものを徐々に公開していく予定です。

XML については、CS3 だともっと楽なのかなぁと思うようなものがいろいろありますね。

2008年01月15日

ライセンスを考える

作っている各InDesignスクリプトはそんな大したものではないし、ほかのいろいろなページを参考にして作ってきたものだから、それにライセンスとか使用許諾とか書くのはおこがましいかもしれない。

ただ場合によってはこの辺を明確にしておかないと困るという場面も出てくるので、共有を主としたライセンスを起こすことにする。英語ライセンスならいくつか使えそうなものはあるのだけど、対象者は日本語ユーザーだし、オレオレライセンスとして適当に作成。

DFSG的フリーをベースに、ライセンスとコードの伝播性を含めてみた。

ソフトウェア使用許諾同意書
本ソフトウェアの利用・変更・再配布にあたっては、下記の使用許諾同意書に
同意する必要があります。

1. 本使用許諾同意書における「ソフトウェア」とは、機械可読の資料 (ライブ
   ラリ、スクリプト、ソースファイル、データファイル)、実行形式、および
   文書を意味します。
2. 本ソフトウェアの使用許諾同意書に同意する限りにおいて、使用者は
   本ソフトウェアを自由に利用、変更することができます。
3. 本ソフトウェアに変更を加えない限りにおいて、使用者は本ソフトウェアを
   自由にコピー、再配布することができます。
4. 本ソフトウェアは無保証です。作者およびそれに関連する組織、配布者は、
   本ソフトウェアの使用に起因する一切の直接損害、間接損害、偶発的損害、
   特別損害、懲戒的損害、派生的損害について何らの責任・保証も負いません。
5. 本ソフトウェアを変更した上で再配布するときには、下記の事項すべてに
   従わなければなりません。
   - 使用許諾同意書の内容に変更を加えてはなりません。技術上の理由で
     文字エンコーディングの変換を行うことは許可しますが、その使用者が
     特殊な技術的措置なしに可読な形でなければなりません。
   - 技術上の理由でバイナリ化・難読化を行う場合も、変更箇所を含めた
     ソフトウェアを、その使用者が可読可能な形式の形で同一のメディアで
     提供しなければなりません。本使用許諾同意書の2条および3条により、
     使用者が可読形式の該当ソフトウェアを変更、コピー、再配布することを
     妨げてはなりません。
   - ソフトウェア構成物の所定の作者名の欄に、変更者のクレジット
     (個人名、企業名、所属、連絡先など)を「追加」しなければなりません。
6. 本ソフトウェアを変更した上で再配布するときには、変更理由および
   その内容を明記することが推奨されます。
7. 使用者がソフトウェアに適用可能な特許に対して特許侵害にかかわる何らか
   の行動を開始した時点で、この使用許諾同意書は自動的に終了し、以降
   使用者はこの使用許諾書によって与えられた一切の権利を放棄するものと
   します。

著作権所有者 Copyright (C) 2008 Kenshi Muto. All rights reserved.
使用許諾同意書バージョン1.0
著作権所有者による書面での事前の許可がない限り、この使用許諾同意書
に変更を加えてはなりません。

2008年01月03日

InDesign+XMLを実践してみる

かねてからの懸案だった、InDesignによるドキュメントの自動組版に挑戦しています。

自動組版ならTeXでいいじゃないという声が聞こえてきそうですが、三美印刷・東京書籍印刷・オーム社のようなTeXニシャンがいない限り、商業出版品質のスタイル付けをするのは現実的に「無理」です。そもそもTeXニシャンの絶対数がどんどん少なくなっていっている上に、DTPオペレータ知識にプログラマ(しかも生TeXの…)とデザイナの素養がプラスで必要となるため、将来に希望の持てる手法とは言い難いものがあります。XMLにXSLを付けるApache FOPは期待を少し持てますが、日本の商業出版品質にまで至るのはまだ当分先……というか、XSLエディタがまだ厳しいなぁというところ。少なくとも商業出版用と言ってデザイナに使わせたらキレるでしょう。あとは商業出版品質だとFrameMaker。まぁこれは妥当なところだとは思うんですが、MacOS版はもうないし、Adobeの本気度もいまいち低めな気がするし、周囲のDTPオペレータも使ってないのでこれから展開するのは難しいものがあります。

で、現状で弊社のDTPオペレータ/デザイナがなじんでいるソフトウェアでなんとか済ませるようにすれば、書面レイアウトなどで無駄がなく、自動組版作業のコストもそこそこ安く済ませられるのではないかと考えています(OS9→OSXや各ソフトウェアのバージョンアップなどはしょうがないとして)。つまり、Adobe InDesignかQuark QuarkXpressです。

ただどうも調べてみるとこれらは自動組版ができるかのように謳いつつも、標準で用意されている機能は版面のちょっとした部分で流し込みができるよ、という程度で、数百ページの書籍の作成に必要な機能が不足しているようです(そもそもこれらは、パンフなどの薄くて書籍要素がほとんどないものを作るためのものかも…)。

InDesignやQuarkの自動組版にあたってサードパーティ製のものはいくつかあるのですが、値段が大変高かったり、機能的に満足行かないものが多く、会社で買って実用にするにはちょっと厳しいかなというところです。

ということで、すでに屍があちこちにありそうですが、簡易XMLドキュメントにDTPオペレータおよびデザイナにより作成した綺麗なスタイルを付け、ほぼそのまま入校できることを目標にします。

InDesign CSからある程度まともなXML処理が加わっており、UIやJavaScript(AppleScriptやVBScriptもありますが、互換性が怖いし)で操作できます。難しそうなところ(構造を平たく示すタグ、相互参照やナンバリングなど)は事前に外部でノーマライズやパーサをRubyあたりで書いておくことで回避するのがよいかなと思っています。

大扉や章扉、権利表記、奥付などの差し替えで対処できそうなところは無理せずに差し替えで対処していこうと思いますが、章扉で節タイトルを含ませたい場合は自動生成したいかもしれません。

とりあえず現時点では、

  • XMLの1つのタグに1つの段落スタイルまたは文字スタイルを割り当てる (InDesignの標準機能)
  • 図表をXMLで表現する (同標準機能)
  • 対象段落スタイルを選択しての節柱の自動生成
  • XML索引用タグからノンブルと索引項目をマッチングさせたCSVの出力
  • XML脚注用タグから脚注の自動生成 (文字スタイルの反映がまだ)

というところまで進んでいます。ライセンス(LGPLの方針を短く日本語にした的なもの)などを記述した後に、このblogカテゴリか専用ページを用意して配布を考えています。

なお、私が使っているのはWindows版InDesign CS2です。XMLイベントモデルがない(提供されるのはDOMモデルっぽいものだけ)、XPathがない、footnoteにはXMLを入れられない(これはCS3でもダメ)、といろいろ涙目。