読者です 読者をやめる 読者になる 読者になる

arinoth's memo

arinothのメモ

MarkdownをXMLに変換してInDesignに読み込む

年始あたりからシコシコ作っていたMarkdownをInDesignに読み込んで、半自動組版するワークフローがだいたいできあがりました。2014年9月期の仕事から実践投入しています(この本この本)。

ダウンロード先:grunt-makdown-custom-inddxml

f:id:arinoth:20141013051724j:plain

md2inaoにインスパイアされて始めたのですが、最終的にしくみも仕様もほとんど別物になりました。以下のような事情があるのです……。

  1. うちは編プロなので出版社さんから提供されるさまざまなデザインフォーマットに対応させなければいけない
  2. ソースコードを色分けする必要があった
  3. 画像も読み込ませたかったしトリミングもしたい
  4. Perlがよくわからない

しくみはものすご〜く単純で、HTMLとXMLの構造はほとんど一緒なので、単純にタグを置換するスクリプトを作ってMarkdown→HTML→XMLという変換を行い、InDesignに読み込むというものです(この単純な答えを思いつくまで1ヶ月ぐらいかかりました……)。少し前からgrunt-markdownを使ってMarkdownをHTML変換する処理をワークフローに採り入れていたので、それに加えてXML変換するプラグインを作りました。中身はほとんどreplaceメソッドの羅列です。

