Hatena::ブログ(Diary)

名もないテクノ手 このページをアンテナに追加 RSSフィード Twitter

EPUB版『InDesign者のための正規表現入門』

InDesignのTips一覧

2009-04-24

[][][]選択している2つのページアイテムの位置を入れ替える「swap_items.jsx 0.2」

何をするスクリプトか?

選択している2つのページアイテムの位置を入れ替えます。

簡単な使い方説明:

D


同梱ファイル3Files

  • Readme.txt このファイルです。とにかく最初によんでください。
  • swap_items.jsx スクリプト本体です。
  • swap_items_GUI_setting.jsx 環境設定のためのスクリプト。

使用条件

このスクリプトが正常に動作する環境は以下の通りです。Windows環境でも動作する可能性がありますが未検証です。

  • MacOS X10.5.8
  • InDesign CS4_J(6.0.3)

ダウンロード

http://www.seuzo.jp/st/scripts_InDesignCS4/index.html#swap_items


インストール

「swap_items.jsx」と「swap_items_GUI_setting.jsx」を

/Applications/Adobe InDesign CS4/Scripts/Scripts Panel/

または

~/Library/Preferences/Adobe InDesign/Version 6.0-J/Scripts/Scripts Panel/

にコピーしてください。エイリアスを入れておくだけでもかまいません。

スクリプトパレットから使用します。

「swap_items.jsx」と「swap_items_GUI_setting.jsx」は同じフォルダ階層に置いておいてください。

「swap_items.jsx」の名前を変更する場合は、「swap_items_GUI_setting.jsx」の18行目あたりにある

const TARGET_FILE_NAME = "swap_items.jsx";

でスクリプト名を編集してください。



使用方法

  1. 「ウインドウ」メニューから「スクリプティング」ー「スクリプト」を選択し、スクリプトパレットを出します。
  2. ページアイテムを2つ選択します。
  3. スクリプトパレットから、スクリプト「swap_items.jsx」をダブルクリックします。ショートカットを割り当てておくとさらに便利。

設定

スクリプトパレットから「swap_items_GUI_setting.jsx」をダブルクリックしてください。

「アイテムの移動基準点」ポップアップから「left-top」「right-top」「left-bottom」「right-bottom」のいずれかを選んでください。例えば「left-top」を選ぶと、それぞれのアイテムの左上を移動基準点として認識します。

「オブジェクトの重なり順序(階層)を入れ替える」チェックボックスにチェックを入れると、異動先のアイテムが持っていたオブジェクトの重なり順(アレンジ)を入れ替えるようになります。たくさんのページアイテムを持つページ上でこのチェックを有効にすると、処理が遅くなる可能性があります。

「レイヤーを入れ替える」チェックボックスにチェックを入れると、それぞれの所属レイヤーを入れ替えるようになります。

「swap_items_GUI_setting.jsx」はスクリプト「swap_items.jsx」そのものを書き換えます。そのため、まれに「swap_items.jsx」が破損することがあります。そのような場合は再度ダウンロードしてください。


既知の不具合、またはToDo


免責事項

  • 本アプリケーションはInDesignにおける作業効率支援なのであって、処理結果を保証するものではありません。かならず確認をされることをおすすめします。
  • このツールを使用する上でデータの破損などのあらゆる不具合・不利益については一切の責任を負いかねますのでご了解ください。
  • このツールはすべてのMacintoshMac OS上で動作をするという確認をとっていませんし、事実上出来ません。したがって、動作を保証するものではありません。

ライセンス

GNU GPLv3

http://sourceforge.jp/projects/opensource/wiki/licenses%252FGNU_General_Public_License_version_3.0


履 歴

2007-03-18 ver.0.1 とりあえず。「replace_items.jsx」「replace_items_GUI_setting.jsx」という名前でリリース。選択している2つのページアイテムの位置を入れ替え - 名もないテクノ手

