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);