Practice makes Perfect !

ExtendedScript素人です。同じ境遇の方、一緒に脱素人を目指しましょう!

実験004_2022.6-1

背幅を入力して表紙(貼込)用のドキュメントを作成するスクリプト

入稿された表紙のデータが見開きになっていない場合、InDesignに貼って見開きのPDFを作成することがあります。また見開き(背幅込)で入稿されたAIデータでも勤務先ではAIから直接PDF作成せずに、一度InDesignに貼りこんでからPDF作成という流れで統一しています。

ページものの表紙はページ数によって背幅が変わるので、テンプレートの準備はあまり意味がありません。これをスクリプトで解決できないか、ということで考えてみました。
主に仕上がりサイズはB5またはA4のページものが多数だと思いますのでそれ以外のサイズは想定していません。

やってみたいこと

背幅を入力するだけでB4長辺・A3長辺に背幅を足したドキュメントを作成する

下のような画面を用意し、仕上がりサイズと背幅の設定、貼込用のグラフィックフレームを全面塗り足しありで作成するか、表1~表4個別・塗り足しなしで作成するかを設定します。

この画面の作成はリプちんさんのスクリプちんを参考にさせていただきました。
dtpscriptin.com

「全面」にチェックをいれて実行すると結果的に図のようなドキュメントが作成されます。

※グラフィックフレームをドキュメントサイズよりも天地左右5mmずつ大きくしているのは貼り込んだAIやPDFトンボの位置がずれてないかわかりやすくするためです。

「個別」にチェックをいれて実行すると結果的に図のようなドキュメントが作成されます。

背幅が分かるように折りトンボを追加・仕上がりが分かるように罫線も追加

「折りトンボ」というレイヤーと「わく」というレイヤーを作成して、それぞれ0.1mmのスミ罫を描画します。校正提出時にお客さんに分かりやすいようにしておきます。もちろんカッター等で仕上げて提出する場合などは不要ですが…

こんな感じで作りました

背幅を入力しないと入力を促すアラートが出ます。背幅が0でいいときは0を入力します。

//背幅の入力画面
var uDlg   = new Window("dialog","表紙サイズ設定",[0,0,190,175]);
var sText  = uDlg.add("statictext",[25,10,150,25], "仕上がりサイズを選択");
var cb01   = uDlg.add("radiobutton", [25, 30, 75, 60], "B5");
var cb02   = uDlg.add("radiobutton", [100, 30, 150, 60], "A4");
var sText  = uDlg.add("statictext",[25,58,100,75], "背幅を入力");
var sehaba = uDlg.add("edittext",[95,54,125,80]);
var sText  = uDlg.add("statictext",[130,58,180,75], "mm");
var sText  = uDlg.add("statictext",[25,90,150,105], "フレームサイズを選択");
var cb03   = uDlg.add("radiobutton", [25, 110, 75, 140], "全面");
var cb04   = uDlg.add("radiobutton", [100, 110, 150, 140], "個別");
var okBtn  = uDlg.add("button",[45,140,45+100,140+20], "OK");

sehaba.active = true;
cb01.value    = true;
cb03.value    = true;
uDlg.center();
var rtType = uDlg.show();
var sehabaX = sehaba.text;//入力された数値

//処理の実行
if((sehaba.text=="")&& (rtType==1)){
	//背幅を入力しないままOKを押すとアラート
	alert("数値を入力してください");
}else{
	//OKボタンを押すと処理開始
	if(rtType==1){
		DocAdd();
	//閉じるボタンを押すと終了
	}else (rtType==2){
		exit();
	}
}

