JavaScriptの最近のブログ記事

前回の
とりあえずから実用へ(InDesignプロンプト版セル幅調整スクリプト)の続き
せっかくなので高さも調整できるようにしてみる。

setsizewithcals.png

/**
 *  cells size setter (with cals) 
 * 
 */
if(app.documents.length == 0 || app.selection.length == 0){exit();}

var cellColumn, cellRow;
selObj = app.selection[0];
switch(selObj.constructor.name){
	case "Table":
		cellColumn = selObj.columnCount;
		cellRow = selObj.bodyRowCount + selObj.headerRowCount + selObj.footerRowCount;
		break;
	case "Cell":
		cellColumn = selObj.columnSpan;
		cellRow = selObj.rowSpan;
		break;
	default :// TableとCell以外は無視
		alert("choose table or cells");
		break;
}
//結合セルも個別セルとして幅と高さを取得
var eachCellW = selObj.columns.everyItem().width;
var eachCellH = selObj.rows.everyItem().height;

//edittextの大きさ,パネルのマージンなどを設定
var editbox = {'w': 60, 'h': 20}; //edittextの大きさ
var startPt; //edittext作成の開始点
var pnlMargin = [10,10,10,15]; //パネルのマージン
var gutter = 5; //edittextの間隔
var wArr = [];
var hArr = [];

var dlg = new Window('dialog',"cells size setter",undefined);
dlg.pnl = dlg.add('panel',undefined);//サイズは仮

//幅用のedittext
startPt = [pnlMargin[0], pnlMargin[1]];
startPt[0] += editbox['w'] + gutter;//開始点を右にずらす

for (var ic=0; ic < cellColumn; ic++) {
	var wValue = dlg.pnl.add('edittext',[startPt[0], startPt[1], startPt[0]+editbox['w'], startPt[1]+editbox['h']],eachCellW[ic]);
	startPt[0] = startPt[0] + editbox['w'] + gutter;
	wArr.push(wValue);
}
var pnlW = startPt[0]+pnlMargin[2];//dlg.pnl width

//高さ用のedittext
startPt = [pnlMargin[0], pnlMargin[1]];
startPt[1] += editbox['h'] + gutter;//開始点を下にずらす

for (var ir=0; ir < cellRow; ir++) {
	var hValue = dlg.pnl.add('edittext',[startPt[0], startPt[1], startPt[0]+editbox['w'], startPt[1]+editbox['h']],eachCellH[ir]);
	startPt[1] = startPt[1] + editbox['h'] + gutter;
	hArr.push(hValue);
}
var pnlH = startPt[1]+pnlMargin[3];//dlg.pnl height

dlg.pnl.bounds = [0, 0, pnlW, pnlH];//パネルのサイズを設定

dlg.grp = dlg.add('group')
dlg.okButton = dlg.grp.add('button',undefined,'ok',{name: 'ok'});
dlg.cancelButton = dlg.grp.add('button',undefined,'cancel',{name: 'cancel'});

dlg.okButton.onClick = function(){
	dlg.close();
	flg = true;
}
dlg.cancelButton.onClick = function(){
	dlg.close();
	flg = false;
}
dlg.center();
dlg.show();

if(flg == true){
	for (var iw=0; iw < wArr.length; iw++) {
		if (eval(wArr[iw].text)*1 > 1) {
			selObj.columns[iw].width = eval(wArr[iw].text) * 1;
		}
	}
	for (var ih=0; ih < hArr.length; ih++) {
		if (eval(hArr[ih].text)*1 > 1) {
			selObj.rows[ih].height = eval(hArr[ih].text) * 1;
		}
	}
}

web系のスクリプトと違い、dtp系のスクリプトの場合とりあえず目の前の仕事をつぶすために動けばいいレベルのことが多いと思います。

例えばたくさんの表組のセル幅を不規則な値に設定しないといけない場合。
表パネルから数値入力していたら、セルを選択>数値入力>セル移動>数値入力...の繰り返し。
面倒なので簡単なスクリプトを書いて、後からいろいろと機能を追加してみる。

var selObj = app.selection[0];
var celObj = selObj.cells;
var currentW = celObj.everyItem().width;

