ディザInDesignブログ: 私が InDesign CS5 を勧める最大の理由

メインの編集ソフトをInDesign CS3からCS5に変更しようとしています。色々新機能が追加された中で(スクリプトはまだ奮闘中ですが)、これはCS5にするべきだ、と思った機能があります。それは「複数のページサイズ」の機能。ヘルプでは「同じドキュメント内に名刺、はがき、レターヘッドおよび封筒の各ページを含める」例があり、また観音折のように内側に入るページの幅が外側のページより3mm程度短くなるケースといった使い方が紹介されてますけれど、普段自動組版を中心としたページ物に携わることが多い自分としては、これらの例はあまり役に立ちません。
それよりも大事なことは、「ページ物の表紙をInDesignで作成することができる」んです。今までページ物の本文はInDesignで作成していても、表紙は背幅があるのでIllustratorで作成していました。しかも背幅は本文のページ数が決まらないと決められないので、仮に作成していてもページ数の増減によって(あるいは本文用紙の変更によって)変更することがしばしば。Illustratorでも変更は面倒な作業でした。
しかーし、InDesign CS5にすることによって背幅の変更がいとも簡単になりました。しかも[マージン・段組]で[レイアウト調整を有効にする]のチェックを入れておけば、マージンに合わせて作成した背文字用のテキストフレームも自動で大きさが変わってくれるんです。(なお、見開きページで作成しないと、ページサイズを変更したときに他のページがついてこないので注意。)
私はもう、これだけでバージョンアップの価値あり、と思います。
Ws04

追記

トンボを付けてプリントすると折トンボもちゃんとついてくるよ。

ディザInDesignブログ: 今こそ「デバイスに依存しない」組版規則が必要と考える

先のセミナー原稿作成を通じて私が発見したものとは「行頭・行末」という表現は「行」というものが存在する前提でしか存在し得ない、行という概念がなくなっても「分離禁止」という概念は存在し続ける、ということです。
今まで文字で表現するものといえば「紙」(もしくは有限の広さを持つ面)でした。それがゆえに「ページ」という概念が存在した訳ですが、Webの登場で「ページ」の概念はなくなりました。そして1行の文字数を無限に設定できる媒体では「行」という概念もなくなります。
実際、文字が流れる電光掲示板では、行数や行間(行送り)はありませんので「行」という概念はありません。下の図のような例も「行」という概念が薄いと思います。
Ws03

だから「分離禁止」はなくていいかっていうとそうではないんじゃないかって思うんです。たとえ分割されることがなくても、分割しちゃいけない、っていう思いがあるんです。もしかすると「行」以外の概念で分割されるかもしれない、そのときには禁則処理に従って分割を避ける。それが「分離禁止」の理念じゃないか、と思うわけです。
前のエントリーで提示した資料は、特に明記はしませんでしたが、これは「紙」限定の話ではありません。Webでも通用するし、「行」という概念のない表示デバイスでも通用します。いわば「デバイスに依存しない」組版規則のひとつである、と思っています。
今、電子書籍が騒がれていますけれども、電子書籍対応だけに捉われるのではなく、将来出てくるであろう新たな表示デバイスに対しても「ちゃんとした日本語組版」を実現させるためには、「デバイスに依存しない」組版規則+「デバイス別の特性に応じた」組版規則で考える必要があるのではないか、というのが私からの提言です。

なお、「ちゃんとした日本語組版」については私はまだまだ勉強不足です。ご指摘いただいた方々に感謝申し上げます。

ディザInDesignブログ: DTP Booster 019「日本語を組むときの基本」のスライドPDFです

Booster19a
当初はこんな予定ではなかったんですけどね。考えを詰めていったらJISの「日本語文書の組版方法(JIS X 4051)」や、W3Cの「日本語組版処理の要件(日本語版)」を否定する内容になっちゃいました。
でも行頭禁則・行末禁則では、中黒を箇条書きとして使うときや疑問符を単独で使うときの説明がうまくできないんですよ。

でもね、これ書いてたら、あ、やっぱり組版は生き物だわ、と思ってしまいました。

で、公開するに当たり、注意事項があります。これは、私のセッションで使用した資料の一部であり、これが私のセッションの内容の全てではない、ということです。スライドですので、文章は短く、また断定的になっている部分があります。実際のセッションでは説明を加え、ところどころ「これは一般的なものではなくあくまでも個人の考え」「こういう考え方もある」という注釈を付けたりしています。実際、セミナーのアンケートでも「独善的だ」「偏っている」という意見も頂きました。それはごもっともなことです。

それでもあえて公開するのは、今現在の日本語組版が抱えている問題点をいくつか指摘しており、その指摘が皆さんの役に立つと思うからです。例えば「禁則の決め事12」については「組版システム・電子書籍リーダーで実装するのは不可能」という意見も頂きました。その通りです。でも会場で賛同するかどうかを聞いたところ、ほとんどの方に賛同を頂きました。コンピュータで実装できないからこそ手作業で禁則処理を行わなければならない場合もあるのです。そういうことも含め、議論のたたき台、日本語組版の考えを深めるための材料としていただければ幸いです。

ダウンロードはこちらから。PDFファイルですのでクリックするとブラウザ内で開いてしまうかもしれません。そういう方は右クリックして「ファイルに保存」などでダウンロードしてください。

ディザInDesignブログ: DTP Booster 019

DTP Booster 019(Kanazawa/100827)

ちょっとしゃべることになりました。よろしくお願いします。

ディザInDesignブログ: [文字に囲み罫を設定する]CS5用暫定版をアップしました

暫定版です。しかもCS5専用です。そのうちCS2~CS5までをひとつでカバーできるものを作るかもしれませんが、とりあえず単独でアップしました。
だってCS4までは「lineMeasurementUnits」で通してきたものが、CS5でいきなり「strokeMeasurementUnits」に名前が変わってるんだもん。これ使ってるの1箇所だけじゃないんだぞ。それぞれの場所でインタープリタのバージョンに合わせてif文を書き加えるなんて、とてもやっとれん。

そんなわけでダウンロードはこちら

あ、ほかのやつもそのままでは動かないのが結構あります。おいおい修正していくので気長に待っててください。急ぐ人は「Scripts Panel」フォルダ内に「Version 6.0 Scripts」フォルダを作成してその中に入れてください。

ものかの: 誤解を解きたい

私(飼い主)はオトコですよー! 今まで誤解されていた方々には、お詫びのしようもございません…

たけうちとおるのスクリプトノート: 大阪DTP勉強会

9/25土曜日、大阪DTP勉強会にせうぞーさん(名もないテクノ手)が来られます。

OSAKA0925.gif

また、後半のディスカッションでは私も参加させていただくのですが
秋葉秀樹さん(WebCreator Extends Designer!?)そして
あかねさん(ちくちく日記)も遠方から参加されます。

東京の人もうらやむぐらいのかなり豪華なセミナーです。
(私はカウントしないで。関西ではいつもいますし(笑))

えー。スクリプターの皆さんや正規表現使ってみたい人はもちろん
DTPやってる方はぜひご参加下さい。

ディザInDesignブログ: 業界の常識を覆す大発見!

今、DTP Boosterのスピーチ原稿を作ってます。テーマは「日本語組版の基本」ということで、過去に社内で行った勉強会の資料やら、さまざまなメモを漁ってまとめています。そのなかで、ここはどうにもうまく説明がつかないんだよな、どういう原理でこうなっているんだろう、てな具合で考えていたら、なんと、今までの常識を覆す発見をしてしまいました。
印刷会社に勤務して20年、まさかこんな結論になろうとは。
今度のDTP Booster 019では、あなたの組版の常識が覆ります。乞うご期待!

いや客寄せではなくて、本当に驚くんだからっ、もう。

ScriptClip: jQuery風にドキュメントのオブジェクトを抽出するかも

ScriptClip
/* Copyright 2010 kamiseto. All Rights Reserved.
 *
 * @doEx is  Document Objects Extract Tool  , like jQuery
 * doEx('selection').filter('groupItems').each(function(){........});
 * doEx(app.activeDocument).find('groupItems>pathItems').each(function(){....});
 * @author kamiseto
 *2010-08-10 ScriptUI関係の関数を追加(drawMosaicPict....etc)
 *2010-08-06 myDialogMaker.jsを組み込む
 *2010-07-28 hvg.jsを組み込む 
 *2010-07-21 c.js からdoEx.jsに改名。
*/
 
//Curry
Function.prototype.curry = function(){
	var slice = Array.prototype.slice, args = slice.apply(arguments) , that = this;
	return function (){
			return that.apply(this, args.concat (slice.apply(arguments)));	
	};
};
 