2009-04-24 ver.0.2 InDesign CS4対応。「swap_items.jsx」「swap_items_GUI_setting.jsx」という名前に変更。スプレッドが回転表示しているときは、処理を中止するようにした。ページアイテムの重なり順を正しく動作するように修正した。

2009-04-24 ver.0.2.1 ダイアログを出す前にUserInteractionLevels.interactWithAllとした。

2009-08-21 ver.0.2.2 右綴じの時、スプレッドの回転を誤認識するバグを改善。


ソースコード

swap_items.jsx
/*
replace_items.jsx
(c)2008 www.seuzo.jp
選択している2つのページアイテムの位置を入れ替えます。

・History
2007-03-18	ver.0.1	とりあえず。「replace_items.jsx」「replace_items_GUI_setting.jsx」という名前でリリース。[http://d.hatena.ne.jp/seuzo/20080316/1205641922:title=選択している2つのページアイテムの位置を入れ替え - 名もないテクノ手]
2009-04-24	ver.0.2	InDesign CS4対応。「swap_items.jsx」「swap_items_GUI_setting.jsx」という名前に変更。スプレッドが回転表示しているときは、処理を中止するようにした。ページアイテムの重なり順を正しく動作するように修正した。
2009-08-21	ver.0.2.2	右綴じの時、スプレッドの回転を誤認識するバグを改善。
*/


////////////////////////////////////////////設定
const my_position = "left-top"; //オブジェクト揃え原点(left-top, right-top, left-bottom, right-bottom)
const my_replace_index = false; //オブジェクトの重なり順序(階層)も入れ替えるかどうか
const my_replace_layer = false; //レイヤーも入れ替えるかどうか



////////////////////////////////////////////エラー処理 
function myerror(mess) { 
  if (arguments.length > 0) { alert(mess); }
  exit();
}

////////////////////////////////////////////スプレッドの回転角度を調べる (1スプレッド2ページまで対応)
function get_spread_angle(spread_obj) {
	var my_document, my_old_ruler_origin, my_old_zeroPoint, my_page, my_page_bounds, my_angle, migitoji, i;
	my_document = app.activeDocument;
	my_old_ruler_origin = false;//
	if (my_document.viewPreferences.rulerOrigin !== 1380143215) {//not page
		my_old_ruler_origin = my_document.viewPreferences.rulerOrigin;//current setting
		my_document.viewPreferences.rulerOrigin = 1380143215;//change ルーラーをページに
	}
	my_old_zeroPoint = false;
	if (my_document.zeroPoint !== [0, 0]) {
		my_old_zeroPoint = my_document.zeroPoint;
		my_document.zeroPoint = [0,0];
	}

	my_page = spread_obj.pages[0];
	my_page_bounds = my_page.bounds;
	migitoji = 0;//右綴じかどうかのカウンター。migitoji===1なら右綴じの見開き
	for (i = 0; i< my_page_bounds.length; i++) {
		if (my_page_bounds[i] === 0) {migitoji++}
	}
	if (migitoji === 1) {//右綴じの見開きは右ページ基点
		my_page = spread_obj.pages[1];
		my_page_bounds = my_page.bounds;
	}

	my_angle = -1;
	if((my_page_bounds[0] === 0) && (my_page_bounds[1] === 0)) {
		my_angle = 0;
	} else if ((my_page_bounds[0] === 0) && (my_page_bounds[3] === 0)) {
		my_angle = 90;
	} else if ((my_page_bounds[2] === 0) && (my_page_bounds[3] === 0)) {
		my_angle = 180;
	} else if ((my_page_bounds[1] === 0) && (my_page_bounds[2] === 0)) {
		my_angle = 270;
	}

	if(my_old_ruler_origin) {my_document.viewPreferences.rulerOrigin = my_old_ruler_origin}
	if(my_old_zeroPoint) {my_document.zeroPoint = my_old_zeroPoint}
	return my_angle;
}