var eachWPrompt = prompt(",で区切ったセル幅を入力",currentW);
if(eachWPrompt != undefined){
	for (var i=0, iL=celObj.length; i < iL ; i++) {
		celObj[i].width = eachWArr[i]*1;
	}
}
3分で書いて、こんなので乗り切ります。
tableprompt.png
処理のイメージできれば書き捨てなものの書出しはいつもこんな感じです。
使い方を気をつければ実用的に使えますが、これじゃあんまりなのでいじっていきます。

絵本みたいなのをジェネレートしたくて、
InDesignのサンプルテキスト割り付け機能を使ってランダムな文字列を生成、文字を変え、色を変え、半透明にして重ねてみた。
a9.jpg
それをページごとにjpeg書き出しして、またインラインオブジェクトとして読み込む。
html書出しをしてから少々検索置換でタグを変換してから、sigilに読み込みepub変換。
(こういう画像配置するようなパターンなら直接htmlで書いて読み込みした方が早い)

書き出されたjpegはこんな。文字化けも素材を活かします。
efon_images.png

できたepubはこんな(約11MB)。>>  efon.epub
なんて無駄なものができてしまったのだろう。

/**
 * creat textpat 
 * サンプルテキスト機能をつかったランダムテキストパターンの実験
 */

#target "InDesign"

var fon = app.fonts;
var draw_area = 50; //描写領域 50 x 50
var layered = 12; //レイヤー数
var page_len = 40; //ページ数 = パターンの数
var max_range = 36; //max size = min size(9) + max_range あまり大きすぎると描写領域に対してサンプルテキストが割り付けられない

var ma = [ //アプリケーションデフォルトのマージン
	app.marginPreferences.top,
	app.marginPreferences.left,
	app.marginPreferences.bottom,
	app.marginPreferences.right
	];
	
var doc = app.documents.add();
var ddp = doc.documentPreferences;
with(ddp){
	pageWidth = draw_area + ma[1] + ma[3];
	pageHeight = draw_area + ma[0] + ma[2];
	pagesPerDocument = page_len;
	facingPages = false;
}

var c, m, y;
try{
	c = doc.colors.add({
		model:ColorModel.PROCESS, 
		space:ColorSpace.CMYK, 
		colorValue:[100,0,0,0], 
		name:"C"});
}catch(e){c = doc.swatches.item('C');}
try{
	m = doc.colors.add({
		model:ColorModel.PROCESS, 
		space:ColorSpace.CMYK, 
		colorValue:[0,100,0,0], 
		name:"M"});
}catch(e){m = doc.swatches.item('C');}
try{
	y = doc.colors.add({
		model:ColorModel.PROCESS, 
		space:ColorSpace.CMYK, 
		colorValue:[0,0,100,0], 
		name:"Y"});
}catch(e){y = doc.swatches.item('C');}
var cmy = [c, m, y];

var tfBon = [ //マージン内にテキストフレームをつくる
	ma[0],
	ma[1],
	ma[0] + draw_area,
	ma[1] + draw_area
	];

for(var j=0; j < page_len; j++){
	for (var i=0; i < layered; i++) {
		var tf = doc.pages[j].textFrames.add({geometricBounds: tfBon });
		with(tf.parentStory){
			pointSize = 9 + ( max_range * Math.random() ) + "pt"; //(9 ~ 81 pt)
			leading = tf.parentStory.pointSize;
			
			try{
				appliedFont = fon[Math.floor(fon.length * Math.random())]
			}catch(e){}

			//line
			// strokeWeight = "0.3 pt";
			// strokeColor = cmy[Math.floor(cmy.length * 10 * Math.random() / 10)];
			// fillColor = "None";

			//fill
			strokeColor = "None";
			fillColor = cmy[Math.floor(cmy.length * Math.random() )];
		}
		//set dummy text
		tf.contents = TextFrameContents.placeholderText;//1346925688; 
		tf.transparencySettings.blendingSettings.blendMode = BlendMode.MULTIPLY;
		tf.transparencySettings.blendingSettings.opacity = 25;
	}
};
//デスクトップにフォルダを作成してその中に、InDesignドキュメントの各ページをjpeg書出し
exportJepgEachPage (doc);
//書き出したjpegをアンカー付きオブジェクトにして取り込み
placeAnchordImageToDoc (imgFolder);

