曜日の漢字の字形を変更する

カレンダーなどを作成するときに、曜日の漢字の字形を括弧付き、白丸、黒丸、白角、黒角m、白角丸、黒角丸といった字形に変更したいことがあります。手作業で変更するのは結構手間なので、スクリプトを書きました。
数字について同様の処理を行うスクリプトを、市川せうぞーさんが既に作られておりましたので、そのコードをありがたく流用させていただきました。せうぞーさん、いつもいつもありがとうございます。

【 動作確認 】
Windows7 x64
InDesign CS4

【 参考ページ 】
丸数字などを簡単に変換できる「round_num 0.3」

【 使い方 】
1) 字形を変更する対象のテキストを選択します。選択範囲は本文中の段落でも、表の列・行・セルでも構いません。
2) 本スクリプトを実行します。
3) 変更後の字形を選択します。白丸、黒丸、白角、黒角m、白角丸、黒角丸が選択できます。

4) ダイアログボックスの[OK]ボタンをクリックすると字形が変更されます。

/*
 * 曜日の漢字の字形を変更する
 * 
 * Rev01 2011.02.09 初版
 *
 * 参考ページ: 丸数字などを簡単に変換できる「round_num 0.3」
 *             http://d.hatena.ne.jp/seuzo/20090527/1243353039
 */

/*******************************************************************************
 * グローバル変数
 *******************************************************************************/
var docObj = app.activeDocument;
var targetObj = new Array();

main();

/*******************************************************************************
 * [概要] メインルーチン
 *******************************************************************************/
function main() {
 if (app.documents.length == 0) {
    myError("文書が開かれていません。\n文書を開いて、テキストを選択してから実行してください。");
  } else if (app.activeDocument.selection.length == 0) {
    myError("何も選択されていません。\nテキストを選択してから実行してください。");
  } else {
    var selObj = docObj.selection[0];
    var objType = selObj.reflect.name;
    //alert(objType);
    objType = "Text, TextColumn, Story, Paragraph, Line, Word, Character, TextStyleRange, Table, Cell".match(objType);
    if (objType == null) {
      myError("テキストを選択してから実行してください。");
    }
  }

  // 変換対象の文字を拾い出す
  var i;
  var hitObj = my_regex(selObj, "[日月火水木金土]");
  for (i = 0; i < hitObj.length; i++) {
    //$.writeln(hitObj[i].contents);
    targetObj.push(hitObj[i]);
  }
  if (targetObj.length == 0) {
    myError("選択されたテキストの中に、曜日の漢字はありませんでした。");
  }

  // 囲み文字の種類を選択するためのダイアログボックスを表示する
  var myList = [
    "括弧付きにする &#12842;", // 0
    "白丸にする &#12938;", // 1
    "黒丸にする", // 2
    "白角にする", // 3
    "黒角にする", // 4
    "白角丸にする", // 5
    "黒角丸にする"  // 6
  ];
  var ans_int = radioDialog("曜日漢字の字形変更", "曜日の漢字の字形を変更します。字形の種類を選択してください\n", myList);
  //$.writeln(ans_int);

  // CIDテーブルのセット
  var my_tbl = new Array(); // my_tblはCID番号の配列
  my_tbl[0] = [3284,1860,1360,2603,3814,1754,3156];           // 標準の字形
  if (ans_int === 0) {
    my_tbl[1] = [8197,8198,8199,8200,8201,8202,8203];         // 括弧付きの字形
  } else if (ans_int === 1) {
    my_tbl[2] = [10471,10472,10473,10474,10475,10476,10477];  // 白丸の字形
  } else if (ans_int === 2) {
    my_tbl[3] = [10753,10754,10755,10756,10757,10758,10759];  // 黒丸の字形
  } else if (ans_int === 3) {
    my_tbl[4] = [11023,11024,11025,11026,11027,11028,11029];  // 白角の字形
  } else if (ans_int === 4) {
    my_tbl[5] = [11296,11297,11298,11299,11300,11301,11302];  // 黒角の字形
  } else if (ans_int === 5) {
    my_tbl[6] = [11566,11567,11568,11569,11570,11571,11572];  // 白角丸の字形
  } else if (ans_int === 6) {
    my_tbl[7] = [11835,11836,11837,11838,11839,11840,11841];  // 黒角丸の字形
  } else {
    myError("処理を中止しました");
  }
  
  // ターゲットをループ
  var my_count = 0;
  var tmp_result = "";
  for (var i = 0; i < targetObj.length; i++) {
    var my_contents = targetObj[i].contents;  //ターゲットのテキスト
    var my_font = targetObj[i].appliedFont;   //ターゲットテキストのフォント

    for (var youbi = 0; youbi < 7; youbi++) {
      //字形検索置換
      try {
        tmp_result = change_glyph(targetObj[i], my_font, my_tbl[0][youbi], my_font, my_tbl[ans_int+1][youbi]);
        if (tmp_result != "") {
          my_count++;
        }
      } catch(e) {
        targetObj[i].contents = my_contents;
      }
    }
  }

  // 結果レポート
  if (my_count == 0) {
    alert ("変更箇所はありませんでした。\n指定された字形を持たないフォントが使われている可能性があります。");
  } else if (targetObj.length > my_count) {
    var failure_count = targetObj.length - my_count;
    alert (targetObj.length + "箇所中、" + my_count + "箇所の曜日を変換しました\n失敗した" + failure_count + "箇所については字形を持たないフォントが使われている可能性があります。");
  } else {
    alert ( my_count + "箇所の曜日を変換しました");
  }
}