var doEx;
(function() {
doEx  = function(){return new doEx.prototype.init(Array.prototype.slice.apply(arguments));};
doEx.selection = doEx.curry('selection');
doEx.prototype = {
/**
*  create doExObject
*  @param :  {Any}
*  @returns : doExObject
*/
	'init' : function () {
		if(!this.length)this.length = 0;
        var arg =Array.prototype.slice.apply(arguments)[0];
        this.log.push('doEX_init : ' + arg.toString());
        for(var i = 0; i < arg.length ; i++){
            var s = arg[i];
    		try{				
        		switch(s.constructor.name){
					case 'Object' :
						try{
							for(var x in s){
										this[x](s[x]);
							}
						}catch(e){this.error.push('init_Object_error : '+e);}
					break;
            		case 'Function' : return doEx(s());
            		case 'String' :
            		      try{
        					  if(typeof this.objectShortName[s] == 'string')s= this.objectShortName[s];
        						  s = app.activeDocument[s];
        						  this.add(s);
        					  }catch(e){
								  this.error.push('objectShortName_error : '+e);
        					}
            			  break;
        			case 'Array' : this.add(s);break;
        			default : 
        					this.add(s);
        			}
        		}catch(e){
        			this.add(s)
    		}
		}
		return this;
	},
/**
*  add Object to doExObject
*  @param :  {Any}
*  @returns : doExObject
*/
     'add' : function(s){
       this.log.push('doEX_add : ' + s.toString());
   	   var len = this.length;
		 try{
			if(typeof s === 'string')s = doEx(s);
 
			if(s.length){
				s = Array.prototype.slice.call(s,0);	
				for(i=0;i < s.length ; i++){
						this[len+i] = s[i];
				}
				this.length = len + s.length;
			}else{
				this[len] = s;
				this.length++;
			}
		}catch(e){
 
			this[len] = s;
			this.length++;
			this.error.push('add_error : '+e);
		}
 
			return this;
   	},
/**
*  doExObject 2 Array
*  @returns : {Array}
*/
    'toArray' : function(){return Array.prototype.slice.call(this,0)} ,
	'saveDoc' : function(path){
						this.each(function(){if(this.constructor.name == 'Document'){this.saveAs(File(path));};});
						return this;
				},
	'position' : 0,
	'get' : function(num){if(typeof num == 'number' &&  num  < this.length && num >= 0)return this[num];return false;},
	'now' : function(){return this.get(this.position);},
	'next' : function(){return this.get(this.position++);},
	'prev': function(){return this.get(--this.position);},
	'loop' : function(){
				if(this.position > this.length)this.position = 0;
				return this.get(this.position++);
	},
	'dofunc' : function(func,arg){
				  if(func == undefined)return this;
	               var res = true;
		          if(func.constructor.name == 'Function')res = func.call(this);
		          if(res){
		              return  this;
		              }else{
		              return {'each' : function(){}};
		          };
		},
	 'eachReverse' : function(fnc,arg) {
	  	    var l = this.length;
	  	    var res = [];
			if(typeof fnc == 'function'){
			for(var i = this.length; i>0;i--){
				 ret = fnc.call(this[i],this[i],arg);
				 (typeof ret != "undefined") && res.push(ret); 
			 }
			}
			if(res.length > 0){
                return doEx(res);
			}else{
                return this;
		    }
   	 },
/**
*  each doExObject
*  @param {Function} , {arg}
*  @returns : doExObject
*/
	 'each' : function(fnc,arg) {
	 		this.log.push('each : ' + this.toArray().toString());
	  	    var l = this.length;
	  	    var res = [];
			if(typeof fnc == 'function'){
			for(var i = 0;i<l;i++){
				 ret = fnc.call(this[i],this[i],arg);
				 (typeof ret != "undefined") && res.push(ret); 
			 }
			}
			if(res.length > 0){
                return doEx(res);
			}else{
                return this;
		    }
   	 },
/*
* filter
* @param {Function , String}
* @return : doExObject
*/
   	 'filter' : function(){
   	 		this.log.push('filter : ' + Array.prototype.slice.apply(arguments).toString());
			if(arguments.length == 0)return this;
			var s = {'TRUE' : [],'FALSE' : []};
			var caseBy = {
				'function' : function(arg){
					while(x = this.next()){
						   			arg(x) ? s.TRUE.push(this) : s.FALSE.push(this);
								};
				},
				'string' : function(arg){
						if(typeof this.objectShortName[arg] == 'string')arg = this.objectShortName[arg];
						if(typeof this.filters[arg] == 'function'){
									this.filters[arg].call(this,s);
						}else{
									var fd = this.attr(arg).toArray();
									s['TRUE'] = s['TRUE'].concat(fd);
						}
				}
			};
			var extractarg = function(args){
			for(i=0;i<args.length;i++){
					var arg = args[i];
					switch(arg.constructor.name){
						case 'Function' :
							caseBy['function'].call(this,arg);
							break;
						case 'String' : 
							var ARG = arg.split (">");
							for(j =0 ; j < ARG.length ; j++){
								caseBy['string'].call(this,ARG[j]);
							}
					};
				};
			};
			extractarg.call(this,arguments);
			try{
				return doEx(s.TRUE);
			}catch(e){
				this.error.push('filter_error : '+e);
				return doEx();
			}
   	 	},
 /*
 *find
 *@param {String}
 *@returns doExObject
 */
 		'find' :function(text){
					this.log.push('doEX_find : ' + text.toString());
					try{
					var ARG = text.split (">");
					var that = this;
					for(var i =0 ; i < ARG.length ; i++){
						var SP = ARG[i].split(",");
						var it = doEx();
						for(var j = 0; j < SP.length ; j++){
									it.add(that.attr(SP[j]));
						}
						that = it;
					};
						this.log.push('doEX_find_return : ' + that.toArray().toString());
						return that;
					}catch(e){
						this.error.push('find_command_error : ' + text );
						return this;
					}
				},
/*
*attr
*@param {}
*@returns doExObject
*/
		'attr' : function(x,y){
			var that = this;
			var it = doEx(that.each(function(){
				try{
						if(typeof x == 'string' && y ){
							try{
								if(typeof y == 'string')return this[x] = y;
								if(typeof y == 'function'){this[x] = y.call(this,this);}
							}catch(e){
								that.error.push('attr_value_set_error ' + e);
							}
						}
						if(typeof x == 'object'){
							for(i in x){
									if(this.hasOwnProperty(i)){
										try{
										switch(typeof x[i]){
												case 'function' : this[i] = x[i].call(this,this);
												break;
												default : this[i] = x[i];
										}
										}catch(e){
												that.error.push('attr_value_error : '+e);
										}
									}
							}
						}
						if(typeof x == 'string'){
										var gx = this[x];
										try{
											if(gx.toString() == '')return "";
											switch(typeof gx){
												case 'string' : return gx;
												case 'number' : return gx;
												case 'function' :return x + " is function";
												case 'undefind' : return undefined;
											}
											if(gx.length){
												return app.name.match(/InDe/) ? Array.prototype.slice.call(gx,0) : Array.prototype.slice.call(gx,0);
											}else{
												return gx;
											}
										}catch(e){
											that.error('attr_value_error_x : ' +e);
											return false;
										}
						}
						if(!x && !y){
								for(i in this){
									try{
									this.hasOwnProperty(i) && $.writeln(i +" : "+ this[i]);
									}catch(e){
												that.error.push('attr_value_error : '+e);
									};
								};
						};
					}catch(e){
						that.error.push('attr_error_ :' + e);
						return false;
					};
				})).toArray();
				var rt = [];
				while(r = it.shift())rt = rt.concat(r);
				return doEx(rt);
			},
/*
* search
* @param {}
* @returns doExObject
*/
		'search' : function(x,y){
			return doEx(this.each(function(){
				if(typeof this[x] == 'string'){
				 if(this[x] == y)return  this
				}
				if(typeof this[x] == 'object'){
				if(this[x].constructor.name == y)return this;
				}
				}));
		},
		'filters' : {},
		'error' : [],
		'temp' : [],
		'log' : [] ,
		'duplicate' : function(x,y){return this.each(function(){return this.duplicate(x,y)})},
		'type' : function(){return this.each(function(){return this.constructor.name})},
		'debug': function(){this.each(function(){$.bp()})},
		'remove' : function(){this.each(function(){this.remove()})},
		'test' : function(x,fnc,arg){typeof fnc == 'function' && fnc.call(this[x],this[x],arg)} ,
		'first' : function(fnc,arg){typeof fnc == 'function' && fnc.call(this[0],this[0],arg)},
		'constructor' : {'name' : "DocumentObjectsExtract"},
		'saveLog' : function(){},
		'alertLog' : function(){alert(this.log.join('\n'));this.log = [] ; return this;},
 
		'alertError' : function(){alert(this.error.join('\n'));this.log = [] ; return this;},
		'view' : function(){
						var i = 0 , that = this ,O = {};
						while(O = that.next()){
						var D = myDialogMaker(
							{type:"dialog", title:"DataBrowse", opt:{}, pos:[0, 0, 400, 400], layout:[
							{type:"group",  name:"Group", label:"Group" ,pos:[0, 0, 398, 398] , option:{}, items:[	
									{type:"edittext", name:"T", label:"", option:{}, pos:[16, 13, 386, 35]}, 
									{type:"listbox", name:"L", label:"ListBox", pos:[15, 46, 384, 354], option:{
											onChange : function(){
												this.selection && this.parent.items["T"].text = this.selection.key  +" : " + this.selection.value},
											onDoubleClick : function(){
												if(this.selection){
													doEx(O[this.selection.key]).view();
												}
												}
											}
									},
									{type:"statictext" , name:"OT" , label : "" ,pos:[16, 363, 200, 387] , option :{}}, 
									{type:"button", name:"E", label:"Next", pos:[250, 363, 300, 387] , option:{onClick:function(){
										this.parent.parent.close();
									}}},
									{type:"button", name:"E", label:"Close", pos:[320, 363, 387, 387] , option:{onClick:function(){
										this.parent.parent.close(2);
									}}},
									{type:"button", name:"E", label:"Load", pos:[200, 363, 250, 387] , option:{onDraw:function(){
												this.parent.items["OT"].text = O.toString()+"["+i.toString()+"] of "+that.length;
												var L = this.parent.items["L"];
												L.removeAll();
												for(v in O){
													try{
														var x = L.add("item",v+" : " +O[v].toString().slice(0,40));
														x.key = v;
														x.value = O[v].toString();
													}catch(e){
														var x = L.add("item",v+" : "+ e );
														x.key = v;
													}
												}
											}
									}}
									]}
							]}
						);
						D.wD.center();
						if(D.wD.show() == 2)break;
						i++;
						};
						return this;
		},
/*
*  
*  @param {}
*  @returns : hvgExObject
*/
		'hvg' : function(Sc){
							if(!Sc)Sc=1;
							/*
							*
							*
							*/
							var hvgObject = {
								'group' : [],
								 			p_x : 0 ,
								 			p_y : 0 ,
							    'getItem' : function(y,x){
										try{
											return this.group[y][x];
										}catch(e){
											return false;    
										};
							        },
							    'next' : function(){
							        if(this.group[this.p_y].length > this.p_x){
										var get = this.getItem(this.p_y,this.p_x);
										this.p_x++;
							        }else{
										this.p_y++;
										this.p_x = 0;
										if(this.group.length > this.p_y){
											var get = this.getItem(this.p_y,this.p_x);
											this.p_x++;
										}else{
											return false;
										};
							        };
							            if(get.toString() == "[object Object]")get = this.next();
							            return get;
							      },
							      'rotate' : function(){
										var temp = [];
										for(var i = 0 ; i < hvgObject.group.length; i++){
											hvgObject.group[i].reverse();
											for(var j = 0; j < hvgObject.group[i].length; j++){
												if(!temp[j]){temp.push([])};
												temp[j].push(hvgObject.group[i][j]);
											}
										}
										hvgObject.group = temp;						      		
							      		return this;
							      },
							      'reverse' : function(){
							      		var temp =[];
							      		for(var i = 0 ; i < hvgObject.group.length; i++){
							      			hvgObject.group[i].reverse();
							      		}
							      		return this;
							      },
								 'each' : function(fnc,args){
							        var i;
							        if(typeof fnc == 'function')while(i = this.next())fnc.call(i,i,args);
							        this.p_x = 0;
							        this.p_y = 0;
							        return this;
							      },
								 'getRows' : function(){
										return doEx(this.group);
								 },
								 'getAll' : function(){
								 		var o = [];
								 		while(i = this.next())o.push(i);
								 		return o;
								 },
								 'doEx' : function(){
								 		return doEx(this.getAll());
								 },
								 'toArray' : function(){
								 		return this.getAll();
								 },
								 'view' : function(){
								 	var x = this.group;
								 	var p = [];
								 	for(var i = 0 ; i < x.length; i++){
										var v = [];
										for(var j=0 ; j < x[i].length ; j++){
												 v.push(x[i][j].toString() !== "[object Object]" ? "■" : "□");
										}
										p.push(v.join(""));
									};
									alert("print\n"+p.join("\n"));
									return this;
								 }
							};
							/*
							*
							*
							*/
							 var orderFunc = { 
								 o : function(a,b){return a.geometricBounds[0]-b.geometricBounds[0] ;} , 
								 g : function(a,b){return b['n'] - a['n'];} , 
								 h : function(x){return Math.abs(x.geometricBounds[1]-x.geometricBounds[3]);}, 
								 c : function(x){return (x.visibleBounds[3]+x.visibleBounds[1])/2;}
							 };
							 //
						     var hl = 0;
						     this.each(function(){
								 try{
								 if(this.hasOwnProperty ("geometricBounds")){
								 hl += orderFunc.h(this);
								 }
								 }catch(e){};
							 });      
							 hl = hl/this.length;
							 //
							 var group = [];
						     this.each(function(){
									  if(!this.hasOwnProperty ("geometricBounds"))return;
						     			var ic = orderFunc.c(this);
						                for(var i = 0; i < group.length ; i ++){
							                if(Math.abs(ic - group[i].n) < hl*Sc){
								                group[i].item.push(this);
								                return;
							                }
						                }
						                group.push({n :ic , item : [this]});
						                return ;
						          	});
						    //
							var temp = []; group = group.sort( orderFunc.g);
							for(var i = 0; i < group.length; i++){temp.push(group[i].item.sort ( orderFunc.o))};
							/*
							*
							*
							*/
							var getCol = function(){
														var temp2 = [];
														var col = [];
														for(var i = 0; i < temp.length; i++){
															var wl = {};
															try {
																wl = temp[i].shift();
																col.push(wl);
															}catch(e){
																col.push(wl);
															};
														};
														var cl = 0;
														var ml = undefined;
														for(var i = 0; i < col.length  ; i++){
															try{
															if(!ml){
																ml = col[i].visibleBounds[0];
																cl = Math.abs((col[i].visibleBounds[2]+col[i].visibleBounds[0])/2);
															}
															if(col[i].visibleBounds[0] < ml){
																ml = col[i].visibleBounds[0];
																cl = Math.abs((col[i].visibleBounds[2]+col[i].visibleBounds[0])/2);
															}
															}catch(e){};
														}
 
														for(i = 0; i < col.length  ; i++){
															try{
																if(Math.abs((col[i].visibleBounds[2]+col[i].visibleBounds[0])/2 - cl) < (Math.abs((col[i].visibleBounds[2] - col[i].visibleBounds[0])))){
																	temp2.push(col[i]);
																}else{
																	temp2.push({});
																	temp[i].unshift(col[i]);
																};
															}catch(e){
																	temp2.push({});
															};
 
															};
 
														return temp2;
												};
							/*
								return Length
							*/
							var getL = function(){
								var l = 0;
								try{
								for(var i = 0; i < temp.length; i++){ l +=temp[i].length};
								}catch(e){};
								return l;
							};
							//
							var temp3 = []
							while(getL()){
								temp3.push(getCol());
							}
							//
							var temp4 = [];
							for(var i = 0 ; i < temp3.length; i++){
								for(var j = 0; j < temp3[i].length; j++){
									if(!temp4[j])temp4.push([]);
										temp4[j].push(temp3[i][j]);
								}
							}
 
							hvgObject.group = temp4;
							if(app.name == 'Adobe InDesign')hvgObject = hvgObject.rotate().rotate().rotate();
							return hvgObject;
		} ,
/*
*
*
*/
		'isPlural' :function(){
			var pluralWords = ['ArtStyles','Artboards','Brushes','CharacterStyles','Characters','CompoundPathItems','DataSets','Documents','GradientStops','GraphItems','GroupItems','InsertionPoints','Layers','LegacyTextItems','Lines','MashItems','NonNativeItems','PageItems','ParagraphStyles','PathItems','PathPoints','Patterns','PlacedItems','PluginItems','RasterItems','Spots','Stories','Swatches','SymbolItems','Symbols','Tags','TextFonts','TextFrameItems','TextRanges','Variables','Views','Words'];
		}
};
/*
*
*
*/
doEx.extend = function(target,source) {
	for (var property in source){
		try{target.prototype[property] = source[property];}catch(e){target[property] = source[property];};
	}
	return target;
}
 
doEx.prototype.init.prototype = doEx.prototype;
doEx.view = function(){
							doEx(app.activeDocument).view()
					};
//
//for Illustrator 
var config_for_illustrator = {
    'filters' : {
    	'ParentisLayer' : function(s){
    		this.each(function(){if(this.parent.constructor.name == 'Layer')s.TRUE.push(this)});
    		return s;
		},
    	'layers' : function(s){
			this.each(function(){
							if(this.constructor.name.match(/Document|Layer/)){
							            doEx(this.layers).each(function(){
							            	$.writeln(this.name);
                							s.TRUE.push(this);
                						});
							}
			});
			return s;
    	},
        'placedItems' : function(s){
                var extract = function(a){a.constructor.name == 'PlacedItem' ? s.TRUE.push(a) : (a.constructor.name == 'GroupItem' ? doEx(a.pageItems).each(function(){extract(this);}) : s.FALSE.push(a));}
                this.each(extract);
    	 		return s;
         },
        'rasterItems' : function(s){
                var extract = function(a){
 
					a.constructor.name == 'RasterItem' ? s.TRUE.push(a) : (a.constructor.name == 'GroupItem' ? doEx(a.pageItems).each(function(){extract(this);}) : s.FALSE.push(a));
				}
                this.each(extract);
    	 		return s;  
         },
        'pathItems' : function(s){
      	 		var extract = function(a){
					a.constructor.name == 'PathItem' ? s.TRUE.push(a)  :  (a.constructor.name.match(/CompoundPathItem|GroupItem/) ? doEx(a.pageItems).each(function(){extract(this);}) : s.FALSE.push(a) );
					}
                this.each(extract);
    	 		return s;
        },
        'compoundPathItems' : function(s){
 
        },
        'pathPoints' : function(s){
      	 		var extract = function(a){a.constructor.name == 'PathItem' ? doEx(a.pathPoints).each(function(){s.TRUE.push(this)})  :  ((a.constructor.name == 'CompoundPathItem' || a.constructor.name == 'GroupItem') ? doEx(a.pageItems).each(function(){extract(this);}) : s.FALSE.push(a) );}
                this.each(extract);
                return s;
            },
        'groupItems' : function(s){
                this.each(function(){
                			if(this.constructor.name == 'GroupItem'){
                							s.TRUE.push(this);
                			}else{
                				if(this.constructor.name.match(/Document|Layer/)){
                						doEx(this.groupItems).each(function(){
                							if(this.parent.constructor.name == 'Layer')s.TRUE.push(this);
                						});
                				}
                			}
                });
                return s;
        },
        'textFrames' : function(s){
                var extract = function(a){a.constructor.name == 'TextFrame' ? s.TRUE.push(a) : (a.constructor.name == 'GroupItem' ? doEx(a.pageItems).each(function(){extract(this);}) : s.FALSE.push(a));}
                this.each(extract);
				//$.writeln(s);
    	 		return s;
        },
        'textRanges' : function(s){
				var extract = function(){
					this.constructor.name == 'TextRange' && s.TRUE.push(this);
					(this.constructor.name == 'TextFrame'  || this.constructor.name == 'Story') && doEx(this.textRanges).each(function(tr){s.TRUE.push(tr)});
				};
				this.each(extract);
				return s;
        },
        'selection' : function(s){
                this.each(function(){(this.selected == true ||  this.selected == 'PathPointSelection.ANCHORPOINT') ? s.TRUE.push(this) : s.FALSE.push(this);});
                return s;
        }
   },
   'objectShortName' : {
        "I" : 'allPageItems',
    	"T" : 'textFrames', 
    	"G" : 'groupItems', 
    	"P" : 'pathItems', 
    	"PP" : 'pathPoints', 
    	"S" : 'selection', 
    	"PL" : 'placedItems', 
    	"L" : 'layers', 
    	"R" : 'rasterItems',
        }
}
 
//
//for InDesign
var config_for_indesign = {
'filters' : {
    'selection' : function(s){},
    'allPageItems' : function(s){
            this.each(function(){
                        doEx(this.allPageItems).each(function(){
                            s.TRUE.push(this);
                        });
            });
                        return s;
            },
    'groupItems' : function(s){
			this.each(function(){
				this.constructor.name == 'Group' ? s.TRUE.push(this) : s.FALSE.push(this);
			});
			return s;
	},
    'textFrames' : function(s){
    		if(this.constructor.name !== 'DocumentObjectsExtract')return s;
            this.each(function(){
				try{
                    this.constructor.name == 'TextFrame' ? s.TRUE.push(this) : (this.constructor.name == 'Group'  ? doEx(this.textFrames).each(function(){s.TRUE.push(this)}) : s.FALSE.push(this));
				}catch(e){}
			}); 
            return s;
    },
 
	'paragraphs' : function(s){
			var textFrames = this.filters.textFrames.call(this,{'TRUE' : [],'FALSE' : []});
			doEx(textFrames.FALSE).each(function(){
				(this.constructor.name == 'Text' || this.constructor.name == 'TextColumn' || this.constructor.name == 'Paragraph' ||  this.constructor.name == 'Cell' )&& textFrames.TRUE.push(this);
				this.constructor.name == 'Table' && doEx(this.cells).each(function(){textFrames.TRUE.push(this)});
			});
			doEx(textFrames.TRUE).each(function(){
				doEx(this.paragraphs).each(function(){s.TRUE.push(this)});
			});
			return s;
	},
	'words' : function(s){
			var textFrames = this.filters.textFrames.call(this,{'TRUE' : [],'FALSE' : []});
			doEx(textFrames.FALSE).each(function(){
				(this.constructor.name == 'Text' || this.constructor.name == 'TextColumn' || this.constructor.name == 'Paragraph'  || this.constructor.name == 'Cell' ) && textFrames.TRUE.push(this);
				this.constructor.name == 'Table' && doEx(this.cells).each(function(){textFrames.TRUE.push(this)});
			});
			doEx(textFrames.TRUE).each(function(){
				doEx(this.words).each(function(){s.TRUE.push(this)});
			});
			return s;
	},
	'characters' : function(s){
			var textFrames = this.filters.textFrames.call(this,{'TRUE' : [],'FALSE' : []});
			doEx(textFrames.FALSE).each(function(){
				(this.constructor.name == 'Text' || this.constructor.name == 'TextColumn' || this.constructor.name == 'Paragraph' || this.constructor.name == 'Cell' ) && textFrames.TRUE.push(this);
				this.constructor.name == 'Table' && doEx(this.cells).each(function(){textFrames.TRUE.push(this)});
			});
			doEx(textFrames.TRUE).each(function(){
				doEx(this.characters).each(function(){s.TRUE.push(this)});
			});
			return s;
	},
    'tables' : function(s){
			var textFrames = doEx(this).filters.textFrames.call(this,{'TRUE' : [],'FALSE' : []});
			doEx(textFrames.FALSE).each(function(){
				if(this.constructor.name == 'Table' || this.constructor.name == 'Cell' ){
					this.constructor.name == 'Cell' && this.tables.length > 0 && textFrames.TRUE.push(this);
					s.TRUE.push(this);
					}
			});
 
			doEx(textFrames.TRUE).each(function(){
				doEx(this.tables).each(
					function(){
						var innertable = doEx(this).filters.tables.call(this.cells,{'TRUE' : [],'FALSE' : []});
						doEx(innertable.TRUE).each(function(){
									this.constructor.name == 'Table' && s.TRUE.push(this);
							});
						s.TRUE.push(this);
						}
				);
			});
			return s;
            },
    'cells' : function(s){
			var tables = this.filters.tables.call(this,{'TRUE' : [],'FALSE' : []});	
			doEx(tables.TRUE).each(function(){
				doEx(this.cells).each(function(){s.TRUE.push(this)});
			});
			return s;
		},
    'rows' : function(s){
			var tables = this.filters.tables.call(this,{'TRUE' : [],'FALSE' : []});
			doEx(tables.TRUE).each(function(){
				doEx(this.rows).each(function(){s.TRUE.push(this)});
				});
			return s;
 
	},
},
'objectShortName' : {
        "I" : 'pageItems',
    	"T" : 'textFrames', 
    	"G" : 'groupItems', 
    	"P" : 'pathItems', 
    	"PP" : 'pathPoints', 
    	"S" : 'selection', 
    	"PL" : 'placedItems', 
    	"L" : 'layers', 
    	"R" : 'rasterItems',
        }
}
 
/*
*
*
*/
function getObjextX(objectType){
	var X = [];
	for(x=0; x < app.activeDocument.layers.length;x++){X.concat( Array.prototype.slice.call(app.activeDocument.layers[x][objectType],0));};
	return doEx(X);
};
 
//Extend
doEx.extend(doEx,{concat : Array.prototype.concat});
 
//
if(app.name == 'Adobe Illustrator'){
	doEx.extend(doEx,config_for_illustrator);
	for(var i in config_for_illustrator.filters){ doEx.prototype[i] = doEx.prototype.filter.curry(i);};
};
//
if(app.name == 'Adobe InDesign'){
	doEx.extend(doEx,config_for_indesign);
	for(var i in config_for_indesign.filters){doEx.prototype[i] = doEx.prototype.filter.curry(i);};
};
})();
/*
 
*/
var myDialogMaker;
(function(){
var setPosition = function(a,b){
return [a[0]+b[0],a[1]+b[1],a[2]+b[2],a[3]+b[3]];
};
extend = function(target,source) {
	try{
	for (var property in source){
			try{
				target.prototype[property] = source[property];
			}catch(e){
				target[property] = source[property];
			};
	};
	}catch(e){};
	return target;
}
myDialogMaker =function(option){return new myDialogMaker.prototype.init(option);};
myDialogMaker.prototype = {
	'init' : function(option){
						this.wD = new Window(option['type'],option['title'],option['pos'],option['properties']);
						extend(this.wD ,option['option']);
						option['layout'].length > 0 &&  this.items = this.buildLayout(this.wD,option['layout']);
						return this;
	},
	'dialog' : function (wD,pos,Config){
						var D = new Window('dialog' , Config['label'] , Config['pos'], Config['option']);
						try{
						Config['layout'].length > 0 &&  D.items = this.buildLayout(D,Config['layout']);
						}catch(e){
 
						}
						D.parents =wD;
						return D;
	},
	'statictext' : function ( wD,pos,Config){
								var sT = wD.add('statictext',pos,Config['label'],{});
								return sT;
	},
	'edittext' : function (wD,pos,Config){
								if(Config['width'] && Config['height'] && Config['size']){
									if(Config['label'])var sT = this.statictext(wD,setPosition([0,3,Config['width']-(Config['size']*10),20],pos),Config);
									var sET = wD.add(Config['type'],setPosition([Config['width']-(Config['size']*10),0,Config['width'],Config['height']],pos),Config['default'],{name:Config['name']});
								}else{
									var Size = 0;
									if(Config['label']){
												Size = Config['label'].length;
												var sT = this.statictext(wD,[pos[0],pos[1],pos[0]*1+Size*10,pos[3]],Config);
									}
									var sET = wD.add(Config['type'],[pos[0]*1+Size*10,pos[1],pos[2],pos[3]],Config['default'],Config['option']);
								}
								extend(sET ,Config['option']);
								return sET;
	},
	'checkbox' : function(wD,pos,Config){
								var cB = wD.add('checkbox',[pos[0],pos[1],pos[2]*1+Config['label'].length*10,pos[3]],Config['label']);
								extend(cB ,Config['option']);
								return cB;
	},
	'checkboxies' : function(wD,pos,Config){
								var GP = wD.add('group',pos,Config['label']);
								switch(typeof Config['list']){
										case 'object' :
											for(var x in Config['list']){
												this.checkbox(GP,checkpos,Config['list'][x]);
											}
										break;
								}
								return GP;
	},
	'radiobutton' : function(wD,pos,Config){
									var RB = wD.add('radiobutton',pos,Config['label']);
									extend(RB ,Config['option']);
									return RB;
	},
	'button' : function(wD,pos,Config){
								var bT = wD.add('button',pos,Config['label'],{name:Config['name']});
								extend(bT ,Config['option']);
								return bT;
	},
	'iconbutton' : function(wD,pos,Config){
							try{
							var SI = ScriptUI.newImage (Config['label']);
							var iB = wD.add('iconbutton',pos,SI);
							extend(iB,Config['option']);
							return iB
							}catch(e){
								return this.button(wD,pos,Config);
							}
	},
	'dropdownlist' : function (wD,pos,Config){
						var ddl = wD.add('dropdownlist',pos);
						Config['list'] && this.addListItems(ddl,Config['list']);
						ddl.selection = ddl.items[0];
						extend(ddl ,Config['option']);
						return ddl;
	},
	'treeview' : function(wD,pos,Config){
						var TB = wD.add('treeview',pos,'');
						Config['list'] && this.addListItems(TB,Config['list']);
						extend(TB ,Config['option']);
						return TB;
	},
	'listbox' : function(wD,pos,Config){
						var TB = wD.add('listbox',pos,'');
						Config['list'] && this.addListItems(TB,Config['list']);
						extend(TB ,Config['option']);
						return TB;
	},
	'flashplayer' : function(wD,pos,Config){
						var FP = wD.add('flashplayer',pos);
						extend(FP ,Config['option']);
						return FP;
 
	},
	'progressbar' : function(wD,pos,Config){
						var PB = wD.add('progressbar',pos);
						extend(PB ,Config['option']);
						return PB;
 
	},
	'addListItems' : function(TG,LIST){
								//$.bp();
								switch(LIST.constructor.name){
								case 'Function' : LIST(TG);
								//TG.selection = TG.items[0];
								break;
								case 'Array' :
								for(var x in LIST){
									TG.add('item',LIST[x]);
								}
								break;
								case 'Object' : 
								for(var x in LIST){
									TG.add('item',x);
								}
								//TG.selection = TG.items[0];
								break;
								}		
	},
	'slider'  : function(wD,pos,Config){
						var SL = wD.add('slider', pos, '');
						extend(SL ,Config['option']);
						return SL;
	},
	'group' : function (wD,pos,Config){
						var GP = wD.add('group',pos,Config['label']);
						GP.items = this.buildLayout(GP,Config['items']);
						extend(GP ,Config['option']);
						//if(Config.option.hasOwnProperty('orientation') && Config['option']['orientation'] !== '--')GP.layout.resize();
						return GP;
		},
	'panel' : function (wD,pos,Config){
						var GP = wD.add('panel',pos,Config['label']);
						GP.items = this.buildLayout(GP,Config['items']);
						extend(GP ,Config['option']);
						return GP;
	},
	'save' : function(){},
	'items' : {},
	'getItem' : function(name){
		return this.items.hasOwnProperty (name) ?  this.items[name] : false;
	},
	'temp' : {},
	'buildLayout' : function(wD,layout){
			var layout_L = layout.length;
			var myitems = {};
			for(var xi=0;xi<layout_L;xi++){
					//$.writeln(layout[xi]['type']);
					var ret = myDialogMaker.prototype[layout[xi]['type']](wD , layout[xi]['pos'] , layout[xi]);
					layout[xi].hasOwnProperty ('name') && typeof layout[xi]['name'] == 'string' && myitems[layout[xi]['name']] = ret;
			}
			return myitems;
	}
};
myDialogMaker.prototype.init.prototype = myDialogMaker.prototype;
 
})();
 
