外部ファイルの指定に従ってフォントを置換するスクリプト(検索・置換利用版)

昨日に引き続き、フォントを置換するJavaScriptです。昨日よりは大分進歩しました。これで完成かどうかは、明日、会社で試してみます。何せ、スクリプトで処理したいファイルは会社にあって、スクリプトは家で書いていますので。多くのDTP担当者の方が私と同じ境遇だと思うのですが、スクリプトを書いて仕事を効率化することの価値は、会社的にはなかなか認めてもらえないのではないでしょうか。DTPの仕事場では、原稿とにらめっこしながら忙しげにレイアウト作業している人がよく働いている人、と見られているように思います。おまけに、ひっきりなしにクライアントから電話がかかってくるような場所で、落ち着いてプログラムなんか書けるわけがない。というわけで、プログラミングはもっぱら家でやることにしています。

ちょっと愚痴っぽくなりましたが、本題に戻ります。
フォントの置換方法を調べるのに、日本語のウェブサイトだけでなく海外のウェブサイトにまで範囲を広げたところ、ドンピシャのページを見つけました。

Find/change missing font with scripting

昨日のスクリプトでは、文書内の全段落、すべての表をなめてフォントを置換しようとしていました。上記のページを見たら、目からウロコ。。。検索・置換の機能で簡単にフォントを置換できるではありませんか (+o+)

このページで紹介しているスクリプトもそのまま使えそうですが、私の場合は置換するフォントのパターンがほぼ決まっているので、GUIを使うより、外部ファイルの指定に従って置換できる方が便利です。このページのスクリプトを参考に、昨日のスクリプトを改良しました。
とてもスッキリ! 実行速度も速くなりました \(^o^)/

12/18 追記:下記のスクリプトでフォントの置換ができるのは、システムにインストールされたフォントだけです。システムにインストールされていないフォントを置換しようとすると、app.activeDocument.fonts.item(tmpArray[0]) がnullを返し、フォントオブジェクトの取得に失敗します。

【 動作確認 】Windows7 x64, InDesign CS4

/*
 * 外部ファイルに記述された対応に従って、文書内のすべてのテキストのフォントを置換する
 * 
 * Rev01 2010.12.14 初版
 * Rev02 2010.12.15 下記のページを参考に、検索・置換機能を使ってフォントを置換する
 *                  ように修正
 *   http://indisnip.wordpress.com/2010/08/24/findchange-missing-font-with-scripting/
 */

/*******************************************************************************
 * グローバル変数
 *******************************************************************************/
var oldFontList = [];  // 置換前のフォント名のリスト
var oldFontObj  = [];  // 置換前のフォントオブジェクトの配列
var newFontList = [];  // 置換後のフォント名のリスト
var newFontObj  = [];  // 置換後のフォントオブジェクトの配列

main();

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

  readFontReplaceFile();  // 外部ファイルから、旧フォント名と新フォント名の対応を読み込む
  replaceFont();          // 検索・置換機能を使って、システムにないフォントを指定のフォントに置き換える
}

/*******************************************************************************
 * [概要] 外部ファイルから、旧フォント名と新フォント名の対応を読み込む
 *******************************************************************************/
function readFontReplaceFile() {
  var fileName = File.openDialog("フォント置換リストを記述したファイルを選択してください");
  if (fileName) {
    var fileObj = new File(fileName);
    var flag = fileObj.open("r"); // ファイルを読み込みモードで開く
    if (flag == true) {
      while (!fileObj.eof) {
        var oneLine = fileObj.readln();
        //$.writeln(oneLine);
        var tmpArray = oneLine.split(",");
        var tmpFontObj;
        try {
          tmpFontObj = app.activeDocument.fonts.item(tmpArray[0]);
          oldFontList.push(tmpArray[0]);  // 置換前のフォント名を配列にプッシュ
          oldFontObj.push(tmpFontObj);    // 置換前のフォントオブジェクトを配列にプッシュ 
        } catch(e) {
          myError("開いている文書の中にないフォントです\nフォント名 = "+tmpArray[0]);
        }
        try {
          tmpFontObj = app.fonts.item(tmpArray[1]);
          newFontList.push(tmpArray[1]);  // 置換後のフォント名を配列にプッシュ
          newFontObj.push(tmpFontObj);    // 置換後のフォントオブジェクトを配列にプッシュ
        } catch(e) {
          myError("システムにインストールされていないフォントです\nフォント名 = "+tmpArray[1]);
        }
      }
    } else {
      myError("ファイル [" + fileName * "] が開けませんでした。");
    }
  } else {
    exit(); // キャンセルボタンがクリックされた場合は、プログラムを終了する
  }
}

/*******************************************************************************
 * [概要] 検索・置換機能を使って、システムにないフォントの置換を行う
 *******************************************************************************/
function replaceFont() {
  app.findTextPreferences = NothingEnum.nothing;   // 検索テキストの指定なし
  app.changeTextPreferences = NothingEnum.nothing; // 置換テキストの指定なし
  for (var i = 0; i < oldFontList.length; i++) {
    app.findTextPreferences.appliedFont = oldFontObj[i];   // 置換前のフォントを指定
    app.changeTextPreferences.appliedFont = newFontObj[i]; // 置換後のフォントを指定
    $.writeln("旧: " + oldFontList[i] + ", 新: " + newFontList[i]);
    app.activeDocument.changeText();  // 検索・置換を実行
  }
}

/*******************************************************************************
 * [概要] 引数で指定されたフォントが置換対象のフォントかどうかを調べる
 * 
 * [引数]
 *   fontName : エラーメッセージ
 *
 * [戻り値:
 *   -1    → 置換対象のフォントではない
 *   0以上 → 新しいフォントオブジェクトの配列のインデックス
 *******************************************************************************/
function searchOldFontList (fontName) {
  for (var i = 0; i < oldFontList.length; i++) {
    if (oldFontList[i] === fontName) {
      //$.writeln("旧: " + fontName + ", 新: " + newFontList[i]);
      return(i);
    }
  }
  return(-1);
}

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

【 免 責 】

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