/*******************************************************************************
 * [概要] 字形変更メニューのダイアログボックスを表示する
 *
 * [引数]
 *   myTitle  : ダイアログボックスのタイトルバーに表示する文字列
 *   myPrompt : ダイアログボックスに表示するメッセージ
 *   myList   : ラジオボタンに展開するリスト
 *
 * [戻り値]
 *   選択したリスト番号
 *
 *******************************************************************************/ 
function radioDialog(my_title, my_prompt, my_list){
  app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
  var my_dialog = app.dialogs.add({name:my_title, canCancel:true});
  with(my_dialog) {
    with(dialogColumns.add()) {
      // プロンプト
      staticTexts.add({staticLabel:my_prompt});
      with (borderPanels.add()) {
        var my_radio_group = radiobuttonGroups.add();
        with (my_radio_group) {
          for (var i = 0; i < my_list.length; i++){
            if (i == 0) {
              radiobuttonControls.add({staticLabel:my_list[i], checkedState:true});
            } else {
            radiobuttonControls.add({staticLabel:my_list[i]});
            }
          }
        }
      }
    }
  }

  if (my_dialog.show() == true) {
    var ans = my_radio_group.selectedButton;
    //正常にダイアログを片付ける
    my_dialog.destroy();
    //選択したアイテムの番号を返す
    return ans;
  } else {
    // ユーザが「キャンセル」をクリックしたので、メモリからダイアログボックスを削除
    my_dialog.destroy();
  }
}

/*******************************************************************************
 * [概要] 字形検索置換
 *
 * [引数]
 *   my_range_obj : 検索置換の対象範囲
 *   find_font    : 変換前のフォント
 *   find_gid     : 変換前のglyph ID
 *   change_font  : 変換後のフォント
 *   change_gid   : 変換後のglyph ID
 *
 * [戻り値]
 *   置換後のオブジェクト
 *
 *******************************************************************************/ 
function change_glyph(my_range_obj, find_font, find_gid, change_font, change_gid) {
  var my_doc = app.activeDocument;
  app.findGlyphPreferences = NothingEnum.nothing;
  app.changeGlyphPreferences = NothingEnum.nothing;
  app.findGlyphPreferences.appliedFont = find_font;
  app.changeGlyphPreferences.appliedFont = change_font;
  app.findGlyphPreferences.glyphID = find_gid;
  app.changeGlyphPreferences.glyphID = change_gid;
  var my_result = my_range_obj.changeGlyph ();
  return my_result;
}

/*******************************************************************************
 * [概要] 正規表現で検索して、ヒットオブジェクトを(お尻から)返す
 *
 * [引数]
 *   my_range_obj : 選択されているテキスト
 *   my_find_str  : 正規表現
 *
 * [戻り値]
 *   正規表現検索にマッチした文字列の配列
 *
 *******************************************************************************/ 
function my_regex(my_range_obj, my_find_str) {
  //検索の初期化
  app.findGrepPreferences = NothingEnum.nothing;
  app.changeGrepPreferences = NothingEnum.nothing;
  //検索オプション
  app.findChangeGrepOptions.includeLockedLayersForFind = false;  // ロックされたレイヤーをふくめるかどうか
  app.findChangeGrepOptions.includeLockedStoriesForFind = false; // ロックされたストーリーを含めるかどうか
  app.findChangeGrepOptions.includeHiddenLayers = false;         // 非表示レイヤーを含めるかどうか
  app.findChangeGrepOptions.includeMasterPages = false;          // マスターページを含めるかどうか
  app.findChangeGrepOptions.includeFootnotes = false;            // 脚注を含めるかどうか
  app.findChangeGrepOptions.kanaSensitive = true;                // カナを区別するかどうか
  app.findChangeGrepOptions.widthSensitive = true;               // 全角半角を区別するかどうか

  app.findGrepPreferences.findWhat = my_find_str;                // 検索文字の設定
  //app.changeGrepPreferences.changeTo = my_change_str;          // 置換文字の設定
  return my_range_obj.findGrep(true);                            // 検索の実行(reverse)
}

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

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