var  buildDialogLayout = myDialogMaker.prototype.buildLayout;
var addListItems = myDialogMaker.prototype.addListItems;
 
/*
ScriptUI Functions
*/
 
function setFont(o,f,t,s){
var g = o.graphics;
var FontStyle = {
REGULAR : ScriptUI.FontStyle.REGULAR ,
BOLD : ScriptUI.FontStyle.BOLD ,
ITALIC : ScriptUI.FontStyle.ITALIC ,
BOLDITALIC :ScriptUI.FontStyle.BOLDITALIC
}
g.font = ScriptUI.newFont(f,FontStyle[t] || ScriptUI.FontStyle.REGULAR,s);
}
function setFontStyle(o,f,t,s,pt,c,w){
	setFont(o,f,t,s);
	setFGC(o,pt,c,w);
}
function setFGC(o,t,c,w){
try{
var g = o.graphics;
g.foregroundColor = g.newPen(g.PenType.SOLID_COLOR,c,w || 1);
}catch(e){}
}
 
function setBGC(o,t,c){
try{
var g = o.graphics;
g.backgroundColor = g.newBrush(g.BrushType.SOLID_COLOR,c);
}catch(e){}
}
 
function drawRact(target , rac) {
	var x = 0 , y = 0 , z = {};
	try{
		target.graphics.newPath();
		target.graphics.rectPath(rac[0],rac[1],rac[2],rac[3]);
		z = target.graphics.newBrush(target.graphics.BrushType.SOLID_COLOR, [rac[4][0], rac[4][1], rac[4][2], 1] );
		target.graphics.fillPath(z);
	}catch(e){
		$.writeln("drawRact : " + e);
	}
 
};
 
function drawRactData ( target , racdata ) {
		var x = 0 , y = 0 , z = {} , rac = {};
	try{
	for(i = 0 ; i < racdata.length ; i++){
		rac = racdata[i];
		target.graphics.newPath();
		target.graphics.rectPath(rac[0],rac[1],rac[2],rac[3]);
		z = target.graphics.newBrush(target.graphics.BrushType.SOLID_COLOR, [rac[4][0], rac[4][1], rac[4][2], 1] );
		target.graphics.fillPath(z);
	}
	}catch(e){
		$.writeln("drawRact : " + e);
	}
};
 
function drawText(target,t,point){
	var x = 0 , y = 0;
	try{
	x = typeof point[0] == 'number' ? point[0] : 0;
	y = typeof point[1] == 'number' ? point[1] : 0;
	}catch(e){
 
	}
 
	try{
	target.graphics.drawString(
		t.text , 
		target.graphics.newPen(target.graphics.PenType.SOLID_COLOR,[t.color[0],t.color[1],t.color[2],t.color[3]],1) ,
		x ,
		y ,
		target.graphics.font
		);
	}catch(e){
	}
}
//DrawMosaicPict
//target :
//picData :
function drawMosaicPict (target,picData,point){
var px = 0 , py = 0 ;
try{
px = typeof point[0] == 'number' ? point[0] : 0;
py = typeof point[1] == 'number' ? point[1] : 0;
}catch(e){
 
}
try {
	   var r = g = b = 0 , z = {};		 
       for(var i = 0 ; i < picData.height  ; i ++){
			  for(var j = 0 ; j < picData.width ; j++){
				target.graphics.newPath();				
				target.graphics.rectPath((j*picData.pictsize+px),(i*picData.pictsize+py),picData.pictsize,picData.pictsize);
				if(picData.type == 'mono') {
					r = g = b = picData.data[i*picData.width + j];
				}else{
					r =  picData.data.r[i*picData.width + j];
					g =  picData.data.g[i*picData.width + j];
					b =  picData.data.b[i*picData.width + j];
				};
				z = target.graphics.newBrush(target.graphics.BrushType.SOLID_COLOR, [r, g, b, 1] ); 
				target.graphics.fillPath(z);
			}
		}
} catch( ex ) {
          $.writeln("xxx : "  + ex);
}
};
 
//MosaicButton
function MosaicButton (targetButtom , mozpic) {
	targetButtom.onDraw = function(){drawMosaicPict (this, mozpic.normal , mozpic.point)}
	try{
	if(mozpic.mouseover){
			targetButtom.addEventListener ("mouseover", function(e){
			e.target.onDraw = function(){drawMosaicPict (this, mozpic.mouseover  , mozpic.point)};
			e.target.notify('onDraw');
			} , false);
			targetButtom.addEventListener ("mouseout", function(e){
			e.target.onDraw = function(){drawMosaicPict (this,mozpic.normal , mozpic.point)};
			e.target.notify('onDraw');
			}, false);
	}
	}catch(e){
 
	}
}
//

InDesign + JavaScript = ?: google edition

昨日行ってきたGoogleエディション説明会@新大阪の個人的メモ。

Googleエディションの土台としてGoogleブックスがある。まずはそのGoogleブックスの説明から。

Googleブックスとは書籍の全てのページをデジタル画像化し、その画像からOCRをかけてテキストデータを拾いだす。そのテキストをもとに検索できるようにする。
ユーザー表示用にはページのデジタル画像を、検索にはテキストが使われるという仕組み。

書籍の提供(Google側からすると入手)方法には二通りある。
・パートナープログラム=出版社から提供
・ライブラリプロジェクト=図書館蔵書を提供(日本だと慶応大学など、アメリカ国外では著作権が切れたもののもい対象)

パートナープログラムに参加している出版社は全世界で3万社、200万タイトルが提供されている。アメリカではほぼ全ての出版社が参加している(例えばピアソン、シュプリンガーや、大学出版局など)。日本では400社強、4万冊といったところ。先日のブックフェア以降増加傾向にあるとのこと。

Googleブックスでは、表示できるページ(プレビュー)が1ヶ月20%に制限されている(のだが、参加者より80%ほど見えてしまっているとの苦情があり)。また、一部の内容はどんな場合にも表示されないようにしているとのこと。印刷、保存、コピーは不可だが、スクリーンショットでの保存はできる(OSレベルの機能は制限しようがないらしい)。出版社はいつでも書籍を追加・削除可能。

出版社からの書籍の提供方法は、PDFまたはEPUBか書籍本体1冊献本。Google側でそれをデジタル化する。書籍本体の場合は画像化→OCR。PDFの場合でも画像として扱い、OCRにかけるとのこと。また、OCR後のテキストデータの校正は一切に行われない。検索用に使用するという目的にはそれで十分な精度があるらしい。OCRエンジンは常にアップデートしており、定期的にOCRをかけ直して、テキストデータの精度を上げていくつもりらしい。

Googleブックスの使い方としてはGoogleブックスから直接検索する場合と、通常のGoogleの検索から飛んでくる場合があり、圧倒的に後者の方が多いらしい。画面設計として、左カラムが購入用や版元への外部リンク、メインカラムがページ画像となる。出版社には、詳細なデータやサマリーレポートがGoogleより書籍タイトルごとに提供される。

Googleエディションは簡単に言えば、Googleブックスはで20%しか見れないところを有料で100%すべて見せますよ、というもの。様々なデバイスでウェブブラウザを介して読む、という形態。一回購入すれば、どのデバイスでも読むことができる。ウェブブラウザ以外にiphoneアプリとしてブックリーダー的なものを提供していきたいと考えている。
ブラウザでの表示以外に、出版社側のオプションとして提供したPDFやEPUBといったファイルのダウンロードも可能。DRMをかけた形でダウンロードする。またHTML5では、ブラウザそのものにオフライン機能があるため、それを利用することもできる。
AmazonやiBookと違うのは、購入をどこでもできるようにするということ。例えば、Amazonからでも楽天ブックスからでも版元のサイトからでもGoogleブックスを購入できるようにする。

販売価格は版元の希望小売価格で、版元の取り分はその小売価格の51%以上。取り分の割合は提供タイトル数だったり提供方法(PDFか書籍本体か)だったりいろいろな条件で変わる様子。Googleエディションは電子書籍ということで、再販価格制度には縛られないものとGoogleは理解しており、販売価格は一定ではなく、市場動向により下がることもあり得るが、積極的にGoogle側でコントロールするつもりはない様子。

課金方法はGoogleチェックアウトが基本。自社サイトでの販売でもGoogleチェックアウトを利用できる。

開始時期は、まずアメリカでのこの夏。次にヨーロッパは秋。日本は年明けを予定している。

他には、
・クラウドブックスの場合、一つのアカウントで同時アクセスできるのではないか?という質問に対して、常識的に同時アクセス数が多い場合はスパムと見なし制限する、との回答。
・ファイルのダウンロードは回数制限を設定するかもしれない。
・スキャンできるのは今のところせいぜいA4サイズまで。大判は想定していない。また、紙質によっても対応できないケースがある。ただ、PDF提供ならその問題はない。
・プレビューの制限量は20%だが、もっと多くすることは出版社側でコントロールできる。統計的にはプレビュー量を多くした方がよく売れている。
・Google検索と一体化しているため、現在登録している200万タイトルのうち8〜9割は毎月誰かがプレビューを見ている。

他にも色々あったような気がするが。。。個人的には、プロモーションとしてGoogleブックスを使うのは全然ありかなぁ、と。
エディションまでいくとなると、同時アクセスあたりの問題が確実に解決されていないと提供しづらい。大学のゼミ等での少部数購入ってのが積み重なっているのが学術系テキストなわけで。
ユーザーとして考えると、iPadで専用アプリが出ればかなり使えそう。課金方法がどれくらいシンプルかつ安全かつ楽か、てのが気になる。
マーカー引いてそのデータを共有したりとかこのフレーズをツイッターで、みたいなソーシャルな機能はまったく想定していないようだ。そういう意味では、電子書籍推進者が一番批判しそうな形(テキストのコピーも出来ない、リフローも出来ない、紙の本の電子化以外の何ものでもない)の電子書籍と言える。
現在、プレビュー機能を紀伊国屋のBookwebに提供している模様。いずれブログパーツ的に一般ユーザーも使えるようになるのかもしれない(もちろん出版社の許可があってだとは思うが)。

ものかの: WPのテーマを大改造しました

ブログにしてからず〜っとWPのテーマに不満でして、実はもう見るのもイヤになってました。そこで思い切って「旧サイトのデザインそっくりにしてしまえ」と大改造を敢行。やはりこっちの方が落ち着きますな。まだちょっと中途半端ですけ [...]

たけうちとおるのスクリプトノート: 20)配置されたオブジェクトを個々に拡大・縮小

InDesignCS4で配置されたオブジェクトを個々に拡大・縮小します。(CS3でも動くと思います)

■■■使い方■■■
入ったオブジェクトを選択します。
スクリプトパレットのオブジェクトを個別に変形.jsxをダブルクリックします。
数値を入力しOKボタンをクリックすると選択されたオブジェクトが個々に拡大・縮小します。