////////////////////////////////////////////オブジェクトの座標と幅、高さを得る 
function get_bounds(my_obj) {
	var tmp_hash = new Array();
	var my_obj_bounds = my_obj.visibleBounds; //オブジェクトの大きさ(線幅を含む)
	tmp_hash["y1"] = my_obj_bounds[0];
	tmp_hash["x1"] = my_obj_bounds[1];
	tmp_hash["y2"] = my_obj_bounds[2];
	tmp_hash["x2"] = my_obj_bounds[3];
	tmp_hash["w"] = tmp_hash["x2"] - tmp_hash["x1"]; //幅
	tmp_hash["h"] = tmp_hash["y2"] - tmp_hash["y1"]; //高さ
	return tmp_hash; //ハッシュで値を返す
}

////////////////////////////////////////////与えられたオブジェクトのレイヤー内かつスプレッド内の重なり順を得る
//results  [Layer, pageItems, index]
function get_stackindex_in_layer(my_pageitem_obj) {
	var my_layer = my_pageitem_obj.itemLayer;
	var my_spread = my_pageitem_obj.parent.parent;//pageItem's parent is Page, Page's parent is Spread.
	var my_items = my_spread.pageItems.everyItem().getElements().slice(0);
	var tmp_array = new Array();
	for (var i = 0; i < my_items.length; i++) {
		if (my_items[i].itemLayer == my_layer) {
			tmp_array.push(my_items[i]);
		}
	}
	var tmp_index = -1;//if return -1 is error.
	for (var j = 0; j < tmp_array.length; j++) {
		if (tmp_array[j] == my_pageitem_obj) {tmp_index = j; break;}
	}
	return [my_layer, tmp_array, tmp_index];
}


////////////////////////////////////////////オブジェクトの階層順を変える(最前面は0)
function change_index(my_obj, my_index) {
	my_obj.bringToFront();//まず最前面にする
	//my_indexの回数分、my_objを背面に送る
	for (var i = 0; i < my_index; i++) {
		my_obj.sendBackward();
	}
}

			

////////////////////////////////////////////以下実行ルーチン
if (app.documents.length == 0) {myerror("ドキュメントが開かれていません")}
var my_document = app.activeDocument;
var my_selection = my_document.selection;
if (my_selection.length != 2) {myerror("2つのオブジェクトを選択してください")}

//スプレッドが回転していたら、エラーで中止。ver6.0(InDesign CS4)以上
if (parseInt(app.version) <= 6) {
	var my_spread = app.layoutWindows[0].activeSpread;
	if (get_spread_angle(my_spread) != 0) {myerror("スプレッドが回転しています。元に戻してから実行してください。")};
}

//オブジェクト種類の検査
for(var i = 0; i < my_selection.length; i++) {
	if (!("Rectangle, Group, Oval, Polygon, TextFrame".match(my_selection[i].reflect.name))) {
		 myerror("ページアイテムを選択してください");
	}
	if (my_selection[i].locked) {
		myerror("ページアイテムがロックされています");
	}
	if (my_selection[i].parent.reflect.name != "Page") {
		myerror("独立したページアイテムを選んでください");
	}
}
var my_obj_A = my_selection[0];
var my_obj_B = my_selection[1];

//ページルーラーの開始位置が「スプレッド」以外になっていたら、「スプレッド」に一時的に変更
var my_ruler_origin = false;//初期値はfalse
if (my_document.viewPreferences.rulerOrigin != 1380143983) {
	my_ruler_origin = my_document.viewPreferences.rulerOrigin;//現在の設定を保存
	my_document.viewPreferences.rulerOrigin = 1380143983;//「スプレッド」に一時的に変更
}
	
//オブジェクトの大きさ(線幅を含む)
var my_bounds_A = get_bounds(my_obj_A);
var my_bounds_B = get_bounds(my_obj_B);