//メイン処理
function DocAdd(){
	doc = app.documents.add();
	var dp = doc.documentPreferences;
	var sumB5 = 364+Number(sehabaX)+"mm";
	var sumA4 = 420+Number(sehabaX)+"mm";
	var tanpen;
	
	if(cb01.value) {
		dp.pageWidth = sumB5;
		dp.pageHeight = "257mm";
		tanpen =182;
	}else{
		dp.pageWidth = sumA4;
		dp.pageHeight = "297mm";
		tanpen =210;
	}

	//マスターページのマージン・段組設定
	docSet();

	//グラフィックフレームを作成
	var lay1 = doc.layers[0];
	var rct1 =msp.rectangles.add();
	if(cb03.value) {
		//全面:塗り足しありで作成
		rct1.contentType = ContentType.GRAPHIC_TYPE;
		rct1.geometricBounds=[msp.bounds[0] - 5, msp.bounds[1] - 5, msp.bounds[2] + 5, msp.bounds[3] + 5];
	}else{
		//H1~H4個別:塗り足しなしで作成
		rct1.contentType = ContentType.GRAPHIC_TYPE;
		rct1.geometricBounds=[msp.bounds[0], msp.bounds[1], msp.bounds[2], msp.bounds[3]/2-(sehabaX/2)];
		var rct2 =msp.rectangles.add();
		rct2.contentType = ContentType.GRAPHIC_TYPE;
		rct2.geometricBounds=[msp.bounds[0], msp.bounds[1]+tanpen+Number(sehabaX), msp.bounds[2], msp.bounds[3]];
	}

	//折りトンボの追加
	var lay_se = doc.layers.add({name:"折りトンボ"});
	var gl1 = msp.graphicLines.add();
	gl1.geometricBounds=["-3mm", tanpen, "-2mm", tanpen];
	gl1.strokeColor = doc.swatches.itemByName("Registration");
	gl1.strokeWeight = "0.1mm";
	var gl2 = gl1.duplicate(undefined, [0, Number(dp.pageHeight)+5]);
	var ST = msp.groups.add([gl1, gl2]);
	ST.duplicate(undefined, [sehabaX, 0]);
	lay_se.locked = true;

	//仕上がり罫を作成
	siagariK();
}

function docSet(){
	msp = doc.masterSpreads[0].pages[0];
	mg =msp.marginPreferences;
	mg.columnCount = 2;
	mg.columnDirection = HorizontalOrVertical.HORIZONTAL;
	mg.columnGutter = sehabaX;
}

function siagariK(){
	var lay_waku = doc.layers.add({name: "わく"});
	var imgObj = msp.rectangles.add();
	with(imgObj){
		contentType = ContentType.GRAPHIC_TYPE;
		geometricBounds =msp.bounds;
		strokeWeight = "0.1mm";
		strokeColor = "Black"
		fillColor = "None"
	}
	lay_waku.locked = true;
	lay_waku.visible = false;
	//一番下のレイヤーをアクティブに
	doc.activeLayer= doc.layers.lastItem();
}

入力された数値を使った計算

とても簡単なことなんでしょうけど、
やっぱり独学ってつまづくことがいろいろありまして。
「入力された数値に10を足して答えを表示する」
これだけのことなんですけど全然わかりませんでした。

最初に書いたスクリプトはこちら。

var rt = prompt("数値を入力","");
alert(rt+10);


これで5を入力したときに15と表示してほしかったんです。
でも表示されたのは「510」

おかしいですね、なんででしょう。

で、調べたらpromptから返されるデータは、数値ではなく文字列とのこと。
Number(),parseInt(),parseFloat()を使って数値型にしなければならないとのこと。
これらを調べたらどうやらNumber()を使うのがいいのかなと思い、上記スクリプトを書き換え。

var rt = prompt("数値を入力","");
var num=Number(rt);
alert(num+10);

これで意図する計算が出来ました。

いやー奥が深いですね
え?基本中の基本?
そうですか…

Bounds! Bounds! Bounds!

ページの上下左右4辺の座標はBoundsで取得できるんですね。
知りませんでした。

A4のドキュメントを作成して

var doc = app.activeDocument.pages[0];
$.writeln(doc.bounds[0]); // 上
$.writeln(doc.bounds[1]); // 左
$.writeln(doc.bounds[2]); // 下
$.writeln(doc.bounds[3]); // 右

と入力すると
0
0
296.999999999461
209.999999999936
という結果が得られます。細かいことは気にせずに。