//html2indtag.jsを一部抜粋
var parseHTML = function(src, olmode){
//img関連。画像全体がpで囲まれているのでfigureタグに置き換え
src = src.replace(/<p>(<img[^>]*>)<\/p>/g, '<figure>$1</figure>');
//img関連。src=""をhref="file://"に
src = src.replace(/<img src="([^>]*)>/g, '<img href="file://$1/>');
//img関連。zoomとclipの指定をimg要素のdata-zoom、data-clip属性に
src = src.replace(/(<img href="[^\?]*)\?zoom=([0-9]*)/g, '$1" data-zoom="$2" ');
src = src.replace(/(data-zoom="[0-9]*" )" /g, '$1');
src = src.replace(/(<img [^\?>]*)\?clip=([0-9\+]*)"/g, '$1" data-clip="$2"');
src = src.replace(/\&amp;clip=([0-9\+]*)"/g, 'data-clip="$1"');

grunt部分の説明は前掲のGitHubページのほうに書いたので、ここではInDesign側での作業について書いておきます。

XMLの読み込み

gruntでXML変換を済ませたら、InDesignに読み込みます。フォーマットはなるべくインラインで済むように作り込んでおきます。このブログでも前に触れましたが、自分が担当する本では基本ソースコード部分は表組みにしています。

f:id:arinoth:20141013054542j:plain

読み込みオプションは「追加」にします。

f:id:arinoth:20141013054135j:plain

構造パネルが表示されてツリーが追加されるので、ページにドラッグ&ドロップします。

f:id:arinoth:20141013054136j:plain

※この時点でXMLの解釈エラーが起きる場合は、エラーメッセージに行数が出ているのでXMLファイルの該当場所を探し、Markdownまでさかのぼって原因を調べます。よくあるのは、文章中にHTMLタグが混ざっているなどです。

タグをスタイルにマップ

InDesignの「タグをスタイルにマップ」機能を使い、XMLのタグと段落・文字スタイルのマッピングをします。大量のテキストを読み込んだ状態だと重いので、まず短めの文書を読み込んでマッピングを済ませ、その後本番の流し込みを行うようにするといいでしょう。この作業が一番面倒かつ重要です。成功するまで何度もテストする必要があります。この設定はinddファイルに保存されるため、一回設定を済ませれば、後は流し込むだけで済むようになります。

f:id:arinoth:20141013060630j:plain

f:id:arinoth:20141013060613j:plain

なお、XML変換時に勝手に作っているタグは以下のとおり。

タグ名 目的
div_hen 編集コメント。オペレータや著者への申し送りを書く。目立つようY100の背景色を下線で付けることが多い。Markdown内では「<div class="hen"></div>」とHTML直書き
div_zuchuu 画像の上に載せたい図中文字。Markdown内では「<div class="zuchuu"></div>」とHTML直書き
alert 見出しが区別しやすいよう付ける「h1」などの警告文字。目立つようキンアカの背景色を下線で付けることが多い。h1〜h6タグの前に勝手に入る
figcaption 図版のキャプション。元はimg要素のalt属性
figure 図版。インライン画像の親段落になる。img要素の親のp要素を変換
ol_li 番号付き箇条書きの要素。番号付きリストから自動変換
codelist ソースコード表全体を囲む。行ごとにpre、codeタグが付く。GFMの```から自動変換される
span_xxxx コード類の色分け部分。```jsのように明記が必要

※表関連はスクリプトで表スタイルを適用するので基本的にはマッピングする必要はありません。ただフォーマットの作りによってはなぜかうまく表スタイルでスタイルが設定しきれないことがあり、その場合はpreやtrタグにマッピングすることがあります。

※リンクは「リンク文字列(URL)」の形に変換します。単純な置換で処理しているので、リンクをバッククォートで``で囲んでおかないとおかしくなることがあります。

グリッドスタイルの適用

グリッドフレームに対して流し込むと、せっかくの段落スタイルや文字スタイルがオーバーライドされてしまいます。流し込んでからグリッドフレームに変換しないといけません。 先に本文用のオブジェクトスタイルとグリッドスタイルを作っておき、流し込んでからスタイルを適用してグリッドフレームにすると楽です。

f:id:arinoth:20141013062121j:plain

画像のサイズ変更

XML読み込みした時点では画像サイズが原寸ママででかいので、流し込みが途中で詰まってしまいます。そこで「resizeXMLImage.jsx」というスクリプトを利用して、画像のサイズを一括して変換しておきます(スクリプトは前掲のGitHubページにまとめておいてあります)。

f:id:arinoth:20141013054138j:plain

f:id:arinoth:20141013054139j:plain

ちなみにimg要素のalt属性は図のキャプションと見なして、figcaptionというタグで囲んで画像の下に挿入されます。なので、figcaptionをスタイルにマップさせれば、キャプションの挿入まで完了します。

独自仕様ですが、Markdown段階で次のようにズームサイズとトリミングを指定しておくと、それもこのスクリプトによって反映されます。つまり、流し込み後にちょっとの後処理するだけで画像のサイズ調整とトリミングまで完了できるということです。

![キャプションなし](img/c3d-c2-01-01.png?zoom=50&clip=0+0+1154+450)

※注意:Markdown段階で画像![alt文字列](url)の前後にアキ行がないと、キャプションがちゃんと出てこないことがあります。原因はうすうすわかっているのでいずれ修正します。

※注意その2:元のXMLファイルと画像の相対位置を変えてしまうと、ファイルをうまく読み込めなくなります。また、CMYK変換などは読み込んだ後で「フォルダに再リンク」機能でリンクを付け替えてやります。

ソースコードや通常表に表スタイルを適用

ソースコード(codelistタグ)の場合は「genXMLCode2Table.jsx」、通常表(tableタグ)の場合は「genXMLTable.jsx」によってInDesignの表に変換し、表スタイルを適用して整えます。

f:id:arinoth:20141013054140j:plain

f:id:arinoth:20141013054143j:plain

表スタイルで「ヘッダー行/フッター行用のセルスタイル」を指定しておくと、自動的に先頭行と最終行にセルスタイルを適用します。InDesign本来のヘッダー行/フッター行の機能と異なり、行をヘッダー行/フッター行に変換する必要はありません。改ページしたときにヘッダー行を付けず、単純に先頭行と最終行だけスタイルを変えるために使っています。

f:id:arinoth:20141013054141j:plain

注意点は、テキストフレームがオーバーフローした状態のままこのスクリプトを実行すると、幅が極端に狭くなってしまうという点です。「shift+クリック」で自動流し込みを行い、ページ上に表の元になるテキストが表示されたことを確認してからスクリプトを実行してください。

f:id:arinoth:20141013063039j:plain

フレームのタグを取り除く

XMLタグがついたままだとInDesignの機能がフルに使えないことがあります。そのため、ひととおり自動流し込みが完了したら、フレームを右クリックして[フレームのタグを取り除く]を選択します。

f:id:arinoth:20141013072510j:plain

これでXMLタグがすべて消え、普通のInDesignのテキストになります。後は通常どおり作業していけばOKです。

課題

ここで解説した自動処理でできるのは、「段落・文字スタイルの自動設定」「画像の読み込み、サイズ調整とトリミング、キャプションの挿入」「ソースコードの色分けと表組み」までです(このサンプルは1色刷りなので色分けはコメントをグレーにするのみですが……)。

f:id:arinoth:20141013065245j:plain

ここでサンプルにした書籍のフォーマットは、セクションタイトル、中見出しを別ボックスにするデザインなので、そのあたりは手作業で作り込んでいきます(コードの行番号は別に自動挿入するスクリプトを作って対応しました)。大半を自動で済ませられるかどうかはフォーマットの作り次第です。

f:id:arinoth:20141013054133j:plain

デザインが凝ったフォーマットだと、コードも画像もすべてインラインで済ませるために改造にかなり時間がかかりますし、オペレータさんへの指示が難しくなるという問題もあります。InDesignで作業する以上、そのへんは仕方ないかなというところです。サンプルの本だとソースコード部分が合計1万行前後あるので、全部手作業でやるよりははるかに楽でした。