function exportJepgEachPage (doc) {
	with(app.jpegExportPreferences){
		jpegExportRange = ExportRangeOrAllPages.EXPORT_ALL;
		jpegQuality = JPEGOptionsQuality.MAXIMUM;
		jpegRenderingStyle = JPEGOptionsFormat.BASELINE_ENCODING;
		resolution = 150;
		exportingSpread = false;
		}
	imgFolder = new Folder("~/Desktop/" + new Date().getTime());
	imgFolder.create();
	if(imgFolder){
		fileObj = new File (imgFolder + "/a" + ".jpg");//なにかprefixがないとdot fileの .jpgが生成されてしまう
		if(fileObj){
			doc.exportFile(ExportFormat.JPG, fileObj, false);
		}
	}
}

// doc.close(SaveOptions.NO);
function placeAnchordImageToDoc (impSrc) {
	var doc2 = app.documents.add();
	var tf2 = doc2.textFrames.add();
	var impSrc = imgFolder;
	var impSrc_fs = new File(impSrc).fsName;
	var impSrc_list = File(impSrc_fs).getFiles(
		function (file){ return /^[^\.]+\.jpg$/i.test(file.name)}
		);
	if(impSrc)
	for (var i=0; i < impSrc_list.length; i++) {
		var ob = tf2.parentStory.insertionPoints[-1].rectangles.add();
		tf2.parentStory.insertionPoints[-1].contents = "\n";
		ob.place(impSrc_list[i]);
		ob.anchoredObjectSettings.anchoredPosition = AnchorPosition.ANCHORED;
		ob.fit(FitOptions.FRAME_TO_CONTENT);
	};

}




のびのびと育ってほしいので、ScriptUIのダイアログをのびるようにしてみました。

ダイアログに表示する内容に合わせてサイズを可変させます。当然、項目が多すぎるとディスプレイからはみ出します。

stretch_dialog_input.png

おまけ、正規表現で設定した内容以外は頑として受け付けません。
sd_regex_alert.png
機能はあくまでサンプルなので実用的かどうかは別問題です。それ以前に、素直にResource Specificationsつかえばいいのに。って声が聞こえてきそう

20100726(Mon)1730頃:cancelButtonの記述がおかしかったのを修正
/**
 * のびのびダイアログ
 * コンテンツに応じてダイアログのサイズを可変させるサンプル
 * 機能:
 * InDesign のスウォッチとレイヤーの名前をリネームする
 */

var docObj = app.documents[0];
var swatchObj = unReservedSwatch(docObj);
var layObj = docObj.layers;

//create dialog
//dialogはpanelのサイズに合わせて自動調整
var dlg = new Window('dialog',"stretch dialog", undefined);
//swatch panel
dlg.panel = dlg.add('panel',[5,5,340,320],"Swaaaaaaaaaatch");
var sw_panelbon = dlg.panel.bounds;

var y1 = 0, swArr = [];
for (var isw=0; isw < swatchObj.length; isw++) {
	swatchObjName = dlg.panel.add('statictext', [20,20+y1,180,40+y1], ''+swatchObj[isw].name);
	swRenameName = dlg.panel.add('edittext', [180,20+y1,320,40+y1], '',{multiline: false});
	y1 += 25;
	swArr.push([swatchObjName, swRenameName]);
}
var py = y1 +35;
//panelのサイズを拡張のびーる
dlg.panel.bounds = [sw_panelbon[0], sw_panelbon[1], sw_panelbon[2], py];

var ly_panelbon = [5, py, 340, py +100];//swatchのパネルの下端から作成、高さはとりあえず100
//layer panel
dlg.panel2 = dlg.add('panel', ly_panelbon, "Layeeeeeeeeeeeer");

var y2 = 0, lyArr = [];
for (var ily=0; ily < layObj.length; ily++) {
	layObjName = dlg.panel2.add('statictext', [20,20+y2,180,40+y2], ''+layObj[ily].name);
	lyRenameName = dlg.panel2.add('edittext', [180,20+y2,320,40+y2], '',{multiline: false});
	y2 += 25;
	lyArr.push([layObjName, lyRenameName]);
	}
