1桁の数字を全角、2桁以上の数字を半角にするスクリプト

クライアントから入稿する原稿は、数字の全角、半角が統一されていないことがよくあります。あまりコンピューターに慣れていない人は、数字やアルファベットの全角と半角を意識していない場合もあるようです。しかし、印刷屋さんとしてはそのような原稿を右から左で印刷物にするわけにはいきません。とは言っても、毎回、手作業で全角⇔半角を行うのは悲しすぎる。。。という訳でスクリプトの出番です。
同様なことは、テキストエディタのマクロとして提供されていたりしますが、InDesignスクリプトの勉強を兼ねて作ってみました。もっとも、自分で書いたコードはわずかで、ほとんどのコードは市川せうぞーさんを始めとする、先人の偉大な功績の恩恵にあずかりました。

【 動作確認 】Windows7 x64, InDesign CS4

/*******************************************************************************
 * 選択されたテキスト中の数字を、1桁の場合は全角、2桁以上の場合は半角にする
 *
 * Rev01 2010.12.10
 *
 *******************************************************************************/

main();

/*******************************************************************************
 * [概要] メインルーチン
 *******************************************************************************/
function main() {
  // 選択されているオブジェクトを確認する
 if (app.documents.length == 0) {
    myError("文書が開かれていません。\n文書を開いて、テキストを選択してから実行してください。");
  } else if (app.activeDocument.selection.length == 0) {
    myError("何も選択されていません。\nテキストを選択してから実行してください。");
  } else {
    var selObj = app.activeDocument.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 hit_obj = my_regex(selObj, "[0-9]");
  for (i = 0; i < hit_obj.length; i++) {
    hit_obj[i].contents = toFullSize(hit_obj[i].contents);
  }

  // 2桁以上の数字を半角に戻す
  var hit_obj = my_regex(selObj, "[0-9,\.]{2,}");
  for (i = 0; i < hit_obj.length; i++) {
    hit_obj[i].contents = toHalfSize(hit_obj[i].contents);
  }
}

/*******************************************************************************
 * [概要] 正規表現で検索して、ヒットオブジェクトを(お尻から)返す
 *
 * [引数]
 *   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)
}

/*******************************************************************************
 * [概要] 半角数字を全角数字に置換する。処理対象は1文字の数字だけ。
 *
 * [引数]
 *   chr : 正規表現で見つかった文字列(1文字)
 *******************************************************************************/
function toFullSize(chr)
{
  var hankaku = "0123456789";
  var zenkaku = "0123456789";
  var pos = hankaku.indexOf(chr);
  return zenkaku.charAt(pos);
}

/*******************************************************************************
 * [概要] 全角数字を半角数字に置換する。処理対象は1文字以上の数字で、半角と全角
 *        が混じっている場合がある。
 *
 * [引数]
 *   str : 正規表現で見つかった文字列(1文字以上)
 *******************************************************************************/
function toHalfSize(str)
{
  var resultStr = "";  // 変換後の文字列
  var hankaku = "0123456789";
  var zenkaku = "0123456789";
  var pos;  // 文字の位置を保持する
  for (var i = 0; i < str.length; i++) {
    pos = zenkaku.indexOf(str[i]);
    if (pos == -1) {
      // 数字が半角の場合
      resultStr = resultStr + str[i];
    } else {  
      // 数字が全角の場合
      resultStr = resultStr + hankaku.charAt(pos);
    }
  }

  //alert("前:" + str + ", 後:" + resultStr);
  return(resultStr);
}

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

【 参考にしたページ、書籍 】
InDesign者のための正規表現入門 (市川せうぞー著)
名もないテクノ手 数字を3桁づつカンマ区切りにする
InDesign CS5自動化作戦 with JavaScript

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