今までは作業中のページサイズの長方形フレームを作成するときは以下のスクリプトを実行していました。

var doc = app.activeWindow.activePage; // 作業中のページ
var rct = doc.rectangles.add();
rct.contentType = ContentType.graphicType;
w = app.activeDocument.documentPreferences.pageWidth;
h = app.activeDocument.documentPreferences.pageHeight;
rct.visibleBounds = ["0mm","0mm",h,w];

なにも考えてなかったのですが、これだと問題がありました。
例えばドキュメント設定でサイズをA4にしていた場合、どのページもA4であるなら問題がないのですが、途中で違うサイズのページが出てきた場合、上記スクリプトを実行すると、そのページにはページサイズのフレームではなくA4サイズのフレームが出来てしまうんですね。

なのでこういう場合も考慮してBoundsを使えばいいと思いました。

var doc = app.activeWindow.activePage;
var rct = doc.rectangles.add();
rct.geometricBounds = doc.bounds;
rct.contentType = ContentType.graphicType;

見た目もキレイでスッキリとしました。
bounds、最高じゃないですか笑

いや、何事もひとりでやっていくって大変ですね笑
(いいからやれよ)

新規ドキュメントの作成

前回の更新日が昨年の11月…
年末から繁忙期に入ったとはいえ、ずいぶん長い間、ブログ更新してないな、と思います。
そして、繁忙期が終わったあと、せっかく勉強してきたスクリプトをほとんど忘れているという悲しい状況でございました。
リハビリを兼ねてといいますか、しばらくは力を抜いてブログを少しずつ再開していきたいと思っています。

新規ドキュメントの作成

「B4横長のドキュメントを新規で作る」
というスクリプトを書こうと思ったら
var doc = app.documents.add();
で行き詰ってしまいました。こんな状況です。
今までいったい何をやってたのでしょう…
ということでドキュメントの設定について調べてみました。
ドキュメントの設定には〈documentPreferences〉を使用するようですね。

var doc = app.documents.add();
doc.documentPreferences.pageSize = "B4";

これでとりあえずB4のドキュメントが作れます。

"B4"のところはメニューから選べるものであれば何でも行けるようですね。
名刺にしたい場合は"名刺(半スペ)4(半スペ)号"で作成できました。
f:id:YustinBieber:20220412154850p:plain


さて、横長にしたい場合は

var doc = app.documents.add();
doc.documentPreferences.pageSize = "B4";
doc.documentPreferences.pageOrientation = PageOrientation.LANDSCAPE;


天地左右のマージンの設定は

doc.pages[0].marginPreferences.top = 10;
doc.pages[0].marginPreferences.left = 5;
doc.pages[0].marginPreferences.bottom = 10;
doc.pages[0].marginPreferences.right = 5;


マージンはマスターで設定しておきたかったので

doc.masterSpreads[0].pages[0].marginPreferences.top = 10;
doc.masterSpreads[0].pages[0].marginPreferences.left = 5;
doc.masterSpreads[0].pages[0].marginPreferences.bottom = 10;
doc.masterSpreads[0].pages[0].marginPreferences.right = 5;

としました。

その他、規格外のサイズのもの、見開き、綴じ方向、ページ数の設定

var doc = app.documents.add();
doc.documentPreferences.pageWidth = "100mm";   //幅
doc.documentPreferences.pageHeight = "200mm";  //高さ
doc.documentPreferences.facingPages = true;  //見開き
doc.documentPreferences.pageBinding = PageBindingOptions.RIGHT_TO_LEFT;  //綴じ方向
doc.documentPreferences.pagesPerDocument = 8;  //ページ数


ブログ、続けられるといいな…
(いや、続けろよ)

実験003_2021.11-1

指定したページに、指定したマスターを当てるスクリプト

ページものを作っていて、各カテゴリや各章ごとにマスターが変わるときに、2・3個のマスターなら手動で割り当ててあげればいいのですが、マスターが10個とか20個とかあると、もうそれだけでうんざり…