var py2 = y2 + 30;
//panel2のサイズを拡張のびーる
dlg.panel2.bounds = [ly_panelbon[0], ly_panelbon[1], ly_panelbon[2], ly_panelbon[1]+py2];

dlg.okButton = dlg.add('button',undefined,"ok",{name: 'ok'});
dlg.cancelButton = dlg.add('button',undefined,"cancel",{name: 'cancel'});

dlg.center();
var flg;
dlg.okButton.onClick = function(){
	flg = true
	dlg.close();	
}
dlg.cancelButton.onClick = function(){
	flg = false
	dlg.close();	
}

dlg.show();

if(flg == true){
	renameswatchObj(docObj, swArr);
	renamelayerObj(docObj, lyArr);
	}


/**
 * raname object (swatch)
 * @param {Object} doc Document
 * @param {Array} array ==> [object, string] 
 */
function renameswatchObj (doc, array) {
	for (var i=0; i < array.length; i++) {
		var stylename = array[i][0].text;
		var renamename = array[i][1].text;
		if(renamename.length > 0){
			var styleObj = doc.swatches.item(stylename);
			retryRename (styleObj, renamename); //Fnへ
			}
		}
}
/**
 * raname object (layer)
 * @param {Object} doc Document
 * @param {Array} array ==> [object, string] 
 */
function renamelayerObj (doc, array) {
	for (var i=0; i < array.length; i++) {
		var stylename = array[i][0].text;
		var renamename = array[i][1].text;
		if(renamename.length > 0){
			var styleObj = doc.layers.item(stylename);
			retryRename (styleObj, renamename); //Fnへ
			}
		}
}
/**
 * regex check and retry rename
 * @param {Object} obj such as Swatch, Layers, ParagraphStyles(exist name property object)
 * @param {String} string rename string
 */
function retryRename (obj, string) {
	//リネームの正規表現チェック
	var regexCheck = string.match(/^[A-Za-z][0-9A-Za-z_-]*/g);
	if(regexCheck != string){
		reg_retry = prompt("ルールにマッチしません",string);
		if(reg_retry){
			string = reg_retry;
			retryRename (obj, string);
			}
		else{exit();}
		}
	//リネームの重複チェック
	try{
		obj.name = string;
		}
	catch(e){
		var retry = prompt("変更前「"+obj.name+"」:\r名前は既にあります。変更して下さい。",string);	
		if(retry){
			retryRename(obj, retry);
			}
		else{exit();}
		}
	
}
/**
 * unreserved swatch
 * @param {Object} doc Document
 * @returns {Array} otherSw the return value 
 */
function unReservedSwatch(doc){
	var swObj = doc.swatches;
	var otherSw = new Array();
	if(swObj.length-4 > 0){
		for(var i=0; i < swObj.length; i++){
			switch(swObj[i].name){
				case "None":
				case "Paper":
				case "Black":
				case "Registration": break;
				default : 
					otherSw.push(swObj[i]);
					break;
				}
			}
		}
	return otherSw;
}

InDesignのスクリプト書きに慣れていると、たまにIllustrator用に書こうとするとえらい苦労をします。

今回は、Illustratorではページアイテムの取得したいのに入れ子のアイテムもひっくるめて全部返してくるので、選択ツール(黒い方)で選択したような戻り値を期待しても取得できないのに手間取ったのですが、達人たちはこんな時「選択アイテム限定」とすることで制御してるらいいのですが。
とりあえずグループアイテムを選択ツールで選択したときの数(app.selection.length)と同等のアイテムが取得できないものか試したときのメモ。

グループアイテムを何個かまとめてグループ化したもの
→groupItems.lengthだと入れ子たちもふくまれちゃう。
→これで一個になってほしい。

条件
  • 親がレイヤー
  • 子に何かしらのアイテムがある(一個でグループの場合も含む)
こんなのでいいのかな? 
groups_on_doc.png
result_of_group_check.png
トップレベルのグループアイテムを取得する。
#target "Illustrator"

var doc = app.documents[0];
var topG = getTopGroup(doc.groupItems);
alert("top level group:"+topG.length+ "\r" +
	"PageItems:" + doc.pageItems.length + "\r" +
	"PathItems:" + doc.pathItems.length + "\r" +
	"CompoundPathItems:" + doc.compoundPathItems.length + "\r" +
	"GroupItems:" + doc.groupItems.length + "\r" +
	"Selection:" + doc.selection.length);