//位置の入れ替え
//obj.move([x1, y1])
if (my_position == "left-top") {
	my_obj_A.move([my_bounds_B["x1"], my_bounds_B["y1"]]);
	my_obj_B.move([my_bounds_A["x1"], my_bounds_A["y1"]]);
} else if (my_position == "right-top") {
	my_obj_A.move([my_bounds_B["x2"] - my_bounds_A["w"], my_bounds_B["y1"]]);
	my_obj_B.move([my_bounds_A["x2"] - my_bounds_B["w"], my_bounds_A["y1"]]);
} else if (my_position == "left-bottom") {
	my_obj_A.move([my_bounds_B["x1"], my_bounds_B["y2"] - my_bounds_A["h"]]);
	my_obj_B.move([my_bounds_A["x1"], my_bounds_A["y2"] - my_bounds_B["h"]]);
} else if (my_position == "right-bottom") {
	my_obj_A.move([my_bounds_B["x2"] - my_bounds_A["w"], my_bounds_B["y2"] - my_bounds_A["h"]]);
	my_obj_B.move([my_bounds_A["x2"] - my_bounds_B["w"], my_bounds_A["y2"] - my_bounds_B["h"]]);
}

//ページルーラー設定の復帰
if (my_ruler_origin) {
	my_document.viewPreferences.rulerOrigin = my_ruler_origin;
}

//レイヤーの入れ替え
if (my_replace_layer) {
	var tmp_layer_A = my_obj_A.itemLayer;
	var tmp_layer_B = my_obj_B.itemLayer;
	my_obj_A.itemLayer = tmp_layer_B;
	my_obj_B.itemLayer = tmp_layer_A;
}

//オブジェクトの重なり順序(階層)を入れ替え
if (my_replace_index) {
	var my_index_A = get_stackindex_in_layer(my_obj_A);
	var my_index_B = get_stackindex_in_layer(my_obj_B);
	if (my_index_A[0] != my_index_B[0]) {myerror("異なるレイヤーのオブジェクトは重なり順を入れ替えできません。重なり順は変更しないで終了します。")}
	change_index(my_obj_A, my_index_B[2]);
	change_index(my_obj_B, my_index_A[2]);
}

swap_items_GUI_setting.jsx
/*
swap_items_GUI_setting.jsx
(c)2008 www.seuzo.jp
swap_itemsのための環境設定GUI
「swap_items.jsx」と同じ階層に置いておく必要があります。


・History
2008-03-18	ver.0.1	とりあえず。「replace_items_GUI_setting.jsx」という名前でリリース
*/

////////////////////////////////////////////設定
const TARGET_FILE_NAME = "swap_items.jsx"; //書き換えるスクリプト名

////////////////////////////////////////////エラー処理 
function myerror(mess) { 
  if (arguments.length > 0) { alert(mess); }
  exit();
}

////////////////////////////////////////////カレントスクリプトのフルパスを得る 
function get_my_script_path() {
	try {
		return  app.activeScript;
	} catch (myError) {
		return File (myError.fileName);
	}
}

////////////////////////////////////////////ファイルの内容を読み込んで返す 
function read_file(my_read_file_path) {
	var my_file_obj = new File(my_read_file_path);
	if (!(my_file_obj.exists)) {myerror("ファイルがありません\n" + my_read_file_path)};
	if(my_file_obj.open("r")) {
		var tmp_str = my_file_obj.read();
		my_file_obj.close();
	} else {
		myerror("ファイルが開けません\n" + my_read_file_path);
	}
	return tmp_str;
}

////////////////////////////////////////////データをファイルに書き込む 
function write_file(my_write_file_path, my_data) {
	var my_file_obj = new File(my_write_file_path);
	//if (!(my_file_obj.exists)) {myerror("ファイルがありません\n" + my_write_file_path)};
	if(my_file_obj.open("w")) {
		my_file_obj.write(my_data);
		my_file_obj.close();
	} else {
		myerror("ファイルが開けません\n" + my_write_file_path);
	}
}