f:id:YustinBieber:20211126114824p:plain
マスターが多すぎて嫌になる…
f:id:YustinBieber:20211126111619p:plain
いちいち手動で設定していくのが手間でした

なんとかならないものだろうかと考えていたんです。


それで次の工程で考えてみました。

  1. エクセルを使って、何ページに何番目のマスターが当たるかを設定しておき、テキストファイルに書き出す
  2. 書き出したテキストファイルを1行ずつ読み込んで、各ページに指定されたマスターが当たるようにスクリプトで処理
f:id:YustinBieber:20211126111717p:plain
エクセルで何番目のマスターを当てるか設定しておく

上の図はあくまで例なのですが、1~2ページに1番目のマスター、3~4ページに2番目のマスター…といった感じです。マスターをなしにする場合は空白にしておきます。

それで考えてみたのが以下のスクリプトです。

var docObj = app.activeDocument;
var pageObj = docObj.pages;

var filename = File.openDialog("リストのテキストファイルを選択してください。");
if (filename)
{
var fileObj = new File(filename);
 // 読み込みモード
fileObj.open("r");

//テキストファイルを1行ずつ読み込み最終行まで繰り返し
while(!fileObj.eof) {
	try{
		for (var i=0; i<pageObj.length; i++){
		var line= fileObj.readln();
		if(line!="") {
		pageObj[i].appliedMaster =app.activeDocument.masterSpreads[line-1];
		}else{
		//リストでマスターの指定がない場合はマスター[なし]にする		
		pageObj[i].appliedMaster =null;
		}
	}
		}catch(e){}
}
fileObj.close();
alert("終了しました");
}else{
	exit();
	}

実行結果は図のページパレットをご覧いただけるとわかると思います。
f:id:YustinBieber:20211126114331p:plain
これでマスターの数分だけ、いちいち手動で割り当てていた作業が数秒で終わるようになりました。

蛇足ですがエクセルでは先に範囲選択をしておけば、数値入力後にCtrl+Enterで選択範囲内に同じ数値が一発で入りますよ。

Recommend_002 段落の選択→任意の行数に収める

段落の選択に4回クリック?

1つの段落を選択するのにInDesignでは4回クリックしなければなりません。
4回のクリックなんて楽なようで面倒です。
スクリプト→ショートカットで解決してしまいましょう。

ちなみにシングル、ダブル、トリプルの次って何だ?と思って調べてみたんですが、こうなっているようです。


1 シングル (single )
2 ダブル (double )
3 トリプル (triple )
4 クアドラプル (quadruple )
5 クインタプル (quintuple )
6 セクスタプル (sextuple )
7 セプタプル (septuple )
8 オクタプル (octuple )
9 ノナプル (nonuple )
10 デキャプル (decuple )


4回クリックは「クアドラプルクリック」! なるほど…。


InDesignの段落の選択に関しては、末尾の改行まで選択してしまうということによる弊害がありまして、こちらについてはDTPtransitさんの方で紹介されています。

www.dtp-transit.jp

そちらで紹介されているスクリプトがUske_Sさんのスクリプト

uske-s.hatenablog.com

任意の段落の一部を選択したり、カーソルを点滅させておけば、画像のように1段落を改行を除いて選択してくれます。
f:id:YustinBieber:20211117171138p:plain

末尾の改行を除いて段落を選択するスクリプトはDTPtransitさんのサイトでダウンロードできるようになっていますので、すぐにダウンロードし、ショートカットを設定されることをお勧めします。


見出しを1行に収めたい

2行にわたってしまっている見出しを1行に収めたかったり、E-mailアドレスを1行に収めたかったり…
そういったことに出くわすことはよくあることだと思います。

そんな時、まずは上のスクリプトで段落を選択。
そして、選択した段落を1行に収めるには市川せうぞーさんのサイトにある「shorten_line_selection」を使用します。

www.seuzo.jp

こちらのスクリプトはデフォルトで選択範囲を1行に収める設定になっています。
私はこちらのスクリプトをカスタマイズさせていただいて、「長体のみ」で1行に追い込むように設定しています。