/**
 * get top level group items
 * @param {Array} group Array of GroupItem
 * @returns {Array} tgr Array of top level GroupItem
 */
function getTopGroup (group) {
	var tgr=[];
	for (var i=0; i < group.length; i++) {
		//parent is Layer
		if(group[i].parent.typename == "Layer"){
			//group is formed with single path item
			if(group[i].pathItems.length == 1){
				tgr.push(group[i]);
			}
			//group is formed with compound path item
			if(group[i].compoundPathItems.length == 1){
				tgr.push(group[i]);
			}
			//group include any page items(textframe, pathitem)
			else if(group[i].pageItems.length != 0){
				tgr.push(group[i]);
				}
			}
		}
	return tgr;
}


ごめんなさい、懺悔します。

以前から一部の自前のスクリプトで何故かExtendScript Toolkitが勝手に立ち上がるときがあるなと思っていたのですが、最近はほとんどESTKを使わない日々が続き、今日やっと理由がわかりました。(今はTextMate使い)

ExtendScript のスクリプトの中に $.writeln( ) や $.write( ) がある(コメントアウトされていない)と
InDesignのScriptPanelなどのアプリケーションから実行しても、裏で ExtendScript Toolkit が勝手に起動してしまう(CS3だとESTK2がDOMのXMLをちくちく読み込みに行き、そしてXML読み込みに失敗する)ことになるのを知りました。


estk_xml.png

$.writeln( ), $.write( )はちゃんとコメントアウトします。反省。

//ESTKを立ち上げていない状態で
//アプリケーションから実行すると、ESTKが立ち上がってくれます。
$.writeln("Hello ESTK from backyard");


paraindesign.png 

InDesignで パラパラオブジェクトをつくる試み。
以前につくった「InDesign_選択オブジェクトをグリグリ、ゲジゲジ」スクリプトを時計風に加工してみました。現在の時刻を元にだいたいランダムなパラメーターを生成します。

スクリプトで300ページのゲジゲジ時計を生成します。
Flashでパラパラできます(parapara.swf)。PDFもパラパラできます。ePubはポリゴンオブジェクトの書出しがされないので残念ながらもうひと手間必要なようです。

//Indesign Just now
//裏処理で新規ドキュメントを作成します。
var doc = app.documents.add(false);

//ドキュメント設定
doc.documentPreferences.pageWidth = 150;
doc.documentPreferences.pageHeight = 150;
doc.documentPreferences.facingPages = false;
doc.documentPreferences.pagesPerDocument = 300; //1-9999
doc.viewPreferences.rulerOrigin = RulerOrigin.SPREAD_ORIGIN;

var dSize = Math.min(doc.documentPreferences.pageWidth, doc.documentPreferences.pageHeight);
var pageCount = doc.documentPreferences.pagesPerDocument
var pageObj = doc.pages;