oimoh - はいさい!(InDesign JavaScript CS3

を参考にさせていただきました。ありがとうございます。

ダウンロードはこちら
resizeobj.zip

InDesign39

ディザInDesignブログ: オブジェクトモデル図UPしました

毎回のことながら、ツリー図だけ先にアップしました。
この先に各プロパティ等の変更比較表を作っていかなくちゃいけないんだけど、今回は年内完成は無理かも。変更が激しすぎ。
http://www15.ocn.ne.jp/~preopen/iddom/about.html

ディザInDesignブログ: スクリプト面から見たInDesign CS5の新機能(5)PageItem.NameとPageItem.Label

PageItemにNameプロパティがつきました。これはせうぞーさんの言われているとおり(http://d.hatena.ne.jp/seuzo/20100724/1279904204)なんですが、「app.scriptPreferences.versionを一時的に書き換える方法」では本当に一時しのぎでしかないですね。
もともと、itemByNameは、オブジェクトにNameがあればそれを参照し、なければLabelを参照するようになっているので、PageItemにNameプロパティがついた以上、Nameプロパティを参照するのが自然です。どうしてNameプロパティがついたのかは川村さんの言うとおり(http://geocities.yahoo.co.jp/gl/lcs_kawamura/view/20100726/1280101409)、レイヤーパネルのデザインの変更によるものなので、その一環として、今までオブジェクトとして扱われてこなかったEPSTextが追加されたのでしょう。

じゃあ、今までitemByNameを使用していたスクリプトはどうするかというと、ドキュメントに変更を加えるのであれば、変更はいりません。今後CS5で扱いたいドキュメントに対して次のようなスクリプトを実行してやればいいだけです。
var doc=app.activeDocument;
for (i=0;i<doc.allPageItems.length;i++){
    doc.allPageItems[i].name=doc.allPageItems[i].label;
    }

どうしてもスクリプトラベルを使いたいという人には、申し訳ありませんが、itemByNameができる以前の環境(InDesign 2.0かな?)に戻ってもらうしかないでしょう。下の例ではallPageItemを使ってますが、範囲が広すぎて時間がかかるかもしれません。Pageで絞るとかオブジェクトの種類で絞るとかしないとね。
var doc=app.activeDocument;
for (i=0;i<doc.allPageItems.length;i++){
       if (doc.allPageItems[i].label == "hoge") break;
   }
var targetPageItem = doc.allPageItems[i];

ところでPageItem.Nameってどこで設定するんでしょうね。スクリプト以外で設定する箇所が見当たりません。まあ、スクリプトを使わない人には基本的に不要ですからね。仕方ないので、名前をつけたいPageItemを選択した状態で次のスクリプトを実行しましょうか。
if (app.selection.length == 1) app.selection[0].name=prompt("オブジェクトの名前を入れてください");

CS5でいろいろ変わりすぎてなかなかオブジェクトモデルの完成にたどり着きません。ふー

----------------------------------------------------------

8月26日 追記

PageItem.Nameはレイヤーパネルでオブジェクト名をダブル(以上)クリックすると変更できます。しつこく連続クリックしないとオブジェクト名がアクティブにならなかったので気がつきませんでした。ここらへんの情報は、InDesignの勉強部屋のStudy Room内、InDesign CS5のNo.3にあります。

ディザInDesignブログ: CS5のアニメーションとボタンのテスト

勉強部屋のBBSで書き込んだとおり、InDesign CS5で簡単なアニメーションとボタンのテストを行いました。
http://omachi.blog.ocn.ne.jp/preopen/files/cs5_anim2.html

そういえばYUJIさん、8月20日に金沢に来てセミナーするんだ。たぶん行きますよー。でもちゃんと申し込みできてるのかしら。

たけうちとおるのスクリプトノート: 電子書籍勉強会でお話させていただきます。

7/24日 大阪DTPの勉強部屋電子書籍勉強会でお話させていただきます。

それを記念して(自分を追い込むために)電子書籍のホームページを立ち上げました。
電子書籍やクロスメディアノートこちらもよろしければご覧下さい。

ePubを少々いじって実験とかしていたのでパネラーとして招待されたのですが、だんだんDRMに興味が出てきてPDFに認証をかけるDEMOをさせていただきます。(そのかわりePubは勉強不足だ)


======================
 セキュリティ 
PDFに認証をかけて違法コピー出来ないようにする仕組みが いくつかのベンダーさんから提供されていますが、

もう少し簡単なものを試験的に作ってみました。 
======================

 

内容としては
PDFに簡易DRMをしてみる

iPad用に本棚をHTML5で作る

あたりの話をしたいと思います。自分の中ではiBookStoreやAppStoreをはじめ、その他同様のサービスを使って販売するより、自前でなんとか出来ないかを考えています。もうキャンセル待ちみたいですが、興味のある方は、ぜひご参加ください。(懇親会に?)もしくはご連絡いただければと思います。特に出版系の方はいろいろご意見を聞かせていただけるとありがたいです。

InDesign + JavaScript = ?: app-book

個人的なかなり大雑把なカテゴライズとして、紙の書籍の意味合いを保持したものの電子書籍をe-bookと呼び、変化したものを暫定的にapp-bookと呼ぶことにしよう。
前者の規格としては、PDFとかEPUBがあり、基本的には紙の書籍をある程度忠実に再現するものだ(EPUBだとリフローすることで見た目は変わるけど)。
後者は、アプリとして書籍の機能を拡張させたようなもの。中身の並べ替えや、抽出・検索が行えるようなもの、また電子体でなければできないような機能のあるものだ。例えば、iPhoneアプリで言えば、有名な大辞林やウィズダム英和辞典などがある。また、画像をレイヤーして説明するようなものがある(CD-ROM等でよくある)。

前者については、やはりPDFで十分であるように思える。頑張ってEPUBに手を出す気がしない。後者はいろんなやり方があると思う。iPhoneアプリを作ってしまうというパターン。またはウェブアプリを作るパターン。比較的教育コストが低くて、将来性もあるとしたらウェブアプリなのではないだろうか、ということで、php+mysqlの勉強を始めた。これが面白い。というか新たなプログラム言語を勉強するのは無条件に楽しいのだが、phpもjavascriptと同じぐらい手軽にプログラムを走らせることができるのがいい。
会社で出してる用語集のデータをデータベースにぶっこんで何か面白いものができないか模索中の今日この頃である。

ものかの: ロック解除できません!

かわいすぎて♡

ディザInDesignブログ: スクリプト面から見たInDesign CS5の新機能(4)SplineItemとPageItem

SplineItemは「図形」と訳したけれど、従来からあるRectangle、Oval、Polygon、GraphicLineをまとめて扱うときに使うものらしい。

CS4まではページ上にレイアウトされたオブジェクトをいくつかまとめて扱いたいときはPageItemしかなかったんだけれども、CS5からは図形関係だけをまとめて扱いたいときにこのSplineItemが使えるようだ。

ただ注意が必要なのは、従来 PageItemが持っていたプロパティのいくつかがSplineItemへ移動している可能性があるということ。まだ詳しくは調べていないのだが、従来のスクリプト(特に図形関係を扱っているもの)でエラーが発生する場合はここを確認することになりそう。

ディザInDesignブログ: スクリプト面から見たInDesign CS5の新機能(3)EPSText

バージョンが上がって追加されたオブジェクトは、新機能をみれば大体想像がつくものだが、中には全く想像がつかないものもある。こういうときはあてずっぽうで色々試してみるしかない。
このEPSTextもそう。InDesign CS5の新機能でEPSTextと関連がありそうな機能は見当たらないので、とにかくEPSと言えばIllustratorと思い、Textを手がかりに色々動かして見る。結果、これは「イラストレータからコピーしてきたテキスト」だと判明。何で今更こんなオブジェクトが? と思ったら、実はこれはPageItemのひとつなのに今まで無視されてきたものだった。

もしかするとIllustrator以外のアプリケーションでもAICB形式でクリップボードに保存できるなら、それをInDesignにペーストしたときにEPSTextになる可能性はあるのだが、今のところ他にも調べなきゃいけないオブジェクトがあるのでこの辺はスルー。とりあえずオブジェクトモデル上では「イラストレータからコピーしてきたテキスト」と表現することにしよう。

では、InDesign CS3とCS5で比較してみよう。まず、環境設定。InDesign側では[ペースト中にPDF形式を優先する]のチェックを外す。Illustrator側ではAICB形式を有効にする。

Eps01_2

Eps02

これで準備完了。あとはIllustratorで適当に文字を含んだ絵を描いてコピー、InDesignの新規ドキュメントにペーストする。

Illustratorで作ったもの

Eps03

InDesignにペーストすると、グループ化されて配置されるので、グループ解除を行う。CS3の場合では、このように。

Eps04

Eps05

画面上、文字ずれが発生しているが今回のテーマとは関係ないので無視。

ここで次のスクリプトを実行。

var doc=app.activeDocument;
for (i = 0; i < doc.allPageItems.length; i++ ){
    $.writeln(doc.allPageItems[i].constructor.name);
    }
$.writeln(i);

するとExtendScriptToolkitのコンソール画面に

Eps08

と表示されて、テキスト部分は無視されていることが分かる。これをCS5で同様に行うと、

Eps06

Eps07

画面上で文字化け文字ずれが発生しているが、これも今回のテーマと関係ないので無視。そして先ほどのスクリプトを実行させると

Eps09

という具合にオブジェクトとして認識されたのでした。

でも、今の所できるのは拡大縮小、回転、反転など。テキストとしての属性を取り出せたらもっといいのにな。

ものかの: あまおかさんのツイートがすごすぎる

知りたいって欲求の多くがウェブに食われて消費されてる いつもキレてる @logicsystem あまおかさんですが、この26文字は箴言。

ディザInDesignブログ: スクリプト面から見たInDesign CS5の新機能(2)WatermarkPreference

新機能紹介の2回目はウォーターマークである。
スクリプトではウォーターマークを作成できるようになっている。ところがこの機能、 InDesignのメニューをあちこち探しても見当たらない。ひょっとするとUI(ユーザーインターフェイス)からは設定できず、スクリプトからのみ設定できる機能なのかもしれない。もしUIから設定できることができた人は教えてください。お詫びの上訂正いたします。

WatermarkPreferenceはアプリケーションの設定とドキュメントの設定の2つがあって、アプリケーションで設定すると、以降作成されるドキュメント全てに反映される。普通はドキュメントレベルでの設定になるんだろうな。JavaScriptでの例は次の通り。

ウォーターマークを設定する
var wm=app.activeDocument.watermarkPreferences;
wm.watermarkText = "㊙"; //表示する文字
wm.watermarkFontPointSize = 300; //文字の大きさ
wm.watermarkRotation = -30; //表示する角度
wm.watermarkDrawInBack = false; //背景に表示するかどうか
wm.watermarkDoPrint = true; //印刷するかどうか
wm.watermarkVisibility = true; //画面に表示するかどうか

実行前
Ws01
実行後
Ws02

watermarkPreferenceで設定できる項目は上記スクリプト中のほか、座標位置、フォント、色などがあります。お好みでどうぞ。解除の仕方はわざわざ書きませんが、上のサンプルを見れば分かりますよね。下手に設定して解除できなくても知りませんからね。

なお、これを知らない人に、便利なスクリプトだよって渡すのは厳禁です。とーってもやりたい誘惑に駆られますけどね。

ものかの: 電子書籍をサービス業に

サービス(英: service)は、経済用語において、売買した後にモノが残らず、効用や満足などを提供する、形のない財のことである。wikipedia 電子書籍を出版物小売業のまま「モノ売り」しているとすぐにやがて限界がき [...]

ディザInDesignブログ: スクリプト面から見たInDesign CS5の新機能(1)ToolBox

本題の前に。直前のエントリに追加しました。ちょっと解決が難しいかも知れませんねー。社内では当面、共存禁止令でいこうかと^^;

その前、さらにその前のエントリ、コメントありがとうございます。おかげさまで大分分かってきました。

では本題。ToolBoxはツールパネルのこと。なぜこの名前かは知らないけれど、CS5からはツールパネルのツールをスクリプトで切り替えることができます。JavaScriptでの使用例を書きます。

現在のツール名を表示する
alert(app.toolBoxTools.currentToolName);
ツールを消しゴムツールに切り替える
app.toolBoxTools.currentTool = UITools.ERASE_TOOL;

てな感じです。使うことあるかなぁ?

ディザInDesignブログ: InDesignクラッシュの犯人が判明! 今度こそ不具合フォームへ

昨日の問題がついに判明しました。といっても原因は分かりません。あくまでも必ず再現する手順が判明したということです。今度こそこれを持って不具合フォームへ書き込みだ!

発生環境
Windows Vista もしくは Windows 7 (もしかするとWindows XP も?)
OpenOfficeがインストールされています。
(私の環境では最新の3.2.1、Java 6 Update 20)

発生手順
OpenOffice calc で新しいドキュメントを作成します。
Ws02
適当なセルに適当な文字を入力して、そのセルをコピーします(つまりクリップボードに格納する)。
Ws05
OpenOffice を終了します。コピーに使ったドキュメントは破棄してかまいません。
Ws06

InDesign CS5 を起動し、新規ドキュメントを作成します。
Ws07
ページ上で右クリックします。
Ws10
するとInDesign CS5 はクラッシュしちゃいます。
Ws11
最後はこう。
Ws12

ということで、Microsoft と Adobe と ORACLE の誰が悪いか分かりませんが、CS5 からJavaの機能を使ってるので、それが裏目に出たのかも。

7月8日 追記

右クリックでなくても、メニューの[編集]をクリックしただけでもクラッシュします。どうもメニューを表示させるのに、ペースト用のメニュー(ペースト、フォーマットなしでペースト、グリッドフォーマットを適用せずにペースト)の有効・無効を判断する必要があって、クリップボードの中を解析しているんだと思います。その過程で予想外のエラーが発生しているんでしょう。

ちなみにIllustratorでは発生しません。クリップボードの解析方法が違うんだと思います。

原因としては、OpenOffice Calcがクリップボードの仕様を外れたデータを放り込んだのか、InDesignがクリップボードの中身をExcelデータだと勘違いして間違った解析をするのか、そもそもInDesignのクリップボードデータの解析手順そのものがおかしいのか、Microsoftによるクリップボードのデータ仕様がおかしいのか、が考えられます。

私の勘では「Excelデータだと勘違いして間違った解析をした」に1票! ですが、そうであればKingsoft Officeでも発生する可能性があります。こっちの検証はAdobeの人にお任せしましょう。きっと読んでるでしょうから(不具合フォームにこのページを見てねって書いといたから^^)。

ディザInDesignブログ: スクリプト面から見たInDesign CS5の新機能(0)前置き

先のバグか? の件は原因不明のままです。

それはおいといて。

InDesignではバージョンが上がるとスクリプトもバージョンが上がって新機能がついたりします。しかーし、Adobeはそのことについて一切アナウンスしないので、どこがどう変わったのか、新しくなったのかは、前バージョンと比較することでしかわかりません。そして、その作業は非常に大変ですし、必要性もあまり高くありません。普通にスクリプトを書いている分には、新しいバージョンで問題なく動作すればいいわけですし、新しい機能を使うことで格段に便利になるわけでもないからです。(格段に、というのは手作業からスクリプトを用いた自動化に変わることに比較して、という意味)

ですから、新しいバージョンで動作しなくなった時点で初めて変更箇所や新機能を知るのが一般的です。そこで転ばぬ先の杖、ということで、しばらく「スクリプト面から見たInDesign CS5の新機能」ということで書いていきたいと思います。

てゆうか、オブジェクトモデルの完成には、もうしばらく時間がかかりそうなので、その検証中に理解したことを書き綴っていくだけなんだけども。

ところで以下のオブジェクトが何のことなのか分かりません。誰かあてずっぽうでもいいからヒントないですか?

  • PlaceGun
  • MultiStateObject
  • MutationEvent
  • Change(CS4から引き続き)

ディザInDesignブログ: 早速バグみっけ?

オブジェクトモデルはなかなか進んでいません。というのもこんなときに限って仕事が混んでたりするんだな。今日校正出したのでしばらく集中できるぞっと。でも試用期間が残り少ない。急がなければ。

ということで色々やっていたら、早速バグに遭遇! ありゃりゃ。

手順:新規ドキュメントに何でもいいから図形を描きます。四角形でも直線でも。描いたら選択状態になっているので、そのままメニューから[オブジェクト]-[キャプション]-[キャプション設定]を開いて、そのまま何もせず[OK]ボタンをクリックします。選択状態になっている図形の上で右クリックします。はい、InDesignが落ちました~。

再現できた人は、このブログのスクリプトリンクにある、不具合報告フォームから報告してね。

21:07 追記

てゆーか、私の環境(Windows Vista)では、あらゆる右クリックで落ちてしまう。ここまでひどいと、私だけのような気がしてきた。

7月7日 追記

結局OSから再インストールしました。すると右クリックが使えるようになりました。(ついでに試用期限も延長になりましたが、これは内緒でお願いします^^)。原因は不明です。何かのアプリケーションとバッティングしているのかもしれません。わかりましたらまた報告します。

ScriptClip: オブジェクトの位置を順送りで入れ替える

ScriptClip
<pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">//2010-07-03 </span> #target <span style="color: #3366CC;">'indesign'</span><span style="color: #339933;">;</span> #include <span style="color: #3366CC;">'c.js'</span><span style="color: #339933;">;</span> #include <span style="color: #3366CC;">'hvg.js'</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #003366; font-weight: bold;">var</span> temp <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #003366; font-weight: bold;">var</span> GRP <span style="color: #339933;">=</span>hvg<span style="color: #009900;">&#40;</span>app.<span style="color: #660066;">activeDocument</span>.<span style="color: #660066;">selection</span><span style="color: #339933;">,</span> 0 <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//0: Z , 1 : N </span> GRP.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>temp.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">geometricBounds</span><span style="color: #009900;">&#91;</span>0<span style="color: #009900;">&#93;</span> <span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">geometricBounds</span><span style="color: #009900;">&#91;</span>1<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> temp <span style="color: #339933;">=</span> c<span style="color: #009900;">&#40;</span>temp<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> temp.<span style="color: #660066;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> GRP.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #003366; font-weight: bold;">var</span> z <span style="color: #339933;">=</span> temp.<span style="color: #660066;">loop</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">move</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>z<span style="color: #009900;">&#91;</span>1<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>z<span style="color: #009900;">&#91;</span>0<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>

たけうちとおるのスクリプトノート: 20)オブジェクトを移動

InDesignCS4でに選択したオブジェクトを設定値で移動します。(CS3でも動くと思います)

スクリプトパレットの「このスクリプト」をダブルクリックします。
選択したオブジェクトが移動します。ただこれだけのソフトなのですが
オブジェクトを100Pぐらいを同じ量移動しないといけない時とかに重宝します。

スクリプトを開き下記のように設定すると右へ7.45動きます。
(単位はドキュメント依存)
var xmovevalue = 7.45
var ymovevalue = 0

ダウンロードはこちら
moveobj.zip

InDesign38

ものかの: ターミナルでファイルの中身を素早く確認する方法

勉強会のショートセッションで、OS X のターミナルでファイルをバイナリで開く方法をちらっとお話しました。Illustrator ファイルなどのバージョン確認に便利かも、と思って xxd コマンドを使ってみたのですが、よ [...]

ものかの: DTPの勉強会@東京 第1回

DTPの勉強会@東京 第1回に参加してきました。今回もとても良いセッションばかりでした!(私のは除く) さて、メインセッション「出力・印刷の現場 ─データを受け取った現場で起こっていること─」の内容は 印刷事故を無くすコ [...]

ものかの: textutil にあるといいな

man textutil すると、現在 OS X 10.6 で変換可能なフォーマットは txt, html, rtf, rtfd, doc, docx, wordml, odt, or webarchive こうなってい [...]

ものかの: DTP Booster 014

「電子出版/電子書籍」をテーマに開催された DTP Booster 014 に行ってきました。 このテーマは、制作側が作り方のノウハウだけ考えればすむものではなく、流通、マーケットも含めた全体から演繹的に作り方が選ばれる [...]

InDesign + JavaScript = ?: iPad来た。

やっとiPad届いた。アップルのオンラインストアで注文して2週間弱。
自分は16GBのWifiのみにしたのだが、やはり3Gにしておけばよかった…。1500円のプリペイドに。まぁ後の祭なので仕方があるまい。。。
さて、使用感。やはり画面は大きい。B5版の書籍のPDFと、A4変型判(学会誌に多い)のPDFをiPadで読んでみる。画面が縦ならズームしなくても1ページ問題なく読める。これは大きい(正直、モニタだといくら画面が大きくても読む気がしない)。そしてPCに詳しくない人にとっても抵抗があまりないように思える。実際、iPadの購入層というのは、ライト層が多いようだ。
コンテンツ供給側としては、iPad的なタブレット端末が爆発的に普及してもらいたいものだ。
規格の話で言えば、過去の出版物についてはPDFでOKなのは間違いない。これぐらいの画面サイズがデフォルトならば、リフローさせる必要性がないと思うし、そこで手間が発生するとPDF化が止まってしまう。
現在、巷の関心の対象は未来の規格。ePubなのか? 中間フォーマットてのも気になる。

ものかの: InDesign Glee 1.1.0

InDesign Glee 1.1.0 をちゃんと download ページに追加しました。6/7 に UP したものとまったく同じです。 DTPの勉強会@東京 第1回で「InDesign Glee のバージョン判別方 [...]

ディザInDesignブログ: CS5 Object Model 始動

ようやっと、ようやっとですよ。CS5の体験版をインストールしました。で、早速オブジェクトモデル図の作業に取り掛かってます。InDesign CS5の新機能を確認することなく、オブジェクトモデル図にかかろうという、今回はとっても無茶苦茶なアプローチをしてます。だってみんなに先に書かれてるんだもん。

ということで調べ始めましたが、もうCS5にしなくちゃ気分満々。だって全てのページアイテムにparentPageプロパティがあるんだもん。今まで入れ子構造が複雑なオブジェクトがあった場合のページ番号の取得の大変さときたらもう、かなり嫌でしたからね。これからはparentPageプロパティで一発取得! だといいなあ。

あと、わけの分からんものがかなり増えてます。backgroundTaskとかidleEventとかidleTaskとか、Event類はかなり増えてます。メニューイベントだけでも使いこなせなかったのに、こんなに増えて使えるんだろうか。

あと、PDF出力が変わったんですね。InteractivePDFExportPreferenceというのができました。じゃあ、従来のPDFExportPreferenceはPrintPDFExportPreferenceに変わったんだろうか、と思いきやPDFExportPreferenceのままでした。まずは一安心。

こんな感じでしばらく籠もるかも。です、はい。

たけうちとおるのスクリプトノート: 24)白のオーバープリントのチェックと解除

●実行環境
IllustratorO.app
Illustrator CS3、CS4のオーバープリント解除処理をします。

AI_CheckOverPrint.app
Illustrator CS3、CS4のオーバープリントを調べオーバープリントのメッセージを表示します。

●インストール
「IllustratorO.app」を好きな場所にコピーしてください。

●実行方法
「IllustratorO.app」をダブルクリックして起動します。
TEXTのみボタン
TEXTのみオーバープリント解除を行います。

パスのみ
パスのみオーバープリント解除を行います。

全て実行
TEXTをパス全てオーバープリント解除を行います。

※アピアランスでフチ文字などが適応されたテキストには効きません。
(これは標準フィルタと同じですがスクリプトで制御できないようです)

白のオーバープリントドキュメント

オーバープリントプレビュー

AI_CheckOverPrint.appでチェックできる。オーバープリントがあればExistの表示

IllustratorO.appは解除。

解除結果のオーバープリントプレビュー

■動作の定義
行間自動の改行に色をつけると行間がくずれるため改行以外にオーバープリント解除をする。

すべてのテキストフレームに対して
改行以外で塗りがグレースケールのK0の文字の塗りにオーバープリント解除
改行以外で塗りがCMYKモードでのC0M0Y0K0の文字の塗りにオーバープリント解除
改行以外で線がグレースケールのK0の文字の線にオーバープリント解除
改行以外で線がCMYKモードでのC0M0Y0K0の文字の線にオーバープリント解除

すべてのパスに対して
塗りがグレースケールのK0のパスの塗りにオーバープリント解除
塗りがCMYKモードでのC0M0Y0K0のパスの塗りにオーバープリント解除
線がグレースケールのK0のパスの線にオーバープリント解除
線がCMYKモードでのC0M0Y0K0のパスの線にオーバープリント解除

グラフアイテムやパターンなどには効きません。

ダウンロードはこちらoverprint.zip

ディザInDesignブログ: 漢数字は漢字と別コードがあったほうが便利?

漢数字の定義とは何ぞや? と聞かれても明確な定義があるのだろうか。「漢数字とは」とGoogleで検索するとWikipediaその他で解説があるが、印刷業界ではちょっと違うような気がする。

一般に言われる漢数字
数を表す漢字その1:一、二、三、十、百、千、万、億、兆、京、など
数を表す漢字その2:零、壱、弐、参、伍、拾、仟、萬、など
数を表す漢字その3:廿、卅、など?
数を表す漢字?:〇

一方、印刷・出版業界では、というのは言い過ぎか。ともかく、このブログのエントリで使っている「漢数字」とは(ややこしいので以降【漢数字】と表記します)、Wikipediaでは「位取り記数法」と記述されているものに近い。それは、アラビア数字を主体とした数値の表記方法を縦書きで表記するために、「0123456789,.」と一対一で対応する文字の集合である。

それがつまり「〇一二三四五六七八九、(位取り)・(小数点)」のことである。この場合「、」「・」は半角で組むというのが一般的。(こういう、言葉を厳密に扱う内容になると、一般的とはどういうことか、どのくらいの多数派なのかということでしばしば自分の思考が中断する。そしてもっとふさわしい言葉がないのかということを考え始めて先に進まないので、とりあえずこのままで進めさせてください。)

これはどのようなときに使うかというと、私の考えはアラビア数字表記の代替措置という立場なので、縦組みで使用するのは当然。さらに主として次の場合に使用する。

  • 西暦の年号を表すとき(今年は二〇一〇年)、
  • 金額や記録など、概数(きりのよい数値)ではなく正確な数値が必要な場合。
  • 数の大きさを分かりやすく表記するため、桁揃えにしたい場合。
  • 郵便番号、電話番号、車のナンバーなど記号(符号)として扱うとき。

他にもあるかもしれないけれど、とりあえずはこんなところか。ところで住所の番地表記って皆さんどうしてますか。役所の正式書類(戸籍など)は百千十を使うのでしょうけれど、ちょっと迷うんですよね。

で、何が言いたいのかというと、この問題を顕在化させたのがInDesignの連数字処理なのである。アラビア数字にだけ限定しておけばよいものを、「漢数字」にまで対応させたので話がややこしくなった。連数字処理が標準でオンになっているので、「万一の場合」の「万一」が分離禁止になっちゃうていうのはInDesignが発売された当初から言われた話で、いまだに明確な解決方法が得られていない。それ以外にも地名では「金沢市十一屋町(じゅういちやまち)」「金沢市四十万町(しじままち)」(ローカルな例で済みません)といった例、人名では「十返舎一九」「直木三十五」「山本五十六」「加藤一二三」「大石十三夫」(あれ、最後の人は例に挙げてもよかったのかな?)といったように、分離禁止にする必要はない(逆に分離禁止にしたら字間が空いてみっともない)例は非常に多いのである。

注:InDesignの連数字処理はここで取り上げたすべての漢数字に対して処理しているわけではない。たとえば「万」「億」は連数字処理の対象になっているが、「兆」「京」「壱」などは対象になっていない。「京一郎」は分離禁止にならないのである。

このようにInDesignの連数字処理は【漢数字】の場合には有効になっていたほうがよいケースがあるが、それ以外のケースでは有効であっては困るのである。そういうことで、連数字処理の扱いには非常に困る。少なくとも「アラビア数字のみ連数字処理」と「アラビア数字と【漢数字】を連数字処理」、および「連数字処理を全く行わない」の3パターンが欲しいところだ。

じゃあ、【漢数字】かどうかをどう判断するか。一つは「〇」が含まれていれば【漢数字】ということになろう。それ以外の方法はないのか? うーん、決め手がないなあ。ハイフネーションみたいに例外辞書を設けて、連数字処理をさせたくない言葉を登録していくか? それも手間だなあ。

そうだ、いっそのこと、【漢数字】に別の文字コードを割り当てて、連数字にしたい場合はそちらの文字コードを使用するというのはどうだ。西欧言語圏の「A(U+0041)」とキリル文字(ロシア語などで使われる)の「А(U+0410)」、またギリシャ語の「Α(U+0391)」は形が同じでも別の文字コードが割り当てられているではないか。これと同じように漢字の「一」と【漢数字】の「一」も形は同じだが別コードを割り当ててもいいのではないか。そうすることで「1」を縦書きにすると自動的に「一」に変換することも可能だし、その逆も然り。横書きにした場合に「1」に自動的に変換したほうがよい場合には【漢数字】の「一」の文字コードを使えばよいし、横書きにした場合にも「一」のままでなければならないのなら、漢字の「一」の文字コード(これは従来どおり)を使うということだ。これで連数字処理が非常に行いやすくなり、また、印刷物は縦書きだが、それをホームページに掲載したい(HTMLで)という場合にも簡単にアラビア数字にできるので非常に使い勝手がよいのである。

ただ、入力方法では既存のIMEに改良が必要だ。今まで「1」と入力して変換した場合に漢字の「一」が候補として出てくるが、それは今後【漢数字】の「一」が候補として出てくる必要があり、漢字の「一」は候補に挙がらない。そのかわり「いち」と入力して変換する場合は漢字の「一」のみが候補として挙がるが【漢数字】の「一」は候補に挙げないという工夫が必要だ。でもそんなに難しいことではないだろう。

そんなわけでタイトルの結論なのだが、ユニコードコンソーシアムはきっと「日本はまたこんな面倒なものを提案して来やがって」と門前払いを喰らいそうな気がするなあ。いや、提案しないけど。

2010.6.12 追記

このエントリを読み返してみると、ユニコードに詳しくない人にとって、誤解を与える表現になっていたので訂正しておきます。文中では、「A」は同じ形に複数の文字コードが与えられているのに、「一」にはひとつの文字コードしか与えられていないという印象を受けるかもしれません。しかし、それは誤解です。実は「一」にも既に複数の文字コードが与えられております。この 文章の中で、あえて『漢字の「一」』と言っている点に注意していただければと思います。ここでいう『漢字の「一」』とは、ユニコードの「CJK統合漢字」というエリアにある「一(U+4E00)」のlことです。それ以外の「一」については、ここでは触れていないだけですので、誤解しないようお願いします。

それ以外の「一」は何かって? 実は私も記憶があいまいで。2つは分かるんですが、それ以外にもあったかどうか、しかもユニコードの規格も私が勉強してたころからバージョンが上がってしまって、すぐに正答を教えることができません。せっかくですから、これを機に勉強されてはいかがでしょうか。正答のコメント、お待ちしてます。(こらこら)

たけうちとおるのスクリプトノート: 23)テキストを全てアウトライン