というわけで、2行にわたる見出しを1行にするといった処理は、上記2つのスクリプトを使えば、キーボードを2回叩くだけでストレスなく終わってしまいます。
名刺の長~いE-mailアドレスなんかにも大活躍!テキストフレームから文字が溢れていても選択できます。

f:id:YustinBieber:20211117171144p:plain
ここまでの処理がキーボード2回叩くと出来てしまう

さらにこの2つのスクリプトを組み合わせてしまえば、1回のショートカットで処理出来てしまいます!
なのでわたしは組み合わせちゃってます。
いままでドラッグして範囲を指定して、文字パレットで1行に収まるまでカチカチクリックして長体かけて…、とやっていたのがアホらしくなってきます。


意外と知られていない? 長体のショートカット

最後に余談ですが、InDesignで文字に長体をかけるショートカットは[編集]メニューの[キーボードショートカット]から[テキストと表]→[水平比率を減少]で設定できます。
こちらも良く使う機能だと思いますのでショートカットの設定をおすすめします。
f:id:YustinBieber:20211117171125p:plain

好きな仕事をしていても、やっぱり「面倒くさい」と思うことはあるわけで、じゃあどれだけストレスなく作業をこなすかって考えたら、「楽に処理できる方法を知る」これにつきますね。

Recommend_001 基準点の変更

InDesignでオブジェクトを選択して、基準点を選択して、位置と大きさを指定して…という作業がいつも面倒くさいと思っていました。これだけでマウスを3回クリックしなくてはいけない…。

オブジェクトを選択して「Crtl+6」でX座標に入れることは知ってはいましたが、その横にある基準点の移動がスクリプトで制御できると知ってからは、格段に作業効率があがりましたし、ストレスもなくなりました。

それで、スクリプト&ショートカットを割り当ててやるのが便利ですよ!って紹介しようかと思っていたのですが、これはすでにDTP Transitさんの方で紹介されていました。

www.dtp-transit.jp

上ページにある「スクリプトを使う」というところで紹介されているスクリプトをダウンロードすれば全て解決です。

ここでは一応その中身のご紹介をさせていただきます。

ダウンロードしたスクリプトのうち基準点を中心に持ってくるスクリプトは次のようになっています。

app.layoutWindows[0].transformReferencePoint = AnchorPoint.CENTER_ANCHOR;

たったこれだけです。

app.layoutWindows[0].transformReferencePoint = AnchorPoint.●●●●●

この●●●●●の部分を変えるだけで基準点を制御できるようになっています。
以下の図にまとめてみました。

f:id:YustinBieber:20211118154444p:plain


あとはいつものようにショートカットを設定してあげるだけです。
それで、さすがに9個もショートカットは覚えられないと思ったので、基準点の位置に合うようにテンキーの1~9を割り当てました。
割り当てたのですが、これだと何故かテキストを入力するときに「1」だけ入力できなくなってしまったので「1」だけショートカットを変えてます…。

f:id:YustinBieber:20211118164404p:plain

f:id:YustinBieber:20211119084607p:plain

これでオブジェクトを選択した後はこのショートカットで基準点を設定した後に「Ctrl+6」でX座標に入ってしまえば、あとはキーボードのみで処理できるので大分ストレスが減るのではないかと思います。
(数値の入力を始めると上のショートカットは使えなくなるのでそこは難点ですが…)

こんな細かいことでもスクリプトを知ってるか知らないかで作業効率が変わってきます。
別に大きなことをやろうとする必要はなく、ちょっとした工夫で大きな効果を得られることはどんどん取り入れていくべきですね!

余談ですが、だったらオブジェクトを選択したら自動で基準点が左上になるようにスタートアップスクリプトで設定しとけばいいじゃん!と思って以下のコードを入れてみましたが、ダメでした。残念…

var selObj= app.activeDocument.selection;
if (selObj.length !== 0) app.layoutWindows[0].transformReferencePoint = AnchorPoint.TOP_LEFT_ANCHOR;