外部ファイルの指定に従ってノンブルを振る

印刷物を作っていると、変則的なノンブルの振り方を要求されることがしばしばあります。真面目にセクションを定義して指定どおりのノンブルを振るのは結構骨が折れる作業です。そこで、外部ファイルでノンブルの振り方を指定し、ノンブル専用のレイヤにテキストフレームを置いてノンブルを書いていくスクリプトを作ってみました。

【 動作確認 】
Windows7 x64
InDesign CS4

【 使い方 】
1) Excelを使って下記のような2列のデータからなるスプレッドシートを作ります。

列1: 通しのページ番号
列2: ノンブルの数字。ただし、0を指定するとそのページにノンブルを振らない。

 ■例(10ページの文書)

  列1 列2
  1    0  <-- 目次
  2    0  <-- 白ページ
  3    1
  4    2
  5    3
  6    0  <-- 白ページ
  7    5  <-- トビラ
  8    0  <-- 白ページ
  9    7
 10    8

2) スプレッドシートをタブ区切りテキストファイルに保存します。

3) InDesignで対象文書を開き、本スクリプトを実行します。

4) ノンブルのテキストフレームの高さを聞いてくるので、mm単位で入力します(デフォルト値は10mm)。

5) ノンブル情報を記述したファイルの選択を求められるので、上記で作ったタブ区切りテキストファイルを選択します。

以上の操作により、「ノンブル」というレイヤが追加され、各ページにノンブルが振られます。
ノンブルのフォントタイプやフォントサイズはスクリプトの先頭で定義しているので、必要に応じて修正してください。

【 注 意 】
下記のスクリプトは、ドキュメント設定の「見開きページ」がオフになっている文書を前提にしています。

/*
 * 外部ファイルの指定に従って、文書にノンブルを振る
 * 
 * Rev01 2011.02.12 初版
 *
 */

/*******************************************************************************
 * グローバル変数
 *******************************************************************************/
var docObj = app.activeDocument;
var folioArray = new Array();  // 各ページに振るノンブルの数値を記憶する配列
var setColor = [0, 0, 0, 0];   // ノンブルのテキストフレームの塗りの色(白)
var colorWhite = app.activeDocument.colors.add({model:ColorModel.process,space:ColorSpace.cmyk,colorValue:setColor});
var folioFontObj;              // ノンブルのフォントオブジェクト
var folioFontName = "小塚ゴシック Pro Regular";  // ノンブルのフォント
var txtFrmHeight;              // ノンブルを書くテキストフレームの高さ
var folioFontSize = "14q";     // ノンブルのフォントサイズ 

main();

/*******************************************************************************
 * [概要] メインルーチン
 *******************************************************************************/
function main() {
  if (app.documents.length == 0) {
    myError("文書が開かれていません。\n文書を開いてから実行してください。");
  }

  // 定規の開始位置と単位を設定する
  with(docObj.viewPreferences){
    rulerOrigin = RulerOrigin.pageOrigin;
    horizontalMeasurementUnits = MeasurementUnits.millimeters;
    verticalMeasurementUnits = MeasurementUnits.millimeters;
  }

  // ノンブルの文字に指定するフォントの有無を確認する
  folioFontObj = app.fonts.item(folioFontName);
  if (folioFontObj == null) {
    meError("システムにフォントがインストールされていません。\nフォント名 = 小塚ゴシック Pro  Regular");
  }

  // ノンブルのテキストフレームの高さの入力を求める
  txtFrmHeight = parseInt(prompt("ノンブルのテキストフレームの高さ",10));
  
  // 外部ファイルからノンブルの指定を読み込む
  var numPage = readFolioInfo();

  // アクティブドキュメントのページ数と、外部ファイルで指定されたノンブルのページ数が合っているかチェックする
  if (numPage != docObj.pages.length) {
    myError("現在開いている文書ページ数と、外部ファイルで指定されているページ数が異なっています。");
  }

  // 外部ファイルの指定に従って、各ページのノンブルレイヤにノンブルを振る
  folioAssign();
  
  alert("ノンブル振りが終了しました。");
}

/*******************************************************************************
 * [概要] 外部ファイルからノンブルの情報を読み込む 
 *
 * [戻り値]
 *   外部ファイルに記述されている、文書のページ数
 *******************************************************************************/
