コモノExtendScript100本ノック

超初心者のDTPオペレーターが週にひとつスクリプトを書くブログ

047.【ID】左上→右下の順にテキスト書き出し

書いたコード

var main = function () {
  var tmp = [];
  var doc = app.activeDocument;
  // 準備
  // アイテムをオーバーライド
  for (var i = 0; i < doc.pages.length; i++) {
    for (var j = 0; j < doc.pages[i].masterPageItems.length; j++) {
      doc.pages[i].masterPageItems[j].override(doc.pages[i])
    }
  }
  // テキスト変数をテキスト化
  doc.textVariables.everyItem().convertToText(); // テキスト変数をテキスト化
  // 箇条書きをテキスト化
  doc.stories.everyItem().convertBulletsAndNumberingToText();
  // 現在のページ番号をテキスト化
  var marker1 = myFindText("^N");
  for (var i = 0; i < marker1.length; i++) {
    var ttt = marker1[i].contents
    marker1[i].contents = marker1[i].parentTextFrames[0].parentPage.name;
  }
  // 次のページ番号をテキスト化
  var marker2 = myFindText("^X");
  for (var i = 0; i < marker2.length; i++) {
    marker2[i].contents = marker2[i].parentTextFrames[0].nextTextFrame.parentPage.name;
  }

  // 前のページ番号をテキスト化
  var marker3 = myFindText("^V");
  for (var i = 0; i < marker3.length; i++) {
    marker3[i].contents = marker3[i].parentTextFrames[0].previousTextFrame.parentPage.name;
  }
  // セクションマーカーをテキスト化
  var marker4 = myFindText("^x");
  for (var i = 0; i < marker4.length; i++) {
    marker4[i].contents = marker4[i].parentTextFrames[0].parentPage.appliedSection.marker;
  }

  var tf = doc.pages[0].textFrames;
  for (var j = 0; j < tf.length; j++) {
    if (tf[j].textFrameIndex === 0) { // story内のid
      var coords = tf[j].geometricBounds;
      tmp.push([
        [coords[0] * 100000] + coords[1], tf[j].parentStory
      ])
    }
  }
  tmp.sort(compareNumbers);
  var log = [];
  for (var k = 0; k < tmp.length; k++) {
    log.push(tmp[k][1].contents);
  }
  log = log.join("\r");
  var logFile = "~/Desktop/log.txt"
  writeTxt(logFile, log);


  function compareNumbers(a, b) {
    return a[0] - b[0];
  }

  function writeTxt(path, txt) {
    var fObj = new File(path);
    fObj.encoding = "UTF-8";
    if (fObj.open("w")) {
      fObj.write(txt);
      fObj.close();
      return fObj;
    } else {
      alert("ファイルに書き込みできません\n" + path);
    }
  }

  function myFindText(str) {
    app.findTextPreferences = NothingEnum.NOTHING;
    app.findTextPreferences.findWhat = str;
    var result = app.findText();
    app.findTextPreferences = NothingEnum.NOTHING;
    return result;
  }
}

app.doScript(main, ScriptLanguage.JAVASCRIPT, [], UndoModes.FAST_ENTIRE_SCRIPT);
app.undo();

メモ

以前からこういうスクリプトを書きたかったのだけど、ものすごくめんどくさいやり方しか思い浮かばなくて先延ばしにしていた。
InDesign自動化サンプルプログラム逆引きリファレンス』にすごくスマートなやり方が載っていたので、位置の取得・ソートの処理のアイデアをお借りしたのがこれ。

分かったこと

  • textFrameIndex:textFrameのparentStory内でのid。
  • nextTextFrame/previousTextFrame:連結した次の/前のtextFrame。無い場合はnull。
  • charaterオブジェクトのparentTextFramesは配列(?)。

積み残し

  • 多分脚注番号とかテキスト化しなくてはいけないものが他にも色々ある。
  • アイテムをオーバーライドさせるところをもう少しすっきりさせられそう?

参考

(以下は参考にしようと思って以前控えておいたサイト。結局今回は別のやり方にしたけれどめちゃくちゃ面白い)