IllustratorCS4と5で最前面のドキュメントすべてのテキストフレームをアウトライン化します。アウトライン化するまえにバックアップしておく事を強くおすすめします。
たぶん他のバーションのIllustratorでも動くと思います。

DTPBooster13で質問されて、出来るかなーって検証してたら結局作ってしまいました。

こうちゃん犬猫まみれさんもAppleScriptでアップされています。会場ではじめてお会いしました。ずいぶん若い好青年だった。

■■■使い方■■■
Illustratorドキュメントを開いている状態で使用してください。

実行すると
まずは全レイヤーのロックを解除します。
後はテキストフレームのロックを解除してどんどんアウトライン化していきます。
非表示のオブジェクトは一瞬表示してアウトラインして非表示に戻します。

非表示のレイヤーの中などにテキストフレームがあり、失敗した場合はメッセージを出します。

DTPBooster13の質問のお答え。難しいかと思ったら簡単だった。
ちなみにconvert to pathsがあるって質問に答えたんですがAppleScriptでした。

ダウンロードはこちらAiOutline.zip

ソースも

var mydoc = app.documents[0];
//レイヤーのロックだけは解除しておく
layerUnLock(mydoc);
var tfitems = mydoc.textFrames;
var tfcount = tfitems.length;
var mymsg = "";
for(var i = tfcount - 1;i > -1;i--){
	try{
		visiblebak = tfitems[i].hidden;
		tfitems[i].locked = false;
		var newgroup = tfitems[i].createOutline();
		newgroup.hidden = visiblebak;
	}catch(e){
		mymsg = "アウトラインできなかったオブジェクトがあります。";
	}
}
if(mymsg != ""){
	alert(mymsg);
}
function layerUnLock(myObj){
	var lycount = myObj.layers.length;
	for(var n = 0;n < lycount;n++){
		if(myObj.layers[n].visible == true){
			myObj.layers[n].locked = false;
			layerUnLock(myObj.layers[n])
		}
	}
}

たけうちとおるのスクリプトノート: DTP Booster 13のお題(解答編)

とりあえず。お題答えてくれた方で、こちらでキャッチできた方。

カネムーメモ: たけうちとおるさんの「DTP Booster 13のお題」をやってみた
var fullName=doc.fullName.absoluteURI←この方法も考えた!
while(docs.length>0){でドキュメントを閉じていく方法も良い方法だと思っています。

Diary NET. 1mgさん InDesign_ エラー処理について考えてみる
pdfPath=doc[i].fullName.toString()の方法は知りませんでした。

ディザInDesignのブログInDesign_ エラー処理について考えてみるへのコメント(お〜まちさん)
本物クオリティを求めるならこちらを。

っていうか、そうそうたるスクリプターの面々。すんごいプレッシャーになります。あのぉまいりました......汗 せうぞーさんからけっこう答えてるよとの連絡があったときしまったーって思いましたよ(笑)

ということで、解答はカネムーさん、mgさん、お〜まちさんのブログを見て下さい。というわけにもいかないので、セミナーでやった解答を。
※正直言うと、さくさく作れないし、回り道も多いしで僕はスクリプト上手ではないんですよ。いつも悩んでますって。

ExportPDFを試行錯誤しながら作成する

開いているドキュメントをPDF/X-1a:2001で保存するスクリプトを開発。ドキュメントが保存されている同一階層にPDFを作成

開いているドキュメントすべてに処理を実行するにはforを使う

	for(var N = 0;N < app.documents.length;N++){
		var myDocu = app.documents[N];
	}


for(カウンタ=初期値; カウンタ継続条件; 次のカウンタ値){
処理
}

varははじめて登場する変数の前につける約束事
N = 0;はカウンタ=初期値なので変数Nが0スタートということ
N < app.documents.length;はカウンタ継続条件ですのでNがドキュメント数より小さい間繰り返す(app.documents.length;は開いているドキュメントの数)
N++は次のカウンタ値なので次の繰り返し時にNに+1する
var myDocu = app.documents[N];で変数myDocuにドキュメントをセット

PDFを保存するためにドキュメントのパスを調べる

まずはドキュメントが保存されている場所を調べる。Documentをオブジェクトモデルビューアで見るとfilePathというプロパティがあるのでこれにアタリをつけデバッグモードで下記を実行

	for(var N = 0;N < app.documents.length;N++){
		var myDocu = app.documents[N];
		var myPath = myDocu.filePath;
	}

ExtendScript Toolkitでvar myPath = myDocu.filePath;の行に赤い●を付けた状態で実行。スクリプトがストップするのでウィンドウメニューからデータブラウザを表示させる。そしてスクリプトを1行動かすと、変数myPathが出現。myPathを調べてみると保存されたファイルの親フォルダ。欲しいのは親フォルダではなくドキュメントのフルパスなのでこれは違う。

fullNameがドキュメントのフルパス?

次に変数myDocu(現在開いているドキュメント)をデータブラウザで調査。いろいろ項目があり、fullNameが該当する。
displayNameでファイル名が取れることがわかる。
フルパスが分かれば下記のように検索置換で".indd"を".pdf"に置き換えてやれば良い。(ファイル名や親フォルダもわかるので、もっと自由自在にファイル名を付ける事も出来る。)
さっそく下記でテスト
	for(var N = 0;N < app.documents.length;N++){
		var myDocu = app.documents[N];
		var myPath = myDocu.fullName;
		//変数myPathにドキュメントのフルパス
		var pdfPath = myPath.replace(".indd",".pdf");
		//replaceで".indd"を".pdf"に検索置換
		alert(pdfPath);
		//alertでダイアログを表示してみる。
	}

var pdfPath = myPath.replace(".indd",".pdf");でエラー
もう一度データブラウザでmyPathを見るとmyPathの横に[File]と出ている。これはフルパス文字列ではなくファイルオブジェクト。展開して見てみると、この中にもdisplayNameやfullNameやfsNameなどがありfullNameを使ってみれば良さそう。
fullName中のfullNameとはややこしいですが試してみましょう。
先ほどの

	var myPath = myDocu.fullName;

を変更して下記に

	var myPath = myDocu.fullName.fullName;

※または2行にわけて

	var myFile = myDocu.fullName;
	var myPath = myFile.fullName;

実行しするとエラー無しで成功。※パスの途中に「.indd」という文字が入ったフォルダがあると動作しないので注意。

PDFの書き出し

次にPDF書き出し方法を調査。オブジェクトモデルビューアで調べるのは面倒なので「InDesign JavaScript PDF 書き出し」でGoogle検索するといくつかのサイトがヒット(今作っているPDF書き出しスクリプトはSapmleScriptに入っているようです。なんだー。またやっちまったよー。まぁいいや。http://d.hatena.ne.jp/seuzo/20080904/1220458928)。
Document.exportFileを使うとPDF書き出しができるらしい(ソースを出して下さっているサイトに感謝(http://tu-kazu.jp/javascript1.php))。

Document.exportFileをオブジェクトモデルビューアで調べる。(DocumentとDocumentsと2つあるがDocumentのほう)
1つめの引数はExportFormat.pdfType
2つめの引数はファイルオブジェクト
4つめの引数はPDFExportPreset
となっています。(3つめはオプション)
1つめの引数ExportFormat.pdfTypeはPDFで書き出しするのでこのままでOKです。(検索ででてきた指定方法)
2つめの引数はファイルオブジェクトなので先ほど作成したフルパスをファイルオブジェクトに変換します。
具体的にはvar pdfFile = new File(pdfPath);です。
4つめの引数はPDFExportPresetでここでPDFx/1-aを設定できそうです。

下記みたいなので動くかテスト。しかしエラー

for(var N = 0;N < app.documents.length;N++){
	var myDocu = app.documents[N];
	var myFile = myDocu.fullName;
	var myPath = myFile.fullName;
	//変数myPathにドキュメントのフルパス
	var pdfPath = myPath.replace(".indd",".pdf");
	var pdfFile = new File(pdfPath);
	myPDFExportPreset = "PDFx/1-a";//★ここがエラー
	myDocu.exportFile(ExportFormat.pdfType, pdfFile,false, myPDFExportPreset);
}

ウィンドウ下のエラーに注目。myPDFExportPresetが必要なのに値"PDFx/1-a"になっていると言われています。文字列ではダメですということです。
再びPDFExportPresetをオブジェクトモデルビューアで見てみるといろいろあって、どれをつかったらいいかわかりにくい。

「PDFExportPreset」の設定方法をGoogle検索する。

「PDFx/1-a」などを文字列で指定したいのでGoogle検索。「お〜まち」さんのObject Modelが見つかる。StandardsComplianceのところにidPDFX1a2001Standardがあったのでそれと似た項目を再びオブジェクトモデルビューアで調べるがちょっと難しい。

再度「PDFExportPreset」でGoogle検索。スバリ下記のようなソースが見つかりました。

var myPDFExportPreset = app.pdfExportPresets.item("PDFの設定名");

でいけるみたいなのでさっそく下記のように設定して試します。

for(var N = 0;N < app.documents.length;N++){
	var myDocu = app.documents[N];
	var myFile = myDocu.fullName;
	var myPath = myFile.fullName;
	//変数myPathにドキュメントのフルパス
	var pdfPath = myPath.replace(".indd",".pdf");
	var pdfFile = new File(pdfPath);
	myPDFExportPreset = app.pdfExportPresets.item("PDF/X-1a:2001 (日本)");
	//★ここがエラー
	myDocu.exportFile(ExportFormat.pdfType,pdfFile,false, myPDFExportPreset);
}

またエラー。こういう場合はデバッグしてpdfExportPresetsにどんな値があるのか調べます。pdfExportPresetsはPDF書き出しプリセットの事なのでアプリケーション直下にあると思われます。
(ドキュメントが変わっても常に同じプリセットがあるので)オブジェクトモデルビューアでlengthというプロパティがあるので下記のようにループしてPDF/X-1a:2001 (日本)がでてくるまでチェックすればよいと思います。実行してみましょう。

	for(var N = 0;N < app.pdfExportPresets.length;N++){
		var presetname = app.pdfExportPresets[N];
	}

presetnameの横に●をつけて実行しpresetnameを展開するとnameのプロパティに日本語が表示されています。
1つづつ見ていくと"[PDF/X-1a:2001 (日本)]"があります。

保存せずに閉じるには

myDocu.close(SaveOptions.NO);
を使う。ただし閉じるとドキュメントの配列が変わるので逆向きループすると良い。(documents[0]を閉じるとdocument[1]が[0]になるのでうまく行かない)
という事で完成したスクリプトはこちら。myPDFExportPresetはループの中ではなく最初に取得した方が良い。

<pre>
	var myPDFExportPreset = app.pdfExportPresets.
	item("[PDF/X-1a:2001 (日本)]");
	for(var N = app.documents.length - 1;N > -1 ;N--){
		var myDocu = app.documents[N];
		var myFile = myDocu.fullName;
		var myPath = myFile.fullName;
		var pdfPath = myPath.replace(".indd",".pdf");
		var pdfFile = new File(pdfPath);
		myDocu.exportFile(ExportFormat.pdfType, pdfFile, false,myPDFExportPreset);
		myDocu.close(SaveOptions.NO);
	}

ExportPDF2(ダイアログ版)の解説

//ダイアログ表示のおまじない
app.scriptPreferences.userInteractionLevel=1699311169;
var preset_count = app.pdfExportPresets.length;
var pdf_preset_name = new Array();//配列pdf_preset_name
for(var i = 0; i < preset_count; i++){
	pdf_preset_name.push(app.pdfExportPresets[i].name);
}//配列にPDF書き出しプリセットの名前を入れる。
makedialog(pdf_preset_name);
function makedialog(pdf_preset_name){
	//ダイアログを作成する
	myDialog = app.dialogs.add({name:"PDF書き出し"});
	with(myDialog){with(dialogColumns.add()){
	with (dialogRows.add()){//1段増やす
		staticTexts.add({staticLabel:"書出プリセット選択"});
	}
	with (dialogRows.add()){//1段増やす
		var pdf_preset = dropdowns.add
		({stringList:pdf_preset_name, selectedIndex:0,minWidth:120});
	}
	with (dialogRows.add()){//1段増やす
		var window_close = checkboxControls.add
		({staticLabel:"ドキュメントを閉じる", checkedState:true})
	}
	}}
	var myReturn = myDialog.show();//ダイアログ表示
	//ここから処理を行う
	if (myReturn == true){
		pdf_preset_num = pdf_preset.selectedIndex;
		//選ばれた書出プリセット番号をpdf_preset_numに
		var window_close_flg = window_close.checkedState;
		//ドキュメントを閉じるかどうか
		myDialog.destroy();//ダイアログを破棄する
		export_pdf(pdf_preset_num,window_close_flg);
		//export_pdfを呼ぶ(下記)
	}else{myDialog.destroy();}//キャンセル時
}
function export_pdf(export_pdf_name,window_close_flg){
	var myPDFExportPreset = 
		app.pdfExportPresets[pdf_preset_num];
	//myPDFExportPresetに選択されたプリセットを入れる
	for(var N = app.documents.length - 1;N > -1 ;N--){
		var myDocu = app.documents[N];
		var myFile = app.documents[N].fullName;
		var inddPath = myFile.fullName;
		var pdfPath = inddPath.replace(".indd",".pdf");
		var pdfFile = new File(pdfPath);
		app.documents[N].exportFile(ExportFormat.pdfType,pdfFile, false,myPDFExportPreset);
		if(window_close_flg == true){
			myDocu.close(SaveOptions.NO);
			//保存せずに閉じる
		}
	}
}

まとめたら4行にもなる。

でも4行がすごいわけではない。かえって分かりにくい。
for(var N = 0;N < app.documents.length;N++){
	app.documents[N].exportFile(ExportFormat.pdfType, File(app.documents[N].fullName.fullName.replace(".indd",".pdf")), false,app.pdfExportPresets.item("[PDF/X-1a:2001 (日本)]"));
	myDocu.close(SaveOptions.NO);
}

たけうちとおるのスクリプトノート: DTPBooster13フォローアップ

DTPBooster13終わりました。
みなさんありがとうございました。会場へ来ていただいた皆さまをはじめ
twitterでも応援していただいてほんとに嬉しかったです。
なんか皆さんに支えられてるって感じです。心強かったですよ!

IllustratorCS5の原点移動によるスクリプトへの影響に付いて
IllustratorCS5では原点が左上になりました。画面上では左上から下に行くに従って0→100→200のように数値が増えていきますが、スクリプト的には0→-100→-200とマイナスになっていきます。いままでは左下原点だったので左下からさらに下に行くと0→-100→-200となっていたのですがCS5からは左上に来るという事になります。ですので座標を数値入力するようなスクリプトとか、用紙中央にオブジェクトを作成するようなスクリプトは注意が必要です。選択したオブジェクトの周りにトンボ的なスクリプトは問題ありません。

Illustratorの文字のアウトラインについて
下記で出来ました。でもドキュメント全てをアウトラインするには工夫が必要。がんばってくださいねー。ってかやっぱアウトライン好きですねー。InDesignに貼ってアウトラインワザを使った方が良いのでは?

app.activeDocument.layers[0].locked = false;
//レイヤーのロックを解除
app.activeDocument.textFrames[0].locked = false;
//テキストフレームのロックを解除
app.activeDocument.textFrames[0].createOutline();
//テキストフレームのアウトライン

スクリプトでしかできない事について
いろいろ話しましたがRRRさんが速く正確に大量に処理させても文句を言わないヤツって言ってました。たしかに人間の手では出来ないですね。

お題の解説は別ページにて。


DTP Transit
DTP Booster 013(Omotesando/100602)が終了しました #dtpbooster013 #cs5seminar

当日のスライドはこちら
スライド1

スライド2

いわもとブログ

ディザInDesignブログ: InDesign_ エラー処理について考えてみるへのコメント

diary NET. 1mgさんのブログにコメントを書き込めなかったので、ここで書きます。

トラックバックもできるかどうかわからないので、リンクも貼っておかなきゃ。
InDesign_ エラー処理について考えてみる
ここで、

六行目ではtry〜catch(e){}したほうがいいのかな?書き出し失敗したときのアラート出すとか

とありますけど、本来のことを言えば、「ファイルを作成する場合、必ずエラー処理をすべき」なんです。でもわたしは最近はしたことがないんですが(笑)

PDF書き出し、テキスト書き出し、別名で保存など、ファイルを作成することは結構あります。そしてエラーが発生する確率も、ほかの操作に比べて高い気がします。

自分だけで使っているのであれば、それほどエラーに遭遇することはないかもしれませんが、これを他人に使わせると思わぬエラーで苦情が来たりします。

ではファイルを作成する場合に想定されるエラーとは?

  • 書き込もうとするフォルダが読み取り専用になっている
  • 書き込もうとしたときに同名のファイルがすでに存在する
  • しかもそのファイルを別のアプリケーションで開いていたりする
  • 同名のファイルに対して上書き処理にしたのに、実は書き込み権限が無かった
  • それ以前にフォルダ自体に書き込み権限が無い
  • 書き込み先がUSBメモリなのに、差し込んでいなかった
  • USBメモリを差し込んだはずなのに、接触不良でつながっていなかった
  • USBメモリがつながっているのを確認して実行したが、実はUSBメモリに空き容量が無かった
  • そもそもUSBメモリ自体壊れている
  • とりあえずハードディスクに保存しようとしたが、そっちも空き容量が不足していた
  • 不要なファイルを削除して空き容量を確保したが、ハードディスクも壊れていたことが判明
  • 仕方がないのでネットワークでつながっている別のマシン(サーバー)に保存しようとしたら、保存中にネットワークケーブルを抜かれてしまった
  • ネットワークケーブルをつなぎなおしたらハブが壊れてしまった
  • ハブを買いに行っている間に別のマシンも壊れた
  • 別建物のサーバーに保存しようとしたら、そっちのほうは停電になってしまった

わたしは過去にハードディスクの空き容量が少なくて書き込めなかったことがあります。さすがに今はハードディスクの空き容量を心配することは少ないでしょうが、GBクラスのファイルを作成しようとするときは注意しましょう。

そうそう、わたしの公開しているスクリプトは、書き込みに対するエラー処理なんて一切してないので、使用する人は注意してくださいね!

2010.6.3 追記

ひとつ重要なことを忘れてました。ファイル名・フォルダ名の長さ制限、フォルダ階層数の制限、合計のパス名の文字数制限にも注意が必要です。

var originalfailname = "使用者に指定させるファイルの名前";
var backupfilename = originalfilename + "_backup" + dateTime + backupVersion + ".indd";

なんてやってる人はファイル名の長さに引っかかって保存に失敗することがありますのでご注意を。

ディザInDesignブログ: わたしが「日本語の乱れ」を気にしなくなった理由

それはカルチャーショックでした。言葉は時代によって変わるもの、「新しい」という言葉も、今は「あたらしい」というけれど、昔は「あらたしい」と言っていたこと(だから「新たに」という言葉は昔のまま変わっていない)は知識として知っていたのですが、それでも「頭痛が痛い」だの「的を得る」はおかしいし、「あり得ない」の反対語は「ありえる」ではなく「ありうる」だろうが、「ありえる」だと人魚姫じゃねえか、と言っていました。

その考えが変わったのは大学生のとき。能楽のサークルに入ってまして、その流れで古典に目覚め、色々読み漁っていたときのこと。

式亭三馬の「浮世床」を読んでいたら、自分の無知に頭を殴られたぐらいの衝撃を受けたのでした。その一説がこれ(引用は國民圖書株式会社発行『近代日本文學大系第十七巻』昭和2年)。初編巻之上にあります。

しだらがないトいふ事を、『だらし』がない、『きせる』を『せるき』などいふたぐひ、下俗の方言なり。

げげっ! だらしがない、という言葉は元は「しだらがない」と言っていたのか。しかも下俗の方言とは。知らなかったーーー!!! と、これぐらいのショックを受けたのでした。そういえば「ふしだら」という言葉がありますが、これは「不しだら」なので本来の使い方。「今の若者は言葉が乱れてだらしないねえ」と言っている人こそ、しだらがない。でも今更「しだら」に直さなければ、というわけにもいかない。広辞苑(第5版)には「だらしない」は形容詞だとある。違うだろうが、「しだらがない」→「だらしがない」→「だらしない」になったので、本来は名詞+助詞+形容詞だろうが。もしかして「だらしない」の古い言い方は「だらしなし」だと思ってる?(これ、周りの人に聞いてみると面白いかも)

てなわけで、今はおかしいと思っていても将来は誰もが当たり前のように使う言葉になってしまっているかも知れない。でも「せるき」は採用されなかったのね。

そんなわけで、いわゆる「言葉の乱れ」がそれほど気にならなくなったのでした。勝手にしろってな感じで。でもうちの娘が「難しい」ことを「むずい」というのは流石に違和感がある。最初は背中がかゆいのかと思った。

何で突然こんなことを書いたのかというと、このことが「字形の異なる文字(俗に言う異体字)」についての自分の考え方にも影響しているのである。そのうち続く(つもり)。

InDesign + JavaScript = ?: iPad購入とな

といっても、今日注文しただけで、まだ手元にはない。実機を店舗で触ってきたが、電子書籍はアリスしかなく、またPDFを読めるアプリもなかったのでなんとも言えないのだが、やはりあの大きさは魅力である。
まぁ予想するにB5版ぐらいまでのPDFだったら問題なく読めるんじゃないかと思う。だとしたらますますPDFでいいよな、て方向だ。InDesignから日本語の文字化け等を気にしながらePub書き出すよりも、PDFでいいんじゃね?と。確かにPDFも永続性が保証されているわけではないが、ePubも同じことで。というか、PDFだと楽だよね、てのもあるんだけど。
ここの記事で興味深いことが述べられている。
http://blog.drikin.com/2010/05/magastoreipad.html
アプリ化することと永続性。
とは言え、iPadを使ってみたら意見が変わるかもしれない。

たけうちとおるのスクリプトノート: 10)デーバナーガリー文字に置き換え(危)

InDesignCS4で選択された文字をデーバナーガリー文字に置き換えます。
ただそれだけです。危険なスクリプトです。

くれぐれも自己責任で。

なんとなく作ってしまいました。Booster用のネタですね。
約物や数字はそのままです。気分転換にどうぞ。

使い方
文字を選択してこのスクリプトを実行して下さい。

ダウンロードはこちら
findrep09.zip

InDesign37

たけうちとおるのスクリプトノート: 10)文字を適当に置き換え(危)

InDesignCS4で選択された文字を適当に置き換えます。
ただそれだけです。

くれぐれも自己責任で。

ひらがなはひらがな
漢字は漢字
アルファベットはアルファベットに置き換え
約物や数字はそのままです。
日本語っぽさを残したまま置き換えられます。ダミー文字作成にどうぞ。

使い方
文字を選択してこのスクリプトを実行して下さい。

ダウンロードはこちら
findrep08.zip

InDesign36

たけうちとおるのスクリプトノート: 10)数字を漢数字に

InDesignCS4で数字を漢数字に置き換えます。
単純に置き換えるだけです。

使い方
文字を選択してこのスクリプトを実行して下さい。

おそらく他のバーションのInDesignでも動くと思います。

ダウンロードはこちら
findrep07.zip

InDesign35

たけうちとおるのスクリプトノート: 10)注番号の数字振り直し

