InDesign_Script-文字框排序(CS5)
如上圖所示,文件中有5個文字框,希望能依照座標順序,由上到下,由左到右。
應用上,比如說今天使用者要求文件上的文字取出,但是應比照文字框出現順序,但是又沒做錨定。最優先原則為上到下,若有相同者再由左到右。
因此結果應該是,2==>1==>5==>3==>4
主程式碼
var tfAry = new Array ();
for( var v1=0 ; v1<inDoc.textFrames.length ; v1++ )
{
var inTf = inDoc.textFrames[v1];
tfAry.push (inTf); //取得文件上所有文字框
}
var newTfAry = new Array();
newTfAry = sortTextFramesH(tfAry); //排序文字框
var s = "";
for( var v2=0 ; v2<newTfAry.length ; v2++ ) //記錄所有文字框
{
s += newTfAry[v2].geometricBounds[0] + "\t"; // y1
s += newTfAry[v2].geometricBounds[1] + "\n\r"; // x1
}
//紀錄寫入檔案
writeStrToFile( s , "E:\\log.txt" );
呼叫的函數
1.這是最關鍵的核心函式,負責排序文字框
function sortTextFramesH( tfObjs ){
if( tfObjs.length == 0 ){ return null; }
var tmpAry = new Array();
// 先排 Y 軸
for( var v1=0 ; v1<tfObjs.length ; v1++ ){
tmpAry[v1] = {};
tmpAry[v1].txt = tfObjs[v1].geometricBounds[0];
tmpAry[v1].val = tfObjs[v1];
}
var tfAry_OrderY = tmpAry.sort( function(a,b){ return b.txt-a.txt; } ); // Y 軸重新排序後結果
// 再排 X 軸
var nowY = tfAry_OrderY[0].val.geometricBounds[0]; // 紀錄最新 y1
var tfAry_OrderX = new Array(); // 擺 X 排序後新結果
var sameOfy = new Array(); // 放 Y 相同物件
for( var v2=0 ; v2<tfAry_OrderY.length ; v2++ ){
if( tfAry_OrderY[v2].val.geometricBounds[0]!=nowY ){ // Y 不同
// 排 X
sameOfy = sameOfy.sort( function(a,b){ return a.txt-b.txt; } );
// 重置前 將已佇列的元素寫入新陣列
for( var v3=0 ; v3<sameOfy.length ; v3++ ){
// 寫回是帶 y1 回去
tfAry_OrderX.push( {txt:sameOfy[v3].val.geometricBounds[0] , val:sameOfy[v3].val} );
}
nowY = tfAry_OrderY[v2].val.geometricBounds[0] // 重新登記 目前 Y
// 重置陣列
sameOfy = new Array();
sameOfy[0] = {};
sameOfy[0].txt = tfAry_OrderY[v2].val.geometricBounds[0]; // 登記 y1 位置
sameOfy[0].val = tfAry_OrderY[v2].val;
}
else{ // Y 相同
var num = sameOfy.length;
sameOfy[num] = {};
sameOfy[num].txt = tfAry_OrderY[v2].val.geometricBounds[0];
sameOfy[num].val = tfAry_OrderY[v2].val;
}
}
// 最後一次的 sameOfx 要補入陣列
sameOfy = new Array();
sameOfy = sameOfy.sort ( function(a,b){ return a.txt-b.txt; } );
// 帶入新陣列
for( var v3=0 ; v3<sameOfy.length ; v3++ ){
tfAry_OrderY.push( {txt:sameOfy[v3].val.geometricBounds[0] , val:sameOfy[v3].val} );
}
//alert( tfAry_OrderY );
// 轉回單值陣列
var resultAry = new Array();
for( var v4=0 ; v4<tfAry_OrderY.length ; v4++ ){
resultAry.push( tfAry_OrderY[v4].val );
}
//alert( resultAry.length );
return resultAry;
}
2.把字串寫入檔案,為方便記錄觀察結果用而已。
function writeStrToFile( str , filePathStr ){
var txtFile = new File (filePathStr);
txtFile.open("w");
if( str!=null ){
txtFile.write ( str.toString() );
}else{
txtFile.write ( "NULL" );
}
txtFile.close();
}
紀錄結果
備註1:需要注意的是,如果稿件是直稿(直書)的話,原則要稍作調整,也就是由右到左為優先原則,上到下為次要原則。核心函數稍微調整一下就行了。
座標順序紀錄結果
備註2:不用搜尋取文的原因是因為,本文範例中框內數字代表的是繪製出文字框的順序,若不以座標為順序依據,則結果可能是1==>2==>3==>4==>5
備註3:若使用者部分文字框已有錨定,或有文字串鍊情況下,應附加篩選函式;將錨定的文字框,及非串鍊開頭之文框排除之。錨定文框排除原因是因為,其不屬父框成員之一,在逐個父框取文過程中,判定取出即可。非串鍊開頭之文框排除是因為,取文通常會以Story為之,以避免溢文遮字現象,而串鍊文框,為同一Story,不排除會有重複取文的問題。
備註4:需非常清楚InDesign物件座標呈現方式,若不清楚,請參考 ”InDesign_Script-座標與調整文框大小” 文章。