////////////////////////////////////////////リスト内を正規表現検索してindexを得る。 ヒットしなければfalseを返す
function search_index_list(my_list, search_regex) {
	var search_regex = RegExp(search_regex);
	var search_result = false;
	for (var i = 0; i < my_list.length; i++) {
		if (my_list[i].match(search_regex)) {
			search_result = i;
			break;
		}
	}
	return search_result;
}

////////////////////////////////////////////引数strが "true" または "false" の時のみ真偽値を返す
function str2boolean (str) {
	var str ;
	if ((str === "true") || (str === "false")) {
		return eval(str);
	} else {
		//alert(str + " is not boolean.");
		myerror("プログラムが壊れています。\n" + str + " is not boolean.");
	}
}





////////////////////////////////////////////以下実行ルーチン
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
var my_script_path = get_my_script_path();//このスクリプトのフルパス名
var my_script_folder = File (my_script_path).parent;//コンテナフォルダ
var my_file_path = my_script_folder + "/" + TARGET_FILE_NAME;//ターゲットのファイルパス
var my_str = read_file(my_file_path);//内容を得る

//現在の設定を得る
my_str.match (/^(const my_position ?= ?")([^"]+)/im);
var my_position = RegExp.$2;
my_str.match (/^(const my_replace_index ?= ?)([^; ]+)/im);
var my_replace_index = RegExp.$2;
my_str.match (/^(const my_replace_layer ?= ?)([^; ]+)/im);
var my_replace_layer = RegExp.$2;

//設定のチェック
var my_position_list = ["left-top", "right-top", "left-bottom", "right-bottom"];
var my_position_index = search_index_list(my_position_list, my_position);
if (my_position_index === false) {myerror("プログラムが壊れています。Not search index of position list.")}
my_replace_index = str2boolean(my_replace_index);
my_replace_layer = str2boolean(my_replace_layer);


////////////////ダイアログ
var my_dialog = app.dialogs.add({name:"swap_items環境設定", canCancel:true});
with(my_dialog) {
	with(dialogColumns.add()) {
		//staticTexts.add({staticLabel:"swap_itemsの設定をしてください"});// プロンプト
		with(borderPanels.add()) {
			with(dialogColumns.add()){
				staticTexts.add({staticLabel:"アイテムの移動基準点:"});
				var my_popup = dropdowns.add({stringList:my_position_list, selectedIndex:my_position_index});// ポップアップメニュー
			}
		}
		with (borderPanels.add()) {
			with(dialogRows.add()){
				var check_01 = checkboxControls.add({staticLabel:"オブジェクトの重なり順序(階層)を入れ替える", checkedState:my_replace_index});
			}
			with(dialogRows.add()){
				var check_02 = checkboxControls.add({staticLabel:"レイヤーを入れ替える", checkedState:my_replace_layer});
			}
		}
	}
}
//ダイアログの結果を得る
if (my_dialog.show() == true) {
	my_popup = my_popup.selectedIndex;
	my_position = my_position_list[my_popup];
	my_replace_index = check_01.checkedState;
	my_replace_layer = check_02.checkedState;
	//正常にダイアログを片付ける
	my_dialog.destroy();
} else {
	// ユーザが「キャンセル」をクリックしたので、メモリからダイアログボックスを削除
	my_dialog.destroy();
	myerror();
}


//設定の置換
my_str = my_str.replace (/^(const my_position ?= ?")([^" \s]+)/im, "$1" + my_position);
my_str = my_str.replace (/^(const my_replace_index ?= ?)([^; \s]+)/im, "$1" + my_replace_index);
my_str = my_str.replace (/^(const my_replace_layer ?= ?)([^; \s]+)/im, "$1" + my_replace_layer);

//ファイルの書き込み
write_file(my_file_path, my_str);

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証