■■■このスクリプトについて■■■
InDesignCS4で選択範囲の注番号の数字振り直します。
後注等、脚注機能を使わずに作成したドキュメントに有効です。

使い方
文字を選択してこのスクリプトを実行して下さい。
スタート番号を聞いてきますので入力して下さい。
注数字が順番に置き換わっていきます。
「注数」という文字を含んだ文字スタイルに反応します。
他の文字スタイルを使っている場合はソースを変更してください。

おそらく他のバーションのInDesignでも動くと思います。

ダウンロードはこちら
findrep06.zip

InDesign34

InDesign + JavaScript = ?: window

自分用メモ。
xmlでタグ付け等をした後、タグのつけ忘れがないかチェックする時、今までalertでログを表示していたのだが、最近やたらログの量が多くなり、画面に収まりきらなくて困っていた。
scriptUIを使うとスクロールバー付きのウインドウを作れる。

var log //チェック結果のログ
var myDialog = new Window("window", "タグのチェック", [0,0,200,200]);
myDialog.add("edittext", [10,10,190,150],log,{multiline:true});
var myButton = myDialog.add("button", [120,270,180,290], "ok", {name: "ok"});
myDialog.center();
myDialog.show();

myButton.onClick = function(){
myDialog.close();
}

しかし、scriptUIのリファレンスはどこにあるんだろ。estkのヘルプもなんか不十分だし。。。と思ったら、JavaScript Tools Guideに詳しく書いてありますね。

たけうちとおるのスクリプトノート: DTP Booster 13のお題

DTP Booster 13があと1週間程度になりました。
前半:スクリプト紹介
中盤:カスタマイズや、ExtendScript Toolkitの使い方を解説
後半:スクリプトをつくる(たいくつになったらごめんなさい)

新ネタとして1本スクリプトを完成させる過程をご紹介しようと思っています。
そこで「お題です」
「開いているドキュメントをすべてPDF書き出しする」スクリプトを作って下さい。(できればで結構ですよ。何となく自分で作ってみれば理解が深まります。)

・書き出されるPDFはドキュメントと同じファイル名で(拡張子が.pdfになる)同一階層に保存されるとします。
・PDF書き出しプリセットは「PDFx/1-a」です。
・PDFを書き出したドキュメントは保存せずに閉じます。
・20行以内で出来ると思います。
・多少のエラー処理はしなくて結構です。

時間が余ればスクリプトの読み方を解説いたします。

InDesign + JavaScript = ?: まだまだeBook

来週にはiPad発売である。で状況がかなり変わるのかどうか。
で最近のAppleを見ていると、彼らの心境で右往左往するのは困るってわけで、appStore経由でのeBookてのはリスクがそれなりにありそうで、やはりとりあえずの結論としては、いかにHTMLで読みやすいものを作るかってところが目下の関心。
ページめくり機能とかは自然科学系の学術書ではどうでもいい話。教科書(参考書)であればいかに理解しやすいレイアウトか、構造かってことだなぁ。
HTMLを前提すると、XMLをベースにして、InDesignはレンダリングソフトウェア的に考えるのが至極まっとうではある。赤字校正もXMLで。

ScriptClip: ScriptUIでモザイクを使ってお絵描き

ScriptClip
//2010-05-19  CS4はほぼ期待どおり動作、 CS3には 各エレメントのonDrawイベントが期待どおり動かない?
(function(){
#targetengine 'main';
$.memCache = $.memCache*3; // memoryCache X 3 ;
//読み込み処理
//正規表現をつかって読み込むファイルを一網打尽!
var includeFiles = requireFiles(['MosaicData.js' , 'draw.*.jsx']);
//
for(i =0; i < includeFiles.length; i++)$.evalFile (includeFiles[i]);
//InDesign & Photoshop -> dialog  ,  etc -> palette 
//UI
var windowType = (app.name == 'Adobe InDesign'  || app.name == 'Adobe Photoshop' ) ? "dialog" : "palette";
var dlg = new Window(windowType, 'MosaicPictureTest' , [100,100,250,300]);
var pnl = dlg.add('button', [0,0,150,200], 'My Panel');
var drawSwitchImages = [
		//
		function(e){
			drawMosaicPict(this , Mosaic.face);
			drawText(this,{text : "kamiseto" ,fontName : "Lucida Grandeaa" ,style :  ScriptUI.FontStyle.BOLD ,size : 9 , color : [0,0,0,1]},[5,188]);
		},
		//
		function(e){
			drawRactData(this,RACTDATA);
		}
		];
//
dlg.center();
//マウスオーバー
pnl.addEventListener ("mouseover", function(e){
			e.target.onDraw = drawSwitchImages[0];
			e.target.notify('onDraw');
			} , false);
//マウスアウト
pnl.addEventListener ("mouseout", function(e){
			e.target.onDraw = drawSwitchImages[1];
			e.target.notify('onDraw');
			}, false);
//
pnl.onDraw  = drawSwitchImages[1];
//
dlg.show();
})();
 
//////////////////////////////////////////////////////////MyFunctions
//実行中のスクリプトのパスを得る
//illustrator CS3 は 動作しないので ダイアログでパスを選択。
function getScriptPath(){
     try {
			return (app.name == 'Adobe Illustrator' || app.name == 'Adobe Photoshop') ? ERROR : File(app.activeScript); 
     } catch(e) {
			if(app.name == 'Adobe Illustrator' && app.version.split('.')[0] <= 13)return undefined;
			return File(e.fileName); 
     } 
}
//呼び込むファイルを探す
function requireFiles (FilesArray){
var evalFiles = [];
var searchFiles = function(s){
var fols = s.split("/");
var fn =  fols.pop();
var fols = fols.join("/");
return (new Folder(scriptFolder+'/'+fols)).getFiles (function(a){
	return a.toString().match(RegExp(fn)) ? a : false;
});
}
try{
	var scriptFilePath = getScriptPath();
	if(scriptFilePath == undefined){
		var scriptFolder = Folder.selectDialog ('ScriptUI_MosaicPicture.jsxがあるフォルダを選択して下さい。');
	}else{
		var scriptFolder = scriptFilePath.parent;
	}
	for(x =0 ; x < FilesArray.length ; x++){
		var r = (searchFiles(FilesArray[x]));
		for( z =0 ; z < r.length ; z++){
			//$.evalFile (r[z]);
			evalFiles.push(r[z]);
		}
	}
	return evalFiles;
	return "#include" + evalFiles.join("' \n#include '") + "'";
}catch(e){
	alert(e);
	return;	
}
}
 
//ライブラリーのインストール
function installLibrary(Files){
}
 
 

たけうちとおるのスクリプトノート: 30)画像配置06 1枚配置保存

InDesignCS4で画像をドキュメントに配置し
ドキュメントを適切なサイズ(A4、B4、A3それより大きければ画像サイズ)に変更し
トンボを付けて保存します。
おそらく他のバージョンのInDesignでも動くと思います。

■■■使い方■■■
スクリプトパレットの「画像配置06_1枚配置保存.jsx」をダブルクリックします。
配置したいファイルを聞いてきますので選択してください。
拡張子がaiかpdfの場合はダイアログが出てきますので設定し、OKボタンをクリックしてください。

ダウンロードはこちら
img06_1mai.zip

InDesign33

たけうちとおるのスクリプトノート: 30)きりっ子用名刺面付け

InDesignCS4で名刺をドキュメントに配置し
名刺カッター「きりっ子miniSK-202S」用に配置しトンボを付けて保存します。
8個面付け用と10個面付け用があります。
2枚選択すると裏表といった感じで2ページできます。
縦長名刺は90度回転して配置します。
おそらく他のバージョンのInDesignでも動くと思います。他のバージョンの「きりっ子」で使えるかはわかりません。

スクリプト冒頭の
var x_offset = 0;//x方向へ微調整するにはこの値を変更
var y_offset = 0;//y方向へ微調整するにはこの値を変更
の値を変えると位置を微調整できます。

■■■使い方■■■
スクリプトパレットの「きりっこ10.jsx」をダブルクリックします。
配置したいファイルを聞いてきますので選択してください。

ダウンロードはこちらkiricco.zip

InDesign32

InDesign + JavaScript = ?: ebookその後

多くのサイトが競ってeBookの未来予測を立てるこの頃。
まぁ自分もそのうちの一人(ってほどのことでもないが)なのだが、appleのFlash締め出しとかを見るとなかなか動きづらい(出版社側では)。それよりも単純にしておくべきなのは、制作データの社内管理。
印刷会社と出版社の関係では、欧米では出版社が完全に印刷データ(組版データ、製版データ等)を完全にコントロールしている模様だが、日本ではそうでもない。ほんの数年前にも、製版データをめぐる訴訟が起きているし、印刷会社としては、印刷はしても組版データは渡さない、というところも多いのである(まぁここらへんは単純に権利関係の問題で契約を見直すことで解決できるのだが)。
図版や表が多い書籍の場合のeBookの作り方ってのは試行錯誤するしかない。当たり前だが。でも結局、HTML化(WEBアプリ化)するのが一番早いのだと思う。アプリとして売るとしてもHTMLをパッケージすればいいだけのことだし。
もちろん検索性は重要であるから、本の索引をうまく変換することが肝心。

とか考えてもiPad的なB5サイズのタブレットが主流になればPDFで問題ない気もするんだな、これが。

InDesign + JavaScript = ?: e-book

電子書籍て呼び方に違和感があるのかもしれない、結局のところ。
例えば、WIREDやVIV MagのiPadデモを見て、未来の本!と騒ぐ気にはなれないのである。WEBとどーちがうの?というわけで。個人的には、FLASHサイトは鬱陶しかったのだが、それをタブレットで見ることで変わるのかもしれない、てところに期待はしている。

送り手からのメリットとしては、WEBコンテンツの切り売りが可能となり、しかもコピーの問題も多分クリア、てところだろうか。ただ、先のVIV Magのようなリッチなコンテンツを作るのであればそれなりにコストもかかるだろうしな。。。

InDesign + JavaScript = ?: findGrep()で検索したとき

よく忘れるのでメモ。

findGrep()で検索したときの返り値はマッチした文字列の配列。で文字列がどの場所にあるのかを知りたい時は、配列をfor文とかで回してindexプロパティで親ストーリーの何番目のキャラクターなのかがわかる。

例えば次のように取得する。
app.findGrepPreferences.findWhat = "(?s)▲▲(.+?)▼▼";
var result = myStory.findGrep(true);

for(var i=0; i<result.length; i++) {
$.writeln(result[i].index);
$.writeln(result[i].toSpecifier());
}

indexで最初の▲の位置がわかる。toSpecifier()だと最初と最後がわかる。
単純にindexとな。ここで躓いてしまった。

何がしたかったというと、タグで囲まれた部分を吹き出し的なアンカーフレームにする、というもの。テキストフレーム作成→ライブラリ経由→カーソル位置に配置、と今までやってたんだけど、insertionPointがわかってれば直接insertionPoints[x].textFrames.add()、と出来るようなので。

InDesign + JavaScript = ?: acrobatのハイライトテキスト

数時間ネットで調べたのだが、やはり皆苦労しているようだ。
そもそもacrobatのJavascriptはリソースが少ない。少なすぎる!ってことで勉強する気にもなれず、一番手っ取り早いが不完全な方法で手を打つことにした。

単純にテキストがハイライトされたPDFをXMLで書き出すだけ。ハイライトされている部分は<Annot></Annot>で括られてるのでその部分だけを拾っていこうかと。頁番号はちょっと厄介。ノンブル部分の作り方に特徴があれば(例えば章タイトル+全角スペース×2+ノンブル、とか)、その規則性から拾ってくる手もあるんだが、そうでない場合は。。。。

まぁハイライト部分は出現順に拾えるはずなので、拾えているかどうかチェックもかねてノンブルを入力してもらっていくのがいいか。。。

InDesign + JavaScript = ?: acrobat + javascript = ?

作業の効率化UPということを考えると、結局InDesignでできることは最小限に抑えたい、ということになる。InDesignを使える人ってのは限られているわけで、使えない人にもできる作業を増やすことで、効率化だけでなく、全体の作業量を増やすことができる。

で色々考えると、結局InDesignで色々やるんじゃなくて、wordで文書の構造化やレイアウト、文字属性を決めてしまうってのが手っ取り早いのだろう。
プレーンなテキストファイルってのはたしかに扱いやすいが、逆に手間がかかかる。例えば、学術書であれば、イタリックだったり上付き・下付き文字ってのは日常茶飯事でそれをテキストエディタでタグでくくっててのは手間。ワードだったらキーボードショートカット一発でそこらへんの文字属性は設定できるし。

ということでワードの文字属性やスタイルをほぼ完全にInDesignに読み込ませるようなスクリプトが必要。いや、実際InDesignの機能でほぼ読み込みできるのだが。

次に、InDesignで組み上がってきたものに対する処理。予算があればInCopyという手もあるのだが、そうではないので修正はInDesignでちまちまやる、と。

もひとつ面倒なのは索引。InDesign上で索引マーカーひいてくのが便利なのは確かなのだが、その時間を別の書籍の組版にあてたい。てことでPDF書き出して注釈可能にして、テキストをハイライトさせて索引マーカーを著者に引いてもらうのが一番いいかと。でAcrobatからハイライトテキストを書き出す。

という構想だったのだが、ハイライトテキストを書き出すにはいろいろとややこしい。そもそもテキストをハイライトさせる時にハイライトされている文字列を注釈にコピーする必要がありそれが自動的にコピーしてくれるのはAcrobatのみ。でReaderでハイライトされたテキストは文字列として書き出せないのである。ここでInDesignのようにJavaScriptで何とかなるんじゃないかと思ったんだが。。。

ぐぐってみても良い解決策は見当たらない。ここに
http://www.acrobatusers.com/forums/aucbb/viewtopic.php?id=14150
一応の答えはあるんだが。。。というかそもそもAcrobatでのJavascript環境が貧弱すぎ!でっ挫折気味なのだが、ここらへんちゃんとしたスクリプト出来たらかなり強力かもしれん。

つか調査不足だが、PDFをプログラムでコントロールするってはInDesign以上に効果的なような。

InDesign + JavaScript = ?: Grepのバグ?

久々にIndesignネタを。

簡易タグから段落スタイルの割り当てというスクリプトを作っていて、例えば

<ex>
文字列文字列文字列文字列文字列文字列文字列文字列文字列文字列文字列
</ex>

とタグがあってスクリプトを走らせると、現ドキュメントで使用している段落スタイルを選びそのタグで囲まれた文字列に割り当てられる、というもの。

