Monday, July 12, 2010 / InDesign, DTP

ExtendScript 自前の相互参照の作成その3 ... 相互参照を更新する/元に戻す

自前の相互参照の作成その1自前の相互参照の作成その2 で相互参照の準備ができているので、いよいよ相互参照を更新します。

相互参照を更新 updateXref.jsx

xref_test.indd をアクティブドキュメントにした状態で実行。

  • 注意1) 相互参照ソースファイルは /Users/foo/xref_src.indd に決めうち(必要ならソースを書きかえて対応)

  • 注意2) タグ付きテキストを使用して更新するため、タグ付きテキストの制約(たとえば画像が扱えないなど)を受ける点に注意。

    // // 相互参照を更新する. // InDesign CS5 //

    var HOME_DIR="/Users/foo"; var TAGGED_TEXT_FILE = new File(HOME_DIR+"/_tmp.txt");

    function exportTaggedText( outputfile ,xref_id ){ function getTf( doc, xref_id ){ var r = null;

          for( var i=0; i<doc.textFrames.length; i++ ){
              var tf = doc.textFrames.item(i);
              if( tf.label ){
                  if( xref_id == tf.label ){
                      r = tf;
                  }
              }
          }
    
          return r;
      }
    
      function open(){
          var file = File(HOME_DIR+"/xref_src.indd");
          app.open( file );
          return app.activeDocument;
      }
      function close(doc){
          doc.close(SaveOptions.NO);
      }
    
      var doc = open();
      var tf = getTf( doc, xref_id );
      if( tf && tf.paragraphs.length>0){
          var myStory = tf.parentStory;
          myStory.exportFile(ExportFormat.taggedText,outputfile,false);
      }
      close(doc);
    

    }

    function getXrefList( doc ){ function parse( ele, list ){ if( ele.markupTag.name == "xref" ){ list.push( ele ); } for( var i=0; i<ele.xmlElements.length; i++ ){ var ele2 = ele.xmlElements.item(i); parse( ele2,list ); } }

      var list = new Array();
    
      // ルート要素を取得
      var eRoot = doc.xmlElements.itemByName("Root");
      parse( eRoot,list );
    
      return list;
    

    }

    function updateXref( doc, eXref ){ var end = eXref.characters.length-1; eXref.characters.itemByRange(0,end).place( TAGGED_TEXT_FILE,false);

      // 不要な改行を削除
      var start = eXref.characters.length-1;
      var end = eXref.characters.length-1;
      eXref.characters.itemByRange(start,end).remove();
    

    }

    function getId( eXref ){ var attrs=eXref.xmlAttributes; if( attrs.itemByName("id") ){ var xref_id = attrs.itemByName("id").value; return xref_id; } return null; }

    var doc = app.activeDocument; var xrefList = getXrefList( doc ); for( var i=0; i<xrefList.length; i++){ var eXref = xrefList[i]; var xref_id = getId( eXref ); if( xref_id ){ exportTaggedText( TAGGED_TEXT_FILE,xref_id );

          // 該当位置に相互参照ソースを配置
          updateXref( doc, eXref );
      }
    

    }

相互参照を元に戻す revertXref.jsx

更新したら逆にもとの状態に戻したいことがあります。そのときに使用する ExtendScript 。

//
// 相互参照を元に戻す.
// InDesign CS5
//

function getXrefList( doc ){
    function parse( ele, list ){
        if( ele.markupTag.name == "xref" ){
            list.push( ele );
        }
        for( var i=0; i<ele.xmlElements.length; i++ ){
            var ele2 = ele.xmlElements.item(i);
            parse( ele2,list );
        }
    }

    var list = new Array();

    // ルート要素を取得
    var eRoot = doc.xmlElements.itemByName("Root");
    parse( eRoot,list );
    return list;
}

function revertXref( doc,eXref ){
    var xref_id = getId( eXref );
    if( xref_id ){
        var end = eXref.characters.length-1;
        eXref.characters.itemByRange(0,end).contents = "{xref:"+xref_id+"}" ;
    }
}

function stripTag( doc ){
    function removeAttrs(eRoot){
        var attrs=eRoot.xmlAttributes;
        for( var i=0; i<attrs.count(); i++){
            attrs[i].remove();
        }
    }

    var eRoot = doc.xmlElements.itemByName("Root");
    while( eRoot.xmlAttributes.count() >0 ){
        removeAttrs(eRoot);
    }
    while(eRoot.xmlElements.length>0){
        var eles=eRoot.xmlElements;
        for( var j=0; j<eles.length; j++){
            eles[j].untag();
        }
        //doUntag( eles );
    }
}

function getId( eXref ){
    var attrs=eXref.xmlAttributes;
    if( attrs.itemByName("id") ){
        var xref_id = attrs.itemByName("id").value;
        return xref_id;
    }
    return null;
}


var doc = app.activeDocument;
var xrefList = getXrefList( doc );
for( var i=0; i<xrefList.length; i++){
    var eXref = xrefList[i];

    // 元の相互参照記述に戻す
    revertXref( doc, eXref );
}

// XML構造の初期化
stripTag(doc);