【Lifehacks】InDesign文書を生成する
■タスク
・データファイルを元に定型的ページ構成のInDesign文書を自動生成する。
■目的
・ページ内のオブジェクト配置は単純だが、データが多いため手作業を少なくしたい。
・ページ構成が確定していないので、試行錯誤を行いたい。
・今後、様々な文書を生成する場合の雛形となるスクリプトを作りたい。
■仕様
・スクリプトは、前処理、コンテンツ生成処理、後処理の関数に分ける。
・コンテンツ生成処理で参照するページ構成に必要な各種パラメータは、スクリプト先頭部分で定義する。
・コンテンツ生成処理の内容は、生成する文書に応じて書き換えることを想定。
・今回の例におけるデータファイル仕様は以下の通り。
- データファイルはCSV形式。
- データファイルは4つの項目を持つ。
- 第1項目はテキストフレーム用の文字列。
- 第2~4項目はイメージフレーム用の画像ファイル名。
- 第2~4項目は空の場合あり。
・今回の例におけるページ仕様は以下の通り。
- 表紙、中扉等、先頭に6頁。
- 裏表紙、奥付等、末尾に4頁。
- 先頭・末尾頁は頁生成のみスクリプトで実施。
- 主要頁部は、4頁1組で、データファイルの各行が1組に対応する。
■備考
・画像貼り付け用テキストフレームはコンテントタイプをグラフィックに指定するが、テキストに指定した場合とフレームの位置が異なる。
解消方法が不明のため、今回は場当たり的対応を実施。
■使用方法
・本スクリプトをInDesignのスクリプトパネルフォルダに配置。
・InDesignを機動し、スクリプトパネルから当該スクリプトを呼び出し。
■プログラム
// // SgIdGenDocForPjXXX.jsx // InDesign文書を生成する。 // // Author: Orihika Ikuo // Create: 2008.10.12 // Update: 2008.10.18 // //// Constant ///////////////////////////////////////////////////////////// const PATH_SEP = "/"; const ITEM_SEP = ","; const BASE_DIR = "X:/Project/Project01"; const IMG_DIR = BASE_DIR + PATH_SEP + "Image"; const DAT_FILE = BASE_DIR + PATH_SEP + "Data.csv"; const FRONT_PG_NUM = 6; const BACK_PG_NUM = 4; const PG_W = 105; const PG_H = 105; const UNIT = "mm"; const BINDING = PageBindingOptions.leftToRight; const TXT_FR_X = 15; const TXT_FR_Y = 45; const TXT_FR_W = 75; const TXT_FR_H = PG_H - (2 * TXT_FR_Y); const TXT_CHR_SZ = "20Q"; const TXT_FONT = "小塚ゴシック Pro R"; const IMG_FR_X = -20; const IMG_FR_Y = -20; const IMG_FR_W = 145; const IMG_FR_H = 145; const IMG_SCALE_H = 50; const IMG_SCALE_V = 50; //// Main routine ///////////////////////////////////////////////////////// main(); function main() { var itemMatrix = SgIdLoadDat(); var doc = SgIdPrologue(); SgIdGenContent(doc, itemMatrix); SgIdEpilogue(doc); } //// Sub routine ////////////////////////////////////////////////////////// function SgIdLoadDat() { var itemMatrix = new Array(); var myFile = new File(DAT_FILE); var flgOpen = myFile.open("r"); if (!flgOpen) { alert("Cannot open file."); } while(!myFile.eof) { var line = myFile.readln(); var itemList = line.split(ITEM_SEP); itemMatrix.push(itemList); } return itemMatrix; } function SgIdPrologue() { var doc = SgIdCreDoc(); doc = SgIdAddBasicPages(doc); return doc; } function SgIdCreDoc() { var doc = app.documents.add(); doc.viewPreferences.textSizeMeasurementUnits = MeasurementUnits.q; doc.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.millimeters; doc.viewPreferences.verticalMeasurementUnits = MeasurementUnits.millimeters; doc.documentPreferences.pageWidth = PG_W + UNIT; doc.documentPreferences.pageHeight = PG_H + UNIT; doc.documentPreferences.pageBinding = BINDING; return doc; } function SgIdAddBasicPages(doc) { // 先頭頁の追加 // デフォルト頁の分を減じて頁生成 for(var i = 0; i < FRONT_PG_NUM - 1; i++) { doc.pages.add(); } // 末尾頁の追加 for(var i = 0; i < BACK_PG_NUM; i++) { doc.pages.add(); } return doc; } function SgIdEpilogue(doc) { // doc.close(SaveOptions.yes); } //// Custom sub routine /////////////////////////////////////////////////// // // 文書仕様にあわせた内容とする。 // 本例: // ・4頁1組 // ・1頁目にテキストフレーム // データ配列の1件目の文字列を入力 // ・2~4頁目にイメージフレーム // データ配列の2~4件目のファイルを配置 // ・データ配列の2~4件目は空の場合あり // function SgIdGenContent(doc, itemMatrix) { var pos = doc.pages.item(FRONT_PG_NUM - 1); for (var i = 0; i < itemMatrix.length; i++) { var itemList = itemMatrix[i]; var pg0 = doc.pages.add(LocationOptions.after, pos); var pg1 = doc.pages.add(LocationOptions.after, pg0); var pg2 = doc.pages.add(LocationOptions.after, pg1); var pg3 = doc.pages.add(LocationOptions.after, pg2); var aryPg = [pg0, pg1, pg2, pg3]; pos = pg3; if (itemList[0] != "") { SgIdAddTxtFrame(aryPg[0], itemList[0]); } else { alert("0th item is not there."); } for (j = 1; j < itemList.length; j++) { if (itemList[j] != "") { SgIdAddImgFrame(aryPg[j], itemList[j]); } } } } function SgIdAddTxtFrame(pg, str) { var x1 = TXT_FR_X; var y1 = TXT_FR_Y; var x2 = TXT_FR_X + TXT_FR_W; var y2 = TXT_FR_Y + TXT_FR_H; txtFrame = pg.textFrames.add(); if (pg.side == PageSideOptions.rightHand) { x1 += PG_W; x2 += PG_W; } txtFrame.visibleBounds = [y1, x1, y2, x2]; txtFrame.contentType = ContentType.textType; txtFrame.contents = str; txtFrame.paragraphs[0].appliedFont = app.fonts.item(TXT_FONT); txtFrame.parentStory.texts.item(0).pointSize = TXT_CHR_SZ; txtFrame.textFramePreferences.verticalJustification = VerticalJustification.centerAlign; } function SgIdAddImgFrame(pg, fileName) { var x1 = IMG_FR_X; var y1 = IMG_FR_Y; var x2 = IMG_FR_X + IMG_FR_W var y2 = IMG_FR_Y + IMG_FR_H; imgFrame = pg.textFrames.add(); if (pg.side == PageSideOptions.rightHand) { x1 += PG_W; x2 += PG_W; } imgFrame.visibleBounds = [y1, x1, y2, x2]; imgFrame.contentType = ContentType.graphicType; imgFrame.place(IMG_DIR + PATH_SEP + fileName); imgFrame.horizontalScale = IMG_SCALE_H; imgFrame.verticalScale = IMG_SCALE_V; imgFrame.fit(FitOptions.centerContent); }