上記の例でいえば
app.findGrepPreferences.findWhat = "(?s)^<ex>\r(.+?)<\/ex>\r";
app.changeGrepPreferences.changeTo = "$1";
としておいて、findGrep()の戻り値に段落スタイルを適用して、changeGrep()でタグを取り除く、という仕組みにした。一段落ずつ見ていってタグを取り除くより正規表現で置換した方が楽に思えたので。

何回か検証して問題がなかったように見えたのだが、よく見ると、タグを除去した後に、上付き文字の位置がずれている。正確に言うと、上付きの属性がかかる位置がずれているのである。例えば、「H20の・・・」となっていたところが「H2O・・・」となっているのである。。。

どうも置換する際に属性の位置が保たれていないようである。いやいや本格運用する前に気づいて良かった。
ってこれはスクリプトだけではなく、Indesignの検索置換ダイアログでも同様の症状のようだ。。

InDesign + JavaScript = ?: 大きい。。。

iPhoneの巨大版。。。この冬実家に帰ったとき思っていたこととリンクした。
田舎にいる父母にプレゼントしたらいいと思った、iPadを。
別に電話機能はいらない。でもメールのやりとりはしたいはず。特に孫の写真が大きく見れたらいい。
3月発売か。。。兄弟と相談してみよう。

つか、電子書籍というよりそっち方面(高齢者とか、PC苦手な人とか)に受けそう。
となると日本では競合はDSあたりなのかもしれない。ゲームもできるし。
何よりDSよりわかりやすい。使いやすい。ペンをなくす心配もない。そしてゲーム機じゃない。

まじめに考えると、青学がiPhoneを生徒に配布したように、今度は小・中学校でiPadを採用するって流れが出てきそうですね。学校にそのシステムを構築するよりも、iPadを買い与えて3年なり6年使った方がコストはかからないだろうし。そういう意味ではクラウドっぽい。

InDesign + JavaScript = ?: 横断性

目次・索引、てのが書籍における重要な側面だとすれば、電子化することで、検索性とかフィルタリング、並べ換え、が可能になると有用かもしれない。
書籍単体を横断してそのようなことが可能となればさらに面白い。WEB頁のクリップのようなものだ。
OSレベルでの検索機能(たとえばMacの場合のスポットライトとか)が書籍内容にまで拡張できるかどうか。書籍自体にタグ付けだったり注釈がつけれるかどうか。

InDesign + JavaScript = ?: 70%

印税率やらなんたら、アップルのiSlateとかなんとかで、電子書籍をめぐる動きというかニュースが多い。
出版社側としては、マーケットが広くなるのはよいことなのだが、優良な著者が離れるかもしれない、というのがやはり一番怖い。
音楽業界を見てると意外にそうはならないかもしれないような気もするが。

学術系というくくりで考えると、アマゾンで出版するのは自費出版にすぎず、当面は業績にカウントされないのかどうか。というか論文誌とかはとっくに電子化してるわけで、そこらへんとの関係とか。

電子書籍というネーミングに惑わされすぎかもな。

InDesign + JavaScript = ?: DTP

といってもDegital Text Platformのことだけど。

ますます、Javascriptとは関係のない話。
電子書籍の場合、厳密な組版ルール(例えば、Indesignでいうところの文字組み調整機能を駆使するようなもの)がどれほど求められるんだろうか。

画面サイズを自由に変更できるような端末の場合(というか文字サイズを拡大縮小しても一行が画面に収まるようになるという意味で)、版面という概念がないわけで。

PDFは当分の間、標準規格とはなるだろうが(オンラインジャーナルの場合PDF配信が標準)、商業的には別の規格が出てくる予感。結局HTML5なのか。

携帯端末、スマートフォン端末、電子ブックそれぞれで別の規格を作られてもたまったものじゃない。
PDFだと画面の拡大・縮小の問題があるわけだし。

Indesignでの組み方ってのとデータの吐き出し方ってのはよーく考えておかないといけないような。

InDesign + JavaScript = ?: 2010

年が明けてしまった。

アップルがタブレットPC発売を公表するのではないかという噂が大分前から出ている。macbook airは確かに薄いものの、自分的にはインパクトには欠けていた。もしかしたら、タブレットPCを出すための準備的なものだったのかもしれない。

Kindleがヒットしているようである。アップルのタブレットPCはそれに近い端末、と考えることができるかもしれない。サイズはB6ぐらいだろうか。iPhoneに代表されるスマートフォンで青空文庫を読んだり、ネットしたりというのは定着しつつある。

電子書籍ということをずっと考えているのだが、しっくりこない。書籍の電子版という意味では、PDFがある。Kindleだと文字サイズや行間、フォントとか版面も変更できるらしい。よくよく考えれば、HTMLがやっぱり柔軟な気もする。CSS+JavaScript+Flashで文字サイズ以上に何でもできるからなぁ。php使えば、データベース的に書籍データを再構築して並べ替えや抽出もできるし。

Indesignで書籍を制作した結果の副産物としての電子書籍を考えると、組み方も注意しないといけないのかも。XML吐き出しで何とかなるっていう部分もあるっちゃあるけども。

Indesignをただの組版ソフトとしてより、文字データと画像データの集約ツール的として認識して使うべきな気がしてきた。アニメーションは組み込めないけどそのうちフラッシュも組み込めるようになるだろう。実際、電子書籍て考えるとDirectorとかなのかもしれないが。

学術書というか、いわゆる教科書の未来、てのを考えると、B6サイズぐらいのタブレットPCが出現して、学生たちがそれを持ち歩いて教科書は電子データ化されて・・・となるのはもうそこまで来ていると思うのだが(アメリカでは学生たちはKindleにテキストを入れているようだ)、果たして日本では何時?ということだなぁ。

タブレットPCだと、電子化された書籍というよりはもっとインタラクティブな要素のある書籍(というより画面?インターフェース?もしくはソフトウェアになるのか)なんだろうか、求められるのは。

ちょっと真面目に教育の現場を調べないと。

InDesign + JavaScript = ?: コピペじゃなくてムーブ

通常indesignで組む前に元データを整形する。
学術書籍の場合、章タイトル→執筆者→本文→文献→本文で使用する図表のタイトル・説明、という形に元データがなっていることが多い。
整形の際に、本文中の図表を挿入する箇所(元データの出力紙に指定されている)に、図表のタイトル・説明をカットアンドペーストして移動させているのだが、それが面倒になってきた。図表10点ぐらいのタイトル・説明をいちいちカットアンドペーストする気にもならんというか。

てことで挿入箇所に制御文字列を書き、挿入すべき文字列をタグで囲むことで挿入箇所へ文字列を移動させるスクリプトを考えていたのだが、こうゆう場合、文字列をcontentsで拾うより、moveメソッドを使うのがまっとうなんだな、と(マニュアル読み直した成果)。moveで移動することで、元の文字列の属性も保たれるし。

いやぁ、勉強不足だな、ほんとに。

InDesign + JavaScript = ?: 表の自動調整

大分前に表の自動調整のスクリプトを書いたのだが、文字数×フォントサイズでセルの幅を算出していて、欧文フォントのみの表の場合だとその算出方法では幅が合わないので修正。

考え方としては列ごとに各セルを調べて、文字列の最初から最後の幅の最大値を列幅とするもの。

//表のあるフレームを選択
var myTable = app.activeDocument.selection[0].tables[0];
var left, right, max, width;

//列ごとに各セルを調べる
for(var i=0; i<myTable.columns.length; i++) {
max = 0;//文字列の幅の最大値、列ごとに初期化
for(var j=0; j<myTable.columns[i].cells.length; j++) {
var myCell = myTable.columns[i].cells[j];
left = myCell.insertionPoints[0].horizontalOffset;//文字列の左端の位置
right = myCell.insertionPoints[-1].horizontalOffset;//文字列の右端の位置
width = right - left + myCell.leftInset + myCell.rightInset;//セルのマージンも計算に入れとく
if(max<width) max = width;
}
myTable.columns[i].width = max + margin;
}


という感じで列幅が文字列の幅にぴったり合う。
が、文字列が二行になってる場合とか、オーバーフローしてる時とかのケースも考える必要があるな。。。

ScriptClip: リンク画像のファイル名を取得してクリップボードに入れる.js

ScriptClip
#include 'c.js';
#target 'indesign';
(function(){
//
var LINK_NAME = [];
//リンクの区切り文字
var DEMI = "¥t";
//選択範囲or全てのリンク画像
c(app.activeDocument.selection.length > 0 ? app.activeDocument.selection : app.activeDocument.links).each(function(){
    //リンクの場合とそれ以外
	if(this.constructor.name== 'Link'){
		  LINK_NAME.push(this.name);
	}else{
		c((this.constructor.name== 'Image' || this.constructor.name== 'EPS') ? this : this.allGraphics).each(function(){
			LINK_NAME.push(this.itemLink.name);
		});
	}
});
if(File.fs == 'Windows'){
alert('VBには対応しておりません。');
}else{
//forOSX
try{
var appScript = "try¥r" +"set the clipboard to  ¥"" + LINK_NAME.join (DEMI) + "¥" as text¥r"+"return true¥r"+ "on error¥r"+ "return false¥r"+ "end try";
return app.doScript(appScript , ScriptLanguage.APPLESCRIPT_LANGUAGE);
}catch(e){};
}
})();

InDesign + JavaScript = ?: 今さらながら

InDesign CS3 スクリプティング ガイド JS.pdf
InDesign CS3 スクリプティング チュートリアル.pdf
を熟読中。今まではやりたいことだけに絞って、「オブジェクトモデルを調べる→ネットで調査→スクリプト書く」、という流れだったのだが、前回のエントリのような基本的な部分がわかっていない、というのはまずいな、と。

てことで改めて読み直すと大分頭がすっきりしてきた。
マスターページ辺りの制御はまったくしていなかったのでメモっておこう。

//マスターページ(名前はA-マスター)の取得
var myMaster = app.activeDocument.masterSpreads.item("A-マスター");

//マスターページをアクティブなページに適用
var myPage = app.activeDocument.activePage;
myPage.appliedMaster = myMaster;

//マスターページのアイテム(ラベル設定済み)のオーバーライド
myMaster.textFrames.item("スクリプトラベルの名前").override(myPage);

InDesign + JavaScript = ?: スピードと量

辞書系書籍の制作。
項目数が3000近くあって、頁数は500弱ぐらい。
処理的には単純で反復作業が多いため、個々の処理についてスクリプトで対応しようと考えており、実際スクリプトは問題なく作れるのだが、いざ走らせてみると時間がかかる。

まぁスクリプト一晩走らせといて次の日続きを、というのも手なんだが、なんせ時間がない・・・。

試みに、1ページず追加してテキストフレームを置いて連結させて、というスクリプトで、コンソールでログ吐き出しながら、500ページ分処理すると、ページが進むにつれてどんどん遅くなっていく。
コードの書き方に問題があるとは思いたくはないw。スピードを上げるやり方ってのがあるんだろうか。
もしくは、分散処理を考えるべきなのか(500×1ではなく100×5とか)。

そもそもindesignでは大規模文書には向いていないのか(FrameMakerという手もある)。
結局今回は人力w。

後、躓いたのがテキスト変数へのアクセス。
あ・か・さ・た・な・・・というツメを作るのにランニングヘッド(段落スタイル)でテキスト変数を使うのだが、スクリプトでそのテキスト変数にアクセスする仕方がわからない。SpecialCharacterにはあるんだが、個々の変数にどうアクセスするのか、っつー。
結局、ライブラリにテキスト変数入りのテキストフレーム作って保存しといて、それをコピーという手で解決。んー、アクセスできるのかな?

InDesign + JavaScript = ?: XML

間が空いた。
論文等を組む場合。ほぼWORD入稿。てことでWORDの書式を生かしてIndesignで流し込む、ていう方法でやっているのだが、WORD上での太字とか斜体、上付き、下付きが流し込む際にはがれるケースがあるのが鬱陶しい。

正確には上付き、下付きはOKで、日本語の斜体、太字がはがれることが多いようだ。原稿とモニタのつきあわせはなるたけ避けたい。てことでその書式を保持できる方法を調べなきゃなぁ。

論文の場合、書誌情報が必要なことがあるから、WORD原稿に簡易タグ→XML化→(自動?)組版→書誌情報抜き出し、というのが楽かな、と思ったが、結局ネックなのが簡易タグ。簡易タグ打ち込むより、Indesign上でCMD+1とかでスタイル適用した方が早いんじゃないかと。で書誌情報抜き出しは段落スタイルあたりでJavascriptで。XMLは魅力ではあるのだが、タグを手動でつけるのならしんどそう。

WORDの書式が完成度が高くてそっからXML化するのならよさそうだが。

いずれにせよ、作業効率化、短縮化を図らないと、残業が増えるだけで良くないな。

ScriptClip: 選択している画像をPhotoShopで開く

ScriptClip
//2009-09-18 選択している画像をPhotoShopで開く。
//2009-09-29 修正
#include 'c.js';
#target 'indesign';
(function(){
c('selection').each(function(){
	c((this.constructor.name== 'Image' || this.constructor.name== 'EPS') ? this : this.allGraphics).each(function(){
	var bt=new BridgeTalk();
	bt.target = 'photoshop';
	bt.body = uneval(function(file){
		open(File(eval(file)));
		})+"('"+uneval(this.itemLink.filePath)+"');";
	bt.onError = function(e){$.writeln(e.body);};
	bt.send(10);
	});
});
})();

ScriptClip: 選択した画像にクリッピングパスをつける

ScriptClip
//2009-09-18 とりあえず。PhotoShopの最初のパスを決め打ち。
#include 'c.js';
#target 'indesign';
(function(){
 
c('selection').each(function(){
	c((this.constructor.name== 'Image' || this.constructor.name== 'EPS') ? this : this.allGraphics).each(function(){
		//
		try{
		//clippingTypeの値で振り分け
		switch(this.clippingPath.clippingType){
			 //Photoshopパス
			  case 1886613620 : 
 
			  break;
 
			  //エッジの検出
			  case 1685349735 : 
 
			  break;
 
			  //アルファチャンネル
			  case 1634756707 : 
 
			  break;
 
			  //ユーザーによるパスの修正
			  case 1970106484 : 
 
			  break;
 
			  //なし
		      case 1852796517 :
				this.hasOwnProperty ('clippingPath') &&  this.clippingPath.appliedPathName = this.clippingPath.photoshopPathNames[0];
			  break;
		  }
		}catch(e){
		$.writeln(e);	
		}
	});
});
})();

ScriptClip: ドキュメント中から文字を正規表現で検索置換

ScriptClip
//ドキュメント中に存在するテキストを正規表現で検索して置換。複数ある場合は手で修正。
//2009-09-17 とりあえず
(function(){
#include 'c.js';
function myerror (message){alert(message)};
if(app.activeDocument.selection == 0)return myerror('検索する文字列を選択してください。');
//
var SELECTION = app.activeDocument.selection[0];
//
if(!SELECTION.constructor.name.match('Word|TextStyleRange|Text|Paragraph|Character'))return myerror('検索する文字列を選択してください。');
//検索の初期化
app.findGrepPreferences = app.changeGrepPreferences =NothingEnum.nothing;
//検索オプション
app.findChangeGrepOptions.includeLockedLayersForFind = false;//ロックされたレイヤーをふくめるかどうか
app.findChangeGrepOptions.includeLockedStoriesForFind = false;//ロックされたストーリーを含めるかどうか
app.findChangeGrepOptions.includeHiddenLayers = false;//非表示レイヤーを含めるかどうか
app.findChangeGrepOptions.includeMasterPages = false;//マスターページを含めるかどうか
app.findChangeGrepOptions.includeFootnotes = false;//脚注を含めるかどうか
app.findChangeGrepOptions.kanaSensitive = true;//カナを区別するかどうか
app.findChangeGrepOptions.widthSensitive = true;//全角半角を区別するかどうか
////検索文字の設定
app.findGrepPreferences.findWhat = SELECTION.contents;
//
var HIT_WORD = [];
//
c(app.activeDocument.findGrep(true)).each(function(){SELECTION.contents !== this.contents && HIT_WORD.push(this.contents);});
//重複の削除
HIT_WORD = uniq(HIT_WORD);
if(HIT_WORD.length == 0)return myerror(SELECTION.contents +'にヒットする文字列が見つかりませんでした。')
SELECTION.contents =  HIT_WORD.length > 1 ?  "["+HIT_WORD.join (',') +"]" : HIT_WORD[0];
alert('検索が終わりました。');
return;
//UNIQ
function uniq(arr){
    for (var i=0,l=arr.length; i<l; i++) {
        for (var j=0; j<i; j++) {
            if (arr[i] === arr[j]) {
                arr.splice(i--, l-- && 1);
            }
        }
    }
    return arr;
}
})();

ScriptClip: 字形の変換サンプル。日〜土までの文字の字形を変える。

ScriptClip
//2009-07-29 c.jsの変更に伴う修正
#include 'c.js';
(function(){
var weeks ={
	'正規表現' : "(日|月|火|水|木|金|土)",
	'パターン' : {
		'通常'    :    {'日' : 3284 , '月' : 1860, '火' : 1360 , '水' : 2603, '木' : 3814, '金':1754, '土':3156},
		'括弧' :    {'日' : 8197 , '月' : 8198 , '火' : 8199 , '水' : 8200 , '木' : 8201,'金':8202,'土':8203},
		'白丸' :  {'日':10471,'月':10472,'火':10473,'水':10474,'木':10475,'金':10476,'土':10477},
		'黒丸' : {'日' : 10753 , '月' : 10754,'火':10755,'水':10756,'木':10757,'金':10758,'土':10759},
		'白四角' : {'日':11023,'月':11024,'火':11025,'水':11026,'木':11027,'金':11028,'土':11029},
		'黒四角' : {'日':11296,'月':11297,'火':11298,'水':11299,'木':11300,'金':11301,'土':11302},
		'白角丸' : {'日':11566,'月':11567,'火':11568,'水':11569,'木':11570,'金':11571,'土':11572},
		'黒角丸' : {'日':11835,'月':11836,'火':11837,'水':11838,'木':11839,'金':11840,'土':11841}
	},
	'pList' : function(){
				var List = [];
				for(var x in weeks['パターン'])weeks['パターン'].hasOwnProperty (x) && List.push(x);	
				return List;
		},
	'dialog' : function(TEXT){
				var my_list = weeks.pList();
				var my_dialog = app.dialogs.add({name:'検索置換', canCancel:true});
					with(my_dialog) {
					with(dialogColumns.add()) {
						staticTexts.add({staticLabel:TEXT});
						with (borderPanels.add()) {
							var my_radio_group = radiobuttonGroups.add();
							with (my_radio_group) {
								for (var i = 0; i < my_list.length; i++){
									if (i == 0) {
										radiobuttonControls.add({staticLabel:my_list[i], checkedState:true});
									} else {
									radiobuttonControls.add({staticLabel:my_list[i]});
									}
								}
							}
						}
					}
				}
				if (my_dialog.show() == true) {
					var ans = my_radio_group.selectedButton;
					my_dialog.destroy();
					return my_list[ans];
				} else {
					my_dialog.destroy();
				}
		},
	'changeGlyph' : function(myRange,Target){
			try{
				app.findGlyphPreferences = app.changeGlyphPreferences = NothingEnum.nothing;
				app.findGlyphPreferences.appliedFont  = app.changeGlyphPreferences.appliedFont = myRange.appliedFont;
				app.findGlyphPreferences.glyphID = weeks['パターン'][Target[0]][myRange.contents]; //検索グリフ
				app.changeGlyphPreferences.glyphID =  weeks['パターン'][Target[1]][myRange.contents]; //変更グリフ
				return myRange.changeGlyph ();
			}catch(e){
				//throw e;
				return false;
			}
	},
	'myRegex' : function(my_range_obj,CGP){
			try{
				//検索の初期化
				app.findGrepPreferences = app.changeGrepPreferences =NothingEnum.nothing;
				//検索オプション
				app.findChangeGrepOptions.includeLockedLayersForFind = false;//ロックされたレイヤーをふくめるかどうか
				app.findChangeGrepOptions.includeLockedStoriesForFind = false;//ロックされたストーリーを含めるかどうか
				app.findChangeGrepOptions.includeHiddenLayers = false;//非表示レイヤーを含めるかどうか
				app.findChangeGrepOptions.includeMasterPages = false;//マスターページを含めるかどうか
				app.findChangeGrepOptions.includeFootnotes = false;//脚注を含めるかどうか
				app.findChangeGrepOptions.kanaSensitive = true;//カナを区別するかどうか
				app.findChangeGrepOptions.widthSensitive = true;//全角半角を区別するかどうか
				app.findGrepPreferences.findWhat = weeks['正規表現'];//検索文字の設定
				return c(my_range_obj.findGrep(true)).each(weeks.changeGlyph,CGP);//検索の実行(reverse)
			}catch(e){
				throw e;
			}
	}
};
 
var SOURCE_P = weeks.dialog('元になるパターンを選択してください。');
var TARGET_P = weeks.dialog('置換するパターンを選択してください。');
c('S').each(weeks.myRegex,[SOURCE_P,TARGET_P]);
})();
 

