ブログトップ 記事一覧 ログイン 無料ブログ開設

文書遊戯 このページをアンテナに追加 RSSフィード Twitter

2010-12-11

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

| 00:48 | 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

【 免 責 】

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

文書の見た目の美しさを捨てられるか

| 11:15 | 文書の見た目の美しさを捨てられるかを含むブックマーク

印刷の仕事をしていると、Wordで原稿が入稿されることがよくあります。Wordの原稿をInDesignで組み直す場合が多いのですが、ものによってはWordの原稿をそのまま印刷する場合もあります。

Word原稿をそのまま印刷する場合は、スタイルを定義したWordテンプレートを作っておき、標準化されたレイアウトスタイルの文書を作成するのが理想だと思います。実際に、スタイルを定義したWordテンプレートをクライアントに提供したこともあります。しかし、定義してあるスタイルだけを使って、クライアントがWord文書を編集することはまずありません。行末の切れ目が気に入らない、インデントの位置が気に入らない、行を1行に収めたい等々の理由で、定義したスタイルを無視したレイアウトを行ってきます。つまり、クライアントは標準化されたそれなりのレイアウトスタイルより、個別に調整された美しいレイアウトスタイルを求めているわけです。

ここまで印刷屋さんの仕事の話をしましたが、DITAを始めとするXML文書の導入でも同じことが問題になります。XML文書はソフトウェアによってPDFやHTML、ヘルプを自動生成するので、生成される文書のレイアウトスタイルが美しくなるように、個別に微調整を行うことができません。もっとも、HTMLやヘルプはもともとレイアウトスタイルについてルーズなので、これらが問題になることはありません。問題はPDF出力です。

PDF出力、すなわち紙での見た目の美しさを捨てられないのであれば、XML文書を導入しない方がよいでしょう。どうにかする方法の1つに、FrameMakerのようなXMLの入出力が行えるDTPを導入する、という手段があります。私は、この手は使わない方がよいと思っています。なぜなら、先のWordの例であったように、文書を編集する上で「するべきではないこと」が「できてしまう」からです。文書を作成する人は、常に美しいレイアウトスタイルで文書を完成させたいと思っているのです。

見た目の美しさを捨てて、何が得たいのか?これをハッキリさせることがXML文書導入のポイントで、各自よく考えなければいけないことだと思います。単にXML文書を導入したから、

  • 文書作成のコストが下がる
  • 文書作成のTATが短くなる
  • 文書の品質が上がる
  • 文書翻訳のコストが下がる
  • 文書翻訳のTATが短くなる
  • 文書翻訳の品質が上がる

というようなことはあり得ません。例えば上記のようなことを実現するために、XMLをうまく活用する手立てを考えなければいけません。目的を明確にし、その実現方法を考える。あたり前のことですが、これをしっかりやっておかないと、XML文書導入は失敗してしまいます。

みまみまみまみま 2011/09/06 14:39 はじめまして。このスクリプトに出会って助かりました。
何しろ、作ってくださっている皆々様に
「おんぶに抱っこ」の状態ですので。
コメントを残そうと思ったのは
【 動作確認 】Windows7 x64, InDesign CS4
となっておりましたので
MacOS X 10.5.8, InDesign CS4で動作確認できましたことを
お知らせしようと思いました。
選択範囲から実行できるのも嬉しい限りです。
ありがとうございます/

ditahackditahack 2011/09/06 22:05 みまみまさん、コメントありがとうございます。
励みになります。