//ドキュメントのページ数を設定して、その中でループさせる。
for (var pg = 0; pg < pageCount; pg++){
	var timeObj =  new Date();//いま!
	var h = timeObj.getHours();
	var m = timeObj.getMinutes();
	var s = timeObj.getSeconds();

	pi = Math.PI/180;//角度をラジアンに

	//3時から始まるので-90°する。
	var hRadian = (h/12*360 + m/60*360/12 - 90) * pi;
	var mRadian = (m/60*360 + s/60*360/60 - 90) * pi;
	var sRadian = (s/60*360 - 90) * pi;
	
	//盤の大きさ、針の長さ
	var baseL = dSize/2 * 0.6;
	var hL = baseL * 0.5;
	var mL = baseL * 0.75;
	var sL = baseL * 0.8;
	
	//盤と針
	var ov = pageObj[pg].ovals.add();
	ov.visibleBounds = [0,0,2*baseL,2*baseL];
	ov.convertShape (ConvertShapeOptions.CONVERT_TO_POLYGON, 60, 0);

	var houN = pageObj[pg].graphicLines.add()
	houN.paths[0].entirePath = [[baseL, baseL],[hL*Math.cos(hRadian)+baseL,hL*Math.sin(hRadian)+baseL]];

	var minN = pageObj[pg].graphicLines.add()
	minN.paths[0].entirePath = [[baseL, baseL],[mL*Math.cos(mRadian)+baseL,mL*Math.sin(mRadian)+baseL]];

	var secN =pageObj[pg].graphicLines.add()
	secN.paths[0].entirePath = [[baseL, baseL],[sL*Math.cos(sRadian)+baseL,sL*Math.sin(sRadian)+baseL]];

	//グループ化させてセンターに
	var grN = doc.pages[pg].groups.add([ov, houN, minN, secN]);
	grN.move([dSize/2 - baseL, dSize/2- baseL]);
	var sels = grN.allPageItems;
	//グループ化解除
	grN.ungroup();
	
	//パーツごとにぐりぐりする。
	for (var i = sels.length-1; i >= 0 ; i--) {
		var vSpeed = Math.min(1 + s, dSize/10); //仮想移動速度。ちいさい程、分割数が多くなる(ステップ数が増える)
		var childArm = Math.min(1 + m, dSize/20) ; //だいたいの太さ
		var degreePerCount = 1 + h + Math.random() * 90; //ぐるぐると360°を分割してまわる角度
		var childRandom = true;//true げじげじ、 false ぐるぐる
	
		grin (doc, sels[i], vSpeed, childArm, degreePerCount, childRandom);
		sels[i].remove();
		}// eof sels
	}// eof page

//裏方処理をしたなら、表に出す。
if(doc.visible == false){doc.windows.add();}

//オブジェクトの線分をパスポイントに分割
function grin (doc, sel, vSpeed, childArm, degreePerCount, childRandom) {
	var page = doc.pages.itemByName(sel.parent.appliedSection.name + sel.parent.name);
	moArray = new Array();
	var startPoint, endPoint, moArr;
	for(var p = 0; p < sel.paths[0].pathPoints.length-1; p++){
		if(p < sel.paths[0].pathPoints.length-1){
			startPoint=sel.paths[0].pathPoints[p].anchor;
			endPoint=sel.paths[0].pathPoints[p+1].anchor;
			}
		moArr = getLocus(startPoint, endPoint, vSpeed);
		}
	if(sel.paths[0].pathType == PathType.CLOSED_PATH){
		startPoint = sel.paths[0].pathPoints[-1].anchor;
		endPoint = sel.paths[0].pathPoints[0].anchor;
		}
	moArr = getLocus(startPoint, endPoint, vSpeed);
	grinPlace(page, moArr, childArm, degreePerCount, childRandom);
}

//移動中の座標を取得して配列に追加していく
function getLocus(start, end, vSpeed){
	var selW = end[0]-start[0];
	var selH = end[1]-start[1];

	//アンカー間の距離と傾き
	var selDist = Math.sqrt (Math.pow(selW,2) + Math.pow(selH,2));
	var selRad = Math.atan(selH / selW);

	//移項(xの負の方向への移動のとき)
	var aljabr;
	if(selW < 0){aljabr = -1;}
	else{aljabr = 1;}

	//設定した間隔で座標を取得
	for(var i = 0; i < selDist/vSpeed; i++){
		var moX = start[0] + aljabr*vSpeed*i*Math.cos(selRad);
		var moY = start[1] + aljabr*vSpeed*i*Math.sin(selRad);

		moArray.push([moX, moY]);
		}
	//端数で終端に達しなかった時
	if(moArray[-1] != end){
		moArray.push(end);
		}
	return moArray;
}

//ぐりぐりを生成
function grinPlace(page, array, arm, degree, random){
	var chiArray = new Array();
	var childX, childY;
	for(var j = 0; j < array.length; j++){
		for(var k = 0; k < 360/degree; k++){
			if(random == true){
				childX = array[j][0] + arm*Math.cos(pi*degree*k)*Math.random();
				childY = array[j][1] + arm*Math.sin(pi*degree*k)*Math.random();
				}
			else{
				childX = array[j][0] + arm*Math.cos(pi*degree*k);
				childY = array[j][1] + arm*Math.sin(pi*degree*k);
				}
			chiArray.push( [childX, childY] );
			}
		}
		var chiObj = page.rectangles.add();
		chiObj.paths[0].entirePath = chiArray;
		chiObj.paths[0].pathType = PathType.OPEN_PATH;
		chiObj.fillColor = "None";
		chiObj.strokeWeight = 0.5;
		var clrArr = ["Black", "Cyan", "Magenta", "Yellow"];
		chiObj.strokeColor = clrArr[Math.floor(Math.random()*(clrArr.length-1))];
		chiObj.strokeTint = 50 + Math.random()*50;
}