ScriptClip: プログレスバーのサンプル

ScriptClip
function CreateProgressPanel(myMaximumValue, myProgressBarWidth , progresTitle){
	myProgressPanel = new Window('window',  typeof progresTitle == 'string' ? progresTitle : 'Processing....');
	with(myProgressPanel){
		myProgressPanel.myProgressBar = add('progressbar', [12, 12, myProgressBarWidth, 24], 0, myMaximumValue);
	}
	var PP = {
		'ProgressPanel' : myProgressPanel,
		'show' : function(){this.ProgressPanel.show()},
		'hide' : function(){this.ProgressPanel.hide()},
		'max' : myMaximumValue,
		'barwidth' : myProgressBarWidth,
		'val' :  function(val){
			if(typeof val == "undefined")return this.ProgressPanel.myProgressBar.value;
			this.ProgressPanel.myProgressBar.value = val+1;
			this.show();
			this.hide();
			this.show();
			//$.writeln(this.ProgressPanel.myProgressBar.value);
	}
	}
	return PP;
}
 
//cにeachProgressを組み込む
(function(){
	if(typeof c == 'undefined')return;
	var progress = {
	  	'eachProgress' : function(fnc,pbtitle,arg) {
	  	    var l = this.length;
	  	    var res = [];
			var ProgressPanel = CreateProgressPanel(l, 500,pbtitle);
			ProgressPanel.show();
 
			if(typeof fnc == 'function'){
			for(var i = 0;i<l;i++){
				 ret = fnc.call(this[i],this[i],arg);
				 typeof ret != "undefined" && res.push(ret); 
				 ProgressPanel.val(i);
			 }
			}
			ProgressPanel.hide();
			if(res.length > 0){
                return c(res);
			}else{
                return this;
		    }
   	 	}
	}
	c.extend(c,progress);
	//c.extend(Object,progress);
	c.extend(Array,progress);
})();
 

ScriptClip: フォントファミリーとスタイルのリストを作る。

ScriptClip
//ExtendScriptToolKitから利用する
//コンソールに吐き出されるのでこれをコピペして保存。
//テキストエディタで修正が必要。だったりする。
//何に使うの?
(function(){
var pre = "";
$.writeln("var fontFamilyList = {");
for(i=0;i<app.fonts.length;i++){
try{
		check(app.fonts.item(app.fonts[i].name));
}catch(e){
 
}
};
$.writeln("}");
$.writeln("}");
 
function check(f){
if(pre == ""){
	pre = f.fontFamily;
	$.writeln("'"+f.fontFamily+"' : {");
}
if(pre == f.fontFamily){
$.writeln("'"+f.fontStyleNameNative+"' : '"+f.name+"',");
}else{
	pre = f.fontFamily;
	$.writeln("},");
	$.writeln("'"+f.fontFamily+"' : {");
}
}
})();

InDesign + JavaScript = ?: グループでの作業

自分はある程度スクリプトを理解しているのだが、部下もしくは同僚がそうでない場合どうするか、という問題。

どう考えたって、「手作業」VS「タグ付け+半自動化」での後者が圧倒的に処理速度が速い。では、スクリプトを理解してもらえるように勉強してもらうのがよいのか、というとこれも問題。
個人の学習意識の問題だからな・・・。
自分にしても、楽しいから独学で勉強したのであって、強要されていたら勉強したかどうか。

てことを考えると、スクリプトを誰にでも使えるようにUIを設定したり、エラー処理できるようにしておくとか改良しておく方が早いかな。
敷居の低いスクリプト作っとけば、ネットで公開とかも可能だろうし。現状のスクリプトでは公開できるレベルではないw

スクリプトで出来る作業は集約して、一括スクリプト処理しよう。頭を使う仕事に時間を使いたいわね。

InDesign + JavaScript = ?: easily

最近1冊組んで、2冊修正。やはり細々したところで時間がかかる。

新たに組んだ分で言えば、余計な半角スペースの除去とか、マイナスとかハイフンを音引きに変換、文献リストの形式の統一、演算記号の前後をベタとか・・・。こういうのを修正していくのがしんどい。
ここらへんは、対話型のスクリプトを作って対応するしかないか。一括処理だと怖すぎなもので。どの本についてもこういう処理は必要になってくるわけだし。

修正分だと、二分ダーシとかの統一とか。ここもスクリプト処理かな。新規作成についてのスクリプトはある程度汎用性を持つように作り直したから、次は修正用スクリプトの見直しですね。

これから組む分について。文字データの修正をどのタイミングですべきか。前の会社では、初期は分担作業をしていて、図作成+原稿データの修正(原稿整理でのアカの修正)+データの構造化を別の人にやってもらっていたのだが、データの構造化が終わったワードのファイルに文字修正のマクロ(全角→半角とか、カンマ、ピリオド、括弧の統一ぐらい)を当てていた。ただ、後期はIndesignにデータを流し込んでからスクリプトで文字修正を行っていた。

将来的なことを考えると、流し込む前の構造化されたデータをある程度完全なものにしておきたい気もする。構造化されたデータには、表のデータ、図表のキャプション、図のファイル名、図の挿入箇所も全て記述されていて、組版以外にも流用できる形式になっていて、本文データも文字修正がなされていた方がいいような気がするこの頃。

ま、ほんとはワードじゃなくてプレーンなテキストファイルがいいんだけどな。作業フロー考えなきゃなー。

文字ベースの書籍でないケースはどうするか、という問題もあるし。グラフィックフレームの処理についても少し調べておかないと。ラスタ画像はIndesign上である程度縮小してもいいような気がするし。

InDesign + JavaScript = ?: 未来

将来性で考えると、Indesignで書籍を作ったままでいいのか、というお話。
近い将来では、とりあえずPDFにしとけば問題なさそう。が、今の会社の特殊性を考えると、PDFだけではビジネスにならない。結局e-learningの教材的なものを作れるか、てことと、どれだけ使いやすさをUPさせれるか、ということ。

Indesignからフラッシュへ、とかIndesignからWEBパブリッシングへ、という流れをふまえてCS4に色々機能が付加されたわけだが、どこらへんまでできるようになっているのかを調べておかなきゃなぁ。

InDesignのVBScript学習帳: No.004 第2章~Scriptのデバッグや新しい記述の方法について

InDesignのVBScript学習帳
Scriptを完成させた後、実行させてみるとエラーが出ることがあります。Scriptの書き方が間違っていたり、アルゴリズムが良くなかったりすると動かないのです。
動かなったScriptを動くように修正していく作業の事を「デバッグ」と呼びます。
最初の頃はエラーが出て、動かない理由が分からずに苦労することも多々あると思います。そういう苦労から解放されるためにも、エラーが出ないように書いていく方法を勉強していきましょう。
まずは、存在しないメソッドやプロパティを呼び出した際に出る警告を見てみましょう。新しい用語が出てきましたので説明をしておきます。
メソッドとは、オブジェクトが持っている機能の名称のことで、検索するときやテキストフレームを移動させたりするときに使うものです。
プロパティとは、オブジェクトが持っている値のことで、テキストフレームに入力されている文字列やテキストフレームの座標、ルビ文字などのことです。
では、次の名称でSubプロシジャーを作ってください。
Sub デバッグのお勉強()
さて、次に示すコードを入力してください。
Dim MyInDesign As InDesign.Application
Set MyInDesign = CreateObject("InDesign.Application.CS")
With MyInDesign
Set MyDoc = .Documents.Add
MyDoc.SaveAs "C:\test.indd" '保存
Set MyDoc = Nothing
End With
Set MyInDesign = Nothing
上記のコードでは新しい記法が出現しました。その説明をしておきます。
3行目のWith MyInDesignという構文ですが、省略するときの記法になります。本来4行目を記述するときは、Set MyDoc = MyInDesign.Documents.Addと記述するのですが、MyInDesignを記述するのが面倒なので、Withブロックで指定しています。例文では1行しか対象になるコードがありませんが、これが何百、何千もあると大変です。さらにWithブロック内の省略については高速化できるという「おいしい」特典もあるのです。このWith ~という構文はEnd Withが書かれている行の前まで有効になりますので、この範囲内で『.』キーを押すと、Applicationクラスのプロパティやメソッドが表示されるようになります。今後の記事でも多用していくであろうと思いますので、「省略記法なんだな」と思って頂ければ結構です。
では、Scriptの流れを説明いたします。4行目で新規ドキュメントを作って参照できるようにMyDocに格納しています。5行目のMyDoc.SaveAsに保存したいFileのPath("C:\test.indd")を指定して保存しようとしています。
実はこの5行目がエラーの直接原因となっています。
2-001
エラーの理由は、MyDocに格納したドキュメントのメソッドSaveAsを呼び出そうとしていますが、そのメソッドが存在しないのでエラーです。という事をVBEが教えてくれたのです。さて、正解のメソッドは何だったのでしょうか? それを調べる方法がありますので、次の画面を見て下さい。
2-002
この画面は、オブジェクトブラウザといいます。タイプライブラリで定義されたプロパティやメソッドを検索することができます。
◆ダウンメニュー【表示(V)→オブジェクトブラウザ(O)】と選択します。
このオブジェクトブラウザは『F2』キーを押すことでも表示できます。
画面ではオブジェクトブラウザのウィンドウ左上のコンボボックスをクリックして選ぶ所が表示されています。InDesignがハイライトしていますが、ここには参照設定で選択したタイプライブラリが表示されます。参照設定をしていない時にはInDesignが選べませんので、参照設定をしておいてくださいね。
InDesignを選ぶと、左下にInDesignで定義されているクラスの一覧が表示されます。右下には左下で選択したクラスのメンバが表示される仕組みになっています。メンバにはメソッドとプロパティの両方が表示されます。
最下部のグレーの領域には、メンバに表示されたプロパティやメソッドの説明が英文で表示されます。
では、InDesignのタイプライブラリを選択したので、正しいメソッドを探しましょう。
画面の検索ボックスにキーワードとして「Save」と入力して『Enter』キーを押して下さい。「SaveAs」で検索してもダメですよ。
2-003
画面が切り替わり、検索結果にいくつかのメンバが表示されました。このメンバにはSaveAsはありません。ですからエラーを表示されたんですね。
正しくは「Save」でした。最下部の説明には英文で引数について書かれていますが、本章では触れません。オブジェクトブラウザを閉じて下さい。
5行目のSaveAsをSaveに修正して実行してみましょう。正しく処理が完了すればCドライブにtest.inddというドキュメントデータが保存されていると思います。
          *
また、この章で勉強して欲しい事がもう1つあります。それはインテリセンス機能をフルに活用することです。そもそもインテリセンス機能を使って記述していれば、上述のようなエラーは起こり得ないのです。
それでは間違っていたScriptをもう一度準備して下さい。
Dim MyInDesign As InDesign.Application
Set MyInDesign = CreateObject("InDesign.Application.CS")
With MyInDesign
ここまでは普通に記述します。4行目の変数MyDocにはDocumentを入れることが分かっていますので、MyDocの型(種類みたいなモノです)をInDesign.Documentとして宣言しましょう。4行目の前に次の1行を入れることにします。
Dim MyDoc As InDesign.Document
この宣言を入れることによって、MyDocはInDesignのDocumentを格納する変数として宣言されることになります。この行を加えることでMyDocにもインテリセンス機能が働くようになります。
元の4行目はそのままでOKです。
Set MyDoc = .Documents.Add
では元の5行目のMyDocの後の『.』を選択して、さらに『.』キーを押してインテリセンス機能の画面を表示させましょう。
2-004
画面では修正するSaveAsの項目をSaveにしたいので、Saveをハイライト表示させています。ハイライトさせたら『Tab』キーを押して下さい。『Enter』を押すと、改行されてしまいますので注意して下さい。
MyDoc.Save "C:\test.indd" '保存
これ以降には修正がありませんので、そのままにしておきましょう。
Set MyDoc = Nothing
End With
Set MyInDesign = Nothing

InDesignのVBScript学習帳: No.003 第1章~ExcelVBAでの開発に慣れてみよう

InDesignのVBScript学習帳
ExcelとはMicrosoft社のOffice製品群のアプリケーションです。この位の説明で大丈夫でしょう。InDesignを使用している所では、十中八九所有しているかと思われます。もしお持ちでない場合には、本講座の内容が実際に体験できないと思います。その際には大変心苦しいのですが、導入して頂くか、デバッグ作業やコーディング効率が落ちてしまいますがScriptのマニュアルを片手に頑張るか、JScriptのデバッガを頼りにJScriptで頑張ってみるという方法もございます。私は現時点でJScriptには疎く、コードを読んで概略を掴む程度のスキルしか持ち合わせていませんのでご質問などには完全に対応できないと思います。ご了承くださいませ。
さて皆さんは「マクロ」という言葉をお聞きになったことはありますでしょうか? この「マクロ」というのは、アプリケーションを内部または外部からコントロールするための方法なのですが、今回はそのマクロを使ってInDesignを外部コントロールしようという企画です。
始めてInDesignをコントロールするので、できれば開発環境を用意した方が便利です。そういう意味からも本講座ではOffice製品群のVBEを使ってInDesignをコントロールしていくというアプローチをしています。
ではExcelを起動してください。さらにマクロを書くためにVBEを起動します。
001
◆ダウンメニュー【ツール(T)→マクロ(M)→Visual Basic Editor(V)】と選択します。デフォルトのショートカットでは『Alt+F11』ですから、そのショートカットで覚えて頂ければ大丈夫です。
002
画面が切り替わって「Microsoft Visual Basic」というウィンドウが開いたと思います。
では「プロジェクトウィンドウ」ですが、Book1というxlsファイルに標準で3つのシートを作る環境設定の場合、画像のようにSheet1からSheet3までが用意されます。そしてThisWorkbookというものも用意されます。
今回はThisWorkbookにマクロを書くことにしますので、このThisWorkbookをダブルクリックしておいてください。
003
さて、今度は「参照設定」をします。
◆ダウンメニュー【ツール(T)→参照設定(R)】と選択します。
次の画面が表示されます。
004
参照設定についてですが、InDesignのScriptを書くときにコード補完(インテリセンスと呼ばれています。)させると便利なので、Scriptを書く前に設定しておきましょう。
005
画面では「Adobe InDesign CS Type Library」にチェックをしましたが、お手持ちのInDesignのVersionによっては画面の表示が違いますので、対象となるInDesignのVersionを選んでください。
チェックしたらOKボタンを押して設定は完了です。
006
先程ThisWorkbookをダブルクリックしておいてもらいましたが、ダブルクリックすると新しいウィンドウが開いてカーソルが立ちます。その部分に以下のように入力してみてください。
Sub InDesignで新規文書を作成する
ここまで入力したら『Enter』キーを押して下さい。
自動的に()がSubの行末に付加され、さらにEnd Subという行が下に生成されます。
このSubからEnd SubまでをSubプロシジャーと呼びます。
この間に実際のコードを書いていきます。
画面では途中まで入力している状態になっていますので、同じように次の行を入力してください。(IMEをOffにしておくと良いです)
Dim MyInDesign AS InDesign
と入力したら『.』キーを押して下さい。画面が変化します。これがインテリセンスしている所です。そのまま続けて『App』と入力するとその部分まで移動してくれます。Applicationがハイライトしたら、『Enter』キーを押して下さい。
次の行にカーソルが移動しますので、次のように入力してください。
Set MyInDesign = CreateObject("InDesign.Application.CS")
ここはお手持ちのInDesignのVersionによって書き換えて下さい。
まだ古い環境の方がいらっしゃるかもしれませんので、Version2の宣言も書いておきます。
Set MyInDesign = CreateObject("InDesign.Application.2.0J")
InDesignCSならSet MyInDesign = CreateObject("InDesign.Application.CS")
InDesignCS2ならSet MyInDesign = CreateObject("InDesign.Application.CS2_J")
InDesignCS3ならSet MyInDesign = CreateObject("InDesign.Application.CS3_J")
でOKです。1つのVersionしかインストールしていないのであれば、次のように書くこともできます。
Set MyInDesign = CreateObject("InDesign.Application")
最新のVersionのInDesignが自動起動します。これまで書いてきたInDesignをコントロールする技術をActiveX/Comと呼びます。オートメーションまたはキック起動などとも呼びます。
さて、SubプロシジャーにDim文とSet文の2行を入力しましたが、これがInDesignをコントロールする最低限の宣言です。これは基本ですので、コピペした方は、煩わしくても打ち込んで覚えて下さいね。では早速、肉付けをしていきましょう。3行目に次のように入力します。
MyInDesign.Documents.Add
4行目に次のように入力します。
Set MyInDesign = Nothing
007
画面では入力し終わった状態を示しています。
以上でScriptが完成しました。早速実行してテストしてみることにしましょう。
008
画面のように右三角のアイコンをクリックするか、プロシジャー内にカーソルを置いたまま『F5』キーを押してマクロの実行をしてください。上手くInDesignが起動して新規文書が作成されていれば成功です。

InDesignのVBScript学習帳: No.002 序章~経緯と経過を回想(お急ぎの方は、読み飛ばしてもらって構いません。)

InDesignのVBScript学習帳
さて、思いつきから始まった本企画ですが、最終的な目的はScriptをラクして作れるスキルを身につけようというものです。
私も最初の頃は失敗の連続で、マニュアルが理解できない・実際に動かしてもエラー連発・そして諦めモード突入という状態でした。
そんな私が参考にさせて頂いたのが、かの有名な「PageMaker & InDesign Scripting」というサイトでした。このサイトには自作スクリプトを作る過程で情報収集している最中にたどり着いたのですが、実際にInDesignをコントロール出来ている点、VBで開発された点などを知って、俄然やる気になったのを思い出します。
勉強がてらにサンプルScriptをCD-ROMからコピーしてきて、構文を読み解きました。さらに、そのサンプルに徐々にコードを継ぎ足して、別の機能のScriptに仕立てる練習もしました。
そんなこんなで実用とは言えないけれども、十数種類におよぶサンプルScriptが出来ていたので、Scriptのサイトを立ち上げました。
社内的な環境整備によりInDesign2からInDesignCSに移行した頃、本格的にScriptにハマることになります。日々、Scriptを作っては作業負担を減らせるようになり、今では難有りの案件に最初からScriptを作って対応できるレベルまで来ました。
Google等の検索エンジンに「InDesign Script」と入れて検索すると、私が始めてScriptingした当時より大量に情報が出てきます。これには感慨深いものがあります。また、この企画を通してさらにWebサイト上に有益な情報を蓄積できるように精進してまいりますので、どうぞ皆様よろしくお願いいたします。

InDesignのVBScript学習帳: No.001 はじめに

InDesignのVBScript学習帳
「InDesignScripting」の講座と呼べるかどうか怪しい感じですが、敷居が高すぎる現状を打開すべく、拙い解説ですが気力の続く限り更新していきたいと思っていますので、どうぞよろしくお願いいたします。 <img src="http://counter2.blog.livedoor.com/c?ro=1&act=rss&output=no&id=2460915&name=ryusei3000&pid=53146" width="1" height="1" />