function readFolioInfo() {
  var folioInfoFile = File.openDialog("ノンブルの情報を記述したファイルを選択してください");
  if (!folioInfoFile) {
    myError("スクリプトの実行を中止しました。");
  }

  var flag = folioInfoFile.open("r");
  if (!flag) {
    myError("選択されたファイルが開けませんでした");
  }

  pageCount = 0;
  var re = new RegExp("([^\t\r\n]*)\t([^\t\r\n]*)");
  while (!folioInfoFile.eof) {
    var oneLine = folioInfoFile.readln();
    //$.writeln(oneLine);
    if (oneLine.match(re)) {
      //$.writeln(pageCount);
      var docPage, folio;
      docPage = RegExp.$1;
      folio = RegExp.$2;
      if (docPage != (pageCount+1)) {
        myError("外部ファイルの1列目の数値が、非連続になっています\n行番号 = " + (pageCount + 1));
      } else {
        folioArray[pageCount] = folio; // 各ページに振るノンブルの数値
      }
      pageCount++;
    } else {
      myError("入力ファイルに異常があります\n行番号 = " + (pageCount + 1));
    }
  }
  folioInfoFile.close();
  return(pageCount);
}

/*******************************************************************************
 * [概要] 外部ファイルの指定に従って、各ページにノンブルを振る
 *******************************************************************************/
function folioAssign() {
  var folioLayerObj = make_layer("ノンブル");
  with (folioLayerObj) {
    printable = true; // レイヤを印刷する
    visible = true; // レイヤを表示する
    move(LocationOptions.atBeginning);  // レイヤを最前面に配置する
  }
  // 全ページのループ
  for (var i = 0; i < docObj.pages.length; i++) {
    if (folioArray[i] != 0) { // ノンブルの指定が0の場合は、ノンブルを振らない
      var pageObj = docObj.pages[i];
      var myTextFrame = pageObj.textFrames.add(); // テキスト・フレーム作成
      var pageBounds = pageObj.bounds;  // ページのバウンダリを取得
      //$.writeln(pageBounds[0] + ", " + pageBounds[1] + ", " + pageBounds[2] + ", " + pageBounds[3]);
      with (myTextFrame) {
        contentType = ContentType.textType;
        strokeWeight = "0mm"; // テキスト・フレームの線幅を0mmにする
        strokeColor = "None"; // 【注意】 線幅を0mmにしても、カラーをNoneにしないと線幅は0mmにならない
        geometricBounds = [pageBounds[2]-txtFrmHeight, pageBounds[1], pageBounds[2], pageBounds[3]];  // 座標
        contents = "− " + folioArray[i] + " −"; // ノンブルの文字列
        paragraphs[0].pointSize = folioFontSize;  // フォントサイズ
        paragraphs[0].appliedFont = folioFontObj; // フォント
        paragraphs[0].justification = Justification.CENTER_ALIGN; // センタリング
        fillColor = colorWhite; // 背景色
      }
    }
  }
}

/*******************************************************************************
 * [概要] 指定された名前のレイヤを探し、なかったら作る
 * 
 * [引数]
 *   my_layer_name : レイヤー名
 *
 * [戻り値]
 *   引数で指定された名前のレイヤーオブジェクト
 *******************************************************************************/
function make_layer(my_layer_name) {
  var my_document = app.documents[0];
  for (var i = 0; i< my_document.layers.length; i++) {
    if (my_document.layers[i].name === my_layer_name) {
      my_document.activeLayer = my_document.layers[i];  // 発見されたらアクティブレイヤーに
      return my_document.layers[i];
    }
  }
  return my_document.layers.add({name:my_layer_name});  //レイヤーがなければ引数名でレイヤーを作成する
}

/*******************************************************************************
 * [概要] エラーメッセージを表示して、スクリプトを抜ける
 * 
 * [引数]
 *   msg : エラーメッセージ
 *******************************************************************************/
function myError(msg) { 
  if (arguments.length > 0) { alert(msg); }
  exit();
}

【 免 責 】

上記スクリプトの使用により発生する、データの破損などのあらゆる不具合・不利益については、一切の責任を負いかねますのでご了解ください。