InDesignの標準機能で png書き出しはないけど、スクリプトならできます。
ただし、jpegやeps、pdf書き出しと違い、なぜかExportOptionsがないので細かい設定ができません。ドキュメント上の原寸サイズで、72ppiの透過png(レイヤー生きなら)が書き出されるようです。もうすこし高解像度にしたければ......(その方法は、ちょっと考えればわかると思います)。

pngを何に使うかといえば、○○○○絡みでInDesignの○○○○書き出しのオプションで画像形式が、まだjpegとgifしか選択できないので、透過png使ってみたいなーなんて。あとInDesignのグラフィックツールで描画したオブジェクトが○○○○では無視されるんで、それの透過png書き出しとか......。

pngexport.png

//PNG書き出し
var sel = app.selection[0];
var file = new File("~/Desktop/pudding.png");
var feedback = exportPNG(sel, file);
alert(feedback);//boolean

/**
 * exportPNG 
 * @param {Object} target Selected Object to export PNG
 * @param {Object} file Export File Destination
 * 
 * @returns {Boolean} true if success to export
 * 
 * export 72ppi transparent png no options exist
 */
function exportPNG (target, file) {
	if(target.allGraphics.length==1){
		var graphicObj = target.allGraphics[0];
		switch(graphicObj.constructor.name){
			case "PICT" :
			case "EPS" :
			case "WMF" :
			case "PDF" :
			case "Image" ://PSD/TIFF/JPEG/BMP
			case "ImportedPage" ://INDD
				try{
					target.exportFile(ExportFormat.PNG_FORMAT, file );
					return true;
				}catch(e){
					//$.writeln("saving was failed\r"+e);
					return false;
					}
			break;			
			default : return false;
			}
		}
	else{
		switch(target.constructor.name){
			case "Polygon":
			case "Rectangle":
			case "Oval":
			case "Group":
			case "GraphicLine" :
			case "TextFrame":
				try{
					target.exportFile(ExportFormat.PNG_FORMAT, file );
					return true;
				}catch(e){
					//$.writeln("saving was failed\r"+e);
					return false;
					}
				break;
			default : return false;
			}
		}
}
InDesign でストーリー中のアンカー付きオブジェクトが挿入されている場所を探すのに、
CharacterObjectでチコチコ PageItem がないか回していたら大変なので、String と indexOfでできないものか調べてみたのでメモ。
an.png
var sel = app.selection[0];
for(var i=0; i < sel.contents.length; i++){
	$.writeln(sel.contents.charCodeAt(i).toString(16));
	}
true
----結果----
3042
3093
3042
3093
fffc
3042
3093
----結果----

fffcが怪しい。
ためしに下のコードで合っているかためしてみると。
$.writeln(app.selection[0].contents.indexOf(String.fromCharCode("0xfffc"),0));
true
----結果----
4
----結果----
いい感じ。
OBJECT REPLACEMENT CHARACTER っていうんだ。勉強になった。
これから○○○○絡みで、アンカー付きオブジェクトって重要になってくるわけで、過去の資産を変換なんてことも必要になってくるはず。それに備えて InDesignのアンカー付きオブジェクト周りを調べてみました。
アンカー付きオブジェクトのGUIそのままにややこしいです。
あるプロパティのBoolean値によって、あるプロパティの値の意味が違ったりします。プロパティの共用しているので、名前に惑わされて思い通りに設定できなくてとても悩みます。
調べてみて一つわからなかったのが ObjectStyleSettings の VerticalAlignment 。名前から「行の上」のときの垂直揃えだと予測できるのですが、GUIでもそんな設定項目がなく、TopやBottomを設定しても無視されてCenterになってしまうのです。

