InDesign_Script-文字框排序(CS5)

InDesign_Script-文字框排序(CS5)

image

如上圖所示,文件中有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();
}

 

紀錄結果

image

 

備註1:需要注意的是,如果稿件是直稿(直書)的話,原則要稍作調整,也就是由右到左為優先原則,上到下為次要原則。核心函數稍微調整一下就行了。

座標順序紀錄結果

備註2:不用搜尋取文的原因是因為,本文範例中框內數字代表的是繪製出文字框的順序,若不以座標為順序依據,則結果可能是1==>2==>3==>4==>5

備註3:若使用者部分文字框已有錨定,或有文字串鍊情況下,應附加篩選函式;將錨定的文字框,及非串鍊開頭之文框排除之。錨定文框排除原因是因為,其不屬父框成員之一,在逐個父框取文過程中,判定取出即可。非串鍊開頭之文框排除是因為,取文通常會以Story為之,以避免溢文遮字現象,而串鍊文框,為同一Story,不排除會有重複取文的問題。

備註4:需非常清楚InDesign物件座標呈現方式,若不清楚,請參考 ”InDesign_Script-座標與調整文框大小” 文章。