とりあえず実行するとこんなオブジェクトスタイルができます。という関数のサンプル。
InDesign CS4 + OSX 10.6.4で試しました。
anchobjObjStyle.png
/**
 * @description アンカー付きオブジェクトだけ設定したオブジェクトスタイルをドキュメントに作る
 * 
 * @param {Object} doc document object
 * @param {String} objStyleName object-style name
 * @example createObjStyl(app.documents[0],"ancho_only");
 */
function createObjStyl (doc, objStyleName) {
	var objStyle;
	try {
		objStyle = doc.objectStyles.add({name:objStyleName});
		}
	catch(e){
		var rep = confirm("already existed object-style named \'"+objStyleName+"\'.\rdo you replace to this?");
		if(rep){
			//問答無用で置換するなら、confirmとif/elseはいらない。下の一行だけでよし
			objStyle = doc.objectStyles.item(objStyleName);
			}
		else {
			alert("replacement was canceled by you");
			exit();
			}
		}
	with(objStyle){
		//アンカー付きオブジェクトを有効にする
		enableAnchoredObjectOptions = true;
		//それ以外を無効にしておく
		enableParagraphStyle = false;
		enableFill = false;
		enableStroke = false;
		enableStrokeAndCornerOptions = false;
		enableTextFrameGeneralOptions = false;
		enableTextFrameBaselineOptions = false;
		enableStoryOptions = false;
		enableTextWrapAndOthers = false;
		enableFrameFittingOptions = false;
		}

	with(objStyle.anchoredObjectSettings){
		anchoredPosition = AnchorPosition.ANCHORED;
			//親の文字からの間隔:カスタム、インライン、行の上
			//ANCHORED //INLINE_POSITION //ABOVE_LINE 

		anchorXoffset = 0;//Xオフセット(カスタム)
		anchorYoffset = 0;//Yオフセット(インライン/カスタム)、後ろスペース(行の上)
		anchorSpaceAbove = 0;//前スペース(行の上)

		lockPosition = false;//手動配置を防ぐ

		pinPosition = false;//段の上下境界線内に収める(カスタム)
		spineRelative = false;//ノド元を基準(カスタム/行の上)

		anchorPoint = AnchorPoint.CENTER_ANCHOR;
			//アンカー付き位置 基準点(カスタム)
			//TOP_CENTER_ANCHOR //TOP_LEFT_ANCHOR //TOP_RIGHT_ANCHOR
			//CENTER_ANCHOR //LEFT_ANCHOR //RIGHT_ANCHOR
			//BOTTOM_CENTER_ANCHOR //BOTTOM_LEFT_ANCHOR //BOTTOM_RIGHT_ANCHOR

		horizontalAlignment = HorizontalAlignment.CENTER_ALIGN;
			//揃え(行の上) ノド元に〜〜はspineRelative = true と併用する
			//CENTER_ALIGN //LEFT_ALIGN //RIGHT_ALIGN //TEXT_ALIGN
			
		verticalAlignment = VerticalAlignment.CENTER_ALIGN;
			//垂直方向の揃え???
			//BOTTOM,TOPを設定しても、CENTER_ALIGN 1667591796 になる
			//BOTTOM_ALIGN //CENTER_ALIGN //TOP_ALIGN
			
		horizontalReferencePoint = AnchoredRelativeTo.COLUMN_EDGE;
			//アンカー付き位置 X基準(カスタム)
			//ANCHOR_LOCATION //COLUMN_EDGE //PAGE_EDGE 
			//PAGE_MARGINS //TEXT_FRAME

		verticalReferencePoint = VerticallyRelativeTo.COLUMN_EDGE;
			//アンカー付き位置 Y基準(カスタム)
			//CAPHEIGHT //COLUMN_EDGE
			//LINE_ASCENT //LINE_BASELINE //LINE_XHEIGHT
			//PAGE_EDGE //PAGE_MARGINS 
			//TEXT_FRAME //TOP_OF_LEADING	
	}
}

TranslateThis

このアーカイブについて

このページには、過去に書かれたブログ記事のうちJavaScriptカテゴリに属しているものが含まれています。

前のカテゴリはInDesignです。

次のカテゴリはLifeです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

アーカイブ

Blog Parts