2008年12月21日日曜日

Illustrator CS3でScriptUIするときはBridgeTalkしなくちゃいけない?


ScriptUIを使っていてハマったのでメモ。
以下のスクリプト。


parette = new Window("palette","ScriptUI TEST");
parette.orientation = 'row';
parette.btn = parette.add('button', undefined, '選択したものの数は?');

parette.btn.onClick = function() {
parette.close();
var obj=app.activeDocument.selection;
alert(obj.length);
}
parette.show();
これをIllustratorで動かしてクリックしても、反応しない。
ちなみに、InDesignで動かせばちゃんと選択項目の数を教えてくれる。
parette = new Window("palette","ScriptUI TEST");
parette.orientation = 'row';
parette.btn = parette.add('button', undefined, '選択したものの数は?');

parette.btn.onClick = function() {
parette.close();
var bt=new BridgeTalk();
bt.target = "Illustrator";
bt.body ="alert(app.activeDocument.selection.length)";
bt.send();
}
parette.show();
これなら動く。
どうも、Illustrator CS3でScriptUIを使う場合は、BridgeTalkで話しかけないと反応しないみたい。
うーん…。

2008年12月20日土曜日

InDesignスクリプトのArrayを拡張してみる

選択範囲の大きさを求める関数を、InDesignのArrayに拡張してみるテスト。
Arrayのprototypeに関数を設定してしまえばよい。
Array.prototype.visibleBounds=function(){
var ary=this[0].visibleBounds;
if(ary){
for(i=1;i<this.length;i++){
var follow=this[i].visibleBounds;
if(ary[0]>follow[0]) ary[0]=follow[0];
if(ary[1]>follow[1]) ary[1]=follow[1];
if(ary[2]<follow[2]) ary[2]=follow[2];
if(ary[3]<follow[3]) ary[3]=follow[3];
}
}
return ary;
};

Array.prototype.geometricBounds=function(){
var ary=this[0].geometricBounds;
if(ary){
for(i=1;i<this.length;i++){
var follow=this[i].geometricBounds;
if(ary[0]>follow[0]) ary[0]=follow[0];
if(ary[1]>follow[1]) ary[1]=follow[1];
if(ary[2]<follow[2]) ary[2]=follow[2];
if(ary[3]<follow[3]) ary[3]=follow[3];
}
}
return ary;
};

選択したもの全体の大きさを出したいときは、選択して
var objs=app.activeDocument.selection;
$.writeln(objs.visibleBounds());
$.writeln(objs.geometricBounds());

で、visibleBounds,geometricBoundsの形でとれる。
JavaScriptは不思議だー。

2008年12月14日日曜日

Illustratorで、選択オブジェクトの持つプロパティと値をコンソールに書き出す

InDesignはオブジェクトの値をtoSource()で見られるけれど、Illustratorでは見られない。
いちいちJavaScriptリファレンスで確認するのも大変だし、どうするかなーと思ってた。

JavaScript の配列と連想配列の違い - IT戦記
配列は素直に for
連想配列には for in

あ、そうか。JavaScriptのオブジェクトは全て連想配列だから…
第一章 JavaScriptにおけるオブジェクトの基本的性質を知る
var obj=app.activeDocument.selection[0];

for (var i in obj) {
$.write(i+":");
try{
$.writeln(obj[i])
}catch(e){
$.writeln(e.toString())
}
};

やっぱりJavaScriptはきちんと勉強しないとだめだね。

091216追記:ワンライナー、変数がかぶってるところにも使えるようにfunctionに。
var o=app.activeDocument.selection[0];
(function(o){for(var i in o){try{i+=':'+o[i]}catch(e){i+=':'+e}$.writeln(i)}})(o);

2008年12月12日金曜日

Antenna House Formatter の説明会に行ってきました

表題の通り、名古屋駅前で開催されたアンテナハウス主催「CSSによる文書レイアウト指定セミナー」へ行ってきました。

小さな会議室で、集まったのは自分を含め10人。これは多いのか、少ないのか。
名古屋という土地柄から見れば多いのかも……。
内容は、アンテナハウスのXSL-Formatterの新バージョン「Antenna House Formatter v5」の紹介と、CSSによる組版の説明。あとWord2DITAという、WORDでDITAを作成するためのプラグイン製品の紹介。

AH Formatter、なかなか印象的でした。

まず料金体系。今回、フル機能版に加えてLite版を用意して、用途に会わせて6製品にわけ、Lite版の方はかなり戦略的な価格に設定してきました。
手元にある説明会資料によると、単機能のLiteでスタンドアロンならば4万。
ニュースリリース参照。
ちょっと奮発すれば個人でも買ってみようかと思える値段。
ただし、Lite版は1文書300ページ以内とか、PDF/XやPDF/A出力機能がない等の制限あり。もっともAcrobatを持っていれば、標準の書き出しを使う必要はないでしょう。

それで、今回の一番の目玉、CSS組版。
セミナー自体は淡々と進みましたが、これはちょっと衝撃でした。

アンテナハウスのサイトで配布しているHTML+CSSのサンプルを、そのままFirefoxで開けてみると、CSS3やAH拡張部分以外は普通に見れてしまうんです。HTMLだから当然ですが。
これをAH Formatterに通すと、きちんとページ組みされて出てくる。CSSをきちんと作ってさえいれば、もう自動組みする必要さえない。完全なワンソース。
あれ?でもそうなると、普通のブラウザが全てCSS3に対応するようになったらどうなるんだろう…。

アンテナの司会の方がぽろっと一言。
「まあ、今はFormatterが他の3、4年先を行っているだけで、3年ぐらいたつとブラウザに追いつかれるかもしれないんですよ〜…」

そう、CSS3は標準化される予定のフォーマットなわけで、そうなれば当然ブラウザに搭載されるわけです。そうなればblogもwikiも最初からページ組を意識して作られるようになります。WEBで見た物が、何も手を加えることなく、そのまま、普通に、タダで組版されて出てくる時代が近いうちに来る。長文組版、大学の紀要やマニュアルなんかのDTPの仕事は確実になくなりそう。
だからこそアンテナハウスは真っ先にCSS組版を作ったのだろうし、これから先はブラウザに比べてどう付加価値をつけるか、日本語組版や多国語をどこまできれいに出力できるかで勝負するつもりなのだろうと思います。
自分らの仕事は、CSS3を駆使していかに上手く組版するかがポイントになるでしょう。機能が多い分使いがいはありそうですが、そうなるとWEB系の人らとガチ勝負になるなー。

セミナーで出た話だと、W3Cの慣例だと実装が2つ揃ったところで勧告になるそうで、たぶんCSS3勧告は2011年頃までかかるだろうとの事。でも3年なんてすぐですもんね。組版の未来を占う上でも、AH Formatterは注目です。

他に出た話。
  • 現状ではCSS組版はFO組版よりだいぶ遅い。分厚いマニュアルや高度なサーバ処理にはFOを進めるとの事。
  • CSS,FOを混在させて組版することはできない。
  • AHの独自拡張部分は、他の仕様と区別するためベンダープレフィックスをつけて欲しい(なしでも出るらしい)。
  • サイズプロパティに入れられるB5,B4の指定はISOの標準なので、日本のB4,B5版はJIS-B4,JIS-B5と入れる。AH独自仕様。
  • スタンドアロン版にはJAVAインターフェイス等の開発環境は含まれない(以前同様)。
  • FOとCSSの機能の差については、体験版をダウンロードした中にあるオンラインマニュアルに対応表がある。

あと、Word2DITAについて。
Darwin Information Typing Architecture - Wikipedia
DITAは技術情報を配布するために策定されたXML仕様。DITAで検索するとアンテナハウス関連のページばかりかかるので、アンテナハウスが押している仕様なのはわかります。
Word2DITAはそれをWORDを使って簡単に作成できるというもの。ウィザード形式に画面の進めていくとテンプレートが生成されて、その内容を埋めることでDITAを書き出せる。再利用性を考えた仕様なので、トピックごとの小さなXMLになり、最終的にマップに取り込んで一つの文書になるらしいです。

なんというか、Wordで作成できる以前に、なぜDITAが便利なのかの理解が進みませんでした。
必要を感じなければ誰も興味を持たないわけで、たぶん流行らないだろうなぁ。。。

2008年12月4日木曜日

GroovyからJPEG画像をRGB→CMYK変換

imageio を使った jpeg の rgb, cmyk 相互変換 - 夜の Discovery
Java Programming [Archive] - HELP!!! URGENT!!!! convert a jpg CMYK to jpg RGB
上記ページのJava→Groovy翻訳に挑戦。自分の力ではこれ以上コード削れなかった…。

import java.awt.image.*;
import java.awt.color.*;
import java.awt.event.*;
import java.awt.*;
import com.sun.image.codec.jpeg.*;

String USAGE = "groovy CMYKSave <cmykProfile> <rgbJPEGFile> <cmykJPEGFile> <invert=yes|no>"

//引数が4つ未満ならUSAGEを表示して終了
if(args.length<4){
println(USAGE)
System.exit(0)
}

//引数それぞれの割当て
String cmykProfile = args[0]
String rgbJPEGFile = args[1]
String cmykJPEGFile = args[2]
boolean invert = "true".equalsIgnoreCase(args[3])

//元イメージを読み込む
def decoder = JPEGCodec.createJPEGDecoder(new FileInputStream(rgbJPEGFile))
def rgbImage = decoder.decodeAsBufferedImage();

//CMYKプロファイルからCMYKカラースペースを作成
def p = ICC_Profile.getInstance(new FileInputStream(cmykProfile))
def cmykCS = new ICC_ColorSpace(p);

def out = new FileOutputStream(cmykJPEGFile)

//RGBイメージからCMYKへのコンバート
def rgbCS = rgbImage.getColorModel().getColorSpace()
def rgbToCmyk = new ColorConvertOp(rgbCS, cmykCS, null)

//変換先CMYKイメージのカラーモデル作成
def cmykModel = new ComponentColorModel(cmykCS,[8, 8, 8, 8] as int[],
false, true, Transparency.OPAQUE, DataBuffer.TYPE_BYTE)
def cmykRaster =
cmykModel.createCompatibleWritableRaster(rgbImage.getWidth(),rgbImage.getHeight())

//ここでCMYKにコンバートする
rgbToCmyk.filter(rgbImage.getRaster(), cmykRaster)

//trueなら階調反転
if(invert){
println("CMYKの階調を反転します")
def swap = new byte[256]
for(i in 0..<swap.length){
swap[i] = (byte)(255-i)
}
def lookup = new ByteLookupTable(0, [swap, swap, swap, swap] as byte[][] )
def luop = new LookupOp(lookup, null)
cmykRaster = luop.filter(cmykRaster, cmykRaster.createCompatibleWritableRaster())
}

//最後にCMYK画像を保存する
def encoder = JPEGCodec.createJPEGEncoder(out)
def param = encoder.getDefaultJPEGEncodeParam(cmykRaster, JPEGDecodeParam.COLOR_ID_CMYK)
param.setQuality(1, false)
encoder.encode(cmykRaster, param)
out.close()
println("イメージ${cmykJPEGFile}を保存しました。")

動作確認は
$ groovy CMYKSave.groovy JapanColor2001Coated.icc test.jpg test_out.jpg true

って感じです。

2008年11月24日月曜日

CotEditorで不可視ファイルを表示する


AYNiMac : 自作ソフト : CotEditor
Mac用テキストエディタ。
UTF-8もSJISも表示できて、正規表現もしっかり実装していて、しかもフリー。
今いちばん充実してるんじゃないだろうか。

で、ちょっとしたTipsのメモ。
.bash_profileとかの不過視ファイルを編集したいとき(それぐらいターミナルでやれって言われそうだけど)、CotEditorではファイルメニューの「開く」では普通には表示されない。
でも、Shiftキーを押しながらファイルメニューを開くと、「非表示ファイルを開く」が現れる。そこから選択すればよい。

2008年11月23日日曜日

Groovyでテキスト処理を試す

組版・DTP関連でプログラムを使ったテキスト処理をするなら、普通はsed、perl、rubyなんかを使うと思う。でもここはあえてgroovyでやってみる。

まずテキストを用意。青空文庫から「我輩は猫である」のテキスト版を引っ張ってきて、それの一部を使うことにする。
 吾輩《わがはい》は猫である。名前はまだ無い。
 どこで生れたかとんと見当《けんとう》がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番|獰悪《どうあく》な種族であったそうだ。この書生というのは時々我々を捕《つかま》えて煮《に》て食うという話である。しかしその当時は何という考もなかったから別段恐しいとも思わなかった。ただ彼の掌《てのひら》に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始《みはじめ》であろう。この時妙なものだと思った感じが今でも残っている。第一毛をもって装飾されべきはずの顔がつるつるしてまるで薬缶《やかん》だ。その後《ご》猫にもだいぶ逢《あ》ったがこんな片輪《かたわ》には一度も出会《でく》わした事がない。のみならず顔の真中があまりに突起している。そうしてその穴の中から時々ぷうぷうと煙《けむり》を吹く。どうも咽《む》せぽくて実に弱った。これが人間の飲む煙草《たばこ》というものである事はようやくこの頃知った。

この文章を"waganeko.txt"としてSJISで保存。とりあえずデスクトップに置く。
それに対して、
  • ルビにxhtml風のタグをつける。
  • 行ごとに<p></p>タグをつける。
  • 語尾が"んぬ。"で終わるようにする。
  • SJISのテキストをUTF8にする。
  • .htmlをつけて保存。
ここまでやってみる。
以下Groovyコード。
def inputCharCode = "SJIS" //入力側文字コード
def outputCharCode = "UTF8" //出力側文字コード

//変換マップ※なぜか行頭にスペースがないとエラーになる?
def replaceTable=[
/^/:"<p>",
/$/:"</p>",
/\n/:"</p><p>",
/|{0,1}([一-龠]+?)《([ぁ-ん]+?)》/:
{ m0, m1, m2 -> "<ruby><rb>$m1</rb><rt>$m2</rt></ruby>" },
"。":"んぬ。"
]

//--------------------処理ここから--------------------
if(args.length < 1){
println("ファイルを指定して下さい。")

}else{
//argsが1個以上なら数を数えてループ
for(i in 0..< args.length){

//ファイルの中身を読む
def file = new File(args[i])
String str = file.getText(inputCharCode)

//変換マップの中を順に置換する
replaceTable.each{key,value -> str=str.replaceAll(key,value)}

//同じ名前の.htmlを作って書き込み
String newPath = args[i].replace(".txt",".html")
def dir = new File(newPath)
dir.write(str,outputCharCode)
println("-------------${newPath}を書き出しました。")
}
}

これをテキストエディタに貼付け、"aozora.groovy"って名前をつけて保存。とりあえずデスクトップに置く。
ターミナルを立ち上げ、
$ cd Desktop/
$ groovy aozora.groovy waganeko.txt
---------------waganeko.htmlを書き出しました。

とすれば、waganeko.htmlが書き出される。

確認のために、XHTMLルビサポートというFirefox用アドオンがあるので、それをインストールしてFirefoxで開いてみよう。

Pタグ以下しかないんで、完璧なhtmlになってはいないけれど、そのへんはテストってことで。

変換を変えたいのなら、変換マップの中身を書き換えればいいだけ。
簡単だ!

2008年11月22日土曜日

正規表現、先読みと後読み

正規表現でテキスト処理をする際、いちばん分かりにくくて、いちばん役に立ったのが先読み後読み。どうもここが正規表現のキモのような気がする。
そういうわけでメモ。

Groovyの場合、肯定的先読みは(?=pattern)、肯定的後読みは(?<=pattern)と書く。
patternの部分は判別させたい文字列。

先読み、後読みは何に使うのかというと、「文字列の前と後にどんな文字が来るか判別したくて、なおかつその部分にはマッチさせたくない」という場合に使う。
たとえば、「hoge(?=pattern)」は patternが後ろにあるhogeにマッチするが、(?=pattern)部分にはマッチしない。
「(?<=pattern)hoge」は patternが前にあるhogeにマッチするが、(?<=pattern)部分にはマッチしない。

マッチしたい文字の前に後読み、後ろに先読みを使うのがミソ。
順番でいうと(後読み)(欲しい部分)(先読み)と使う。
ここまでOK?

実例。下のような文章があったとする。
長嶋 茂雄の誕生日は1936年2月20日。
1974(昭和11)年2月20日から
2008(平成20)年11月20日の間の日数は26,572日、
72年と274日になります。ところで、ただいまの時間は7:19です。

「ところで」の部分が苦しい…のは置いといて、
このテキストの「1桁と2桁の数字だけ<tcy></tcy>というタグで囲みたい」
どうしよう?

まず、1桁と2桁の数字だから、
\d{1,2}

だけど、これだと3桁以上の数字にもマッチしてしまうので、前後に数字がない場合だけマッチさせたい。
(?<=[^\d])(\d{1,2})(?=[^\d])

また、コンマ区切りと小数点、時間を表しているコロンがあった場合もマッチさせたくない。
(?<=[^\d\.,:])(\d{1,2})(?=[^\d\.,:])

この文章にはないけれど、行頭もしくは行末に数字が来るかもしれない。
(?<=^|[^\d\.,:])(\d{1,2})(?=[^\d\.,:]|$)


これで、数字2桁までの「数字部分にだけ」マッチする。
以下Groovyスクリプト。
def text="""長嶋 茂雄の誕生日は1936年2月20日。
1974(昭和11)年2月20日から
2008(平成20)年11月20日の間の日数は26,572日、
72年と274日になります。ところで、ただいまの時間は7:19です。"""

//半角1,2桁の数字にタテ中ヨコ用タグ付け
text=text.replaceAll(/(?<=^|[^\d\.,:])(\d{1,2})(?=[^\d\.,:]|$)/) {
m0, m1 -> "<tcy>${m1}</tcy>"
}
println(text)



ところで、JavaScriptも正規表現を使えるけれど、後読みをサポートしていない
仕方がないので、後読み部分を普通にマッチさせる。後読み部分も1字なので不具合は出ないと思う。
以下ExtendScript。
var text="長嶋 茂雄の誕生日は1936年2月20日。\n"
+"1974(昭和11)年2月20日から\n"
+"2008(平成20)年11月20日の間の日数は26,572日、\n"
+"72年と274日になります。ところで、ただいまの時間は7:19です。"
//半角1,2桁の数字にタテ中ヨコ用タグ付け
text=text.replace(/(^|[^\d\.,:])(\d{1,2})(?=[^\d\.,:]|$)/g,"$1"+"<tcy>"+"$2"+"</tcy>");
$.writeln(text);

2008年11月19日水曜日

Illustartor→InDesign間でBridgeTalk

IllustratorのvisibleBoundsとgeometricBoundsが、yが上に向かって増える仕様なのでInDesignと合わない。むかついたので、腹いせにBoundsをInDesign風に置き換えるfunctionを書いた。
#target "Illustrator"

forIndBounds=function(bounds){
var h=app.activeDocument.height;
var ary=[h-bounds[1],bounds[0],h-bounds[3],bounds[2]];
return ary;
};

//AIの場合は単位を設定しても常にポイントでくる
var selObj = app.activeDocument.selection;
for(var i=0;i<selObj.length;i++){
var aivb=selObj[i].visibleBounds;
var aigb=selObj[i].geometricBounds;
};

ただ、これだけではInDesignに流用は全くできない。
せっかくならアプリ間連携してInDesignで直接テキストフレーム生成できるといいよね?
そういうわけで余計な苦労をはじめるのだ。

とりあえず拾ったgeometricBoundsを全部Arrayにつっこむ。
そしてInDesignに渡す方法を考える。
illustrator13.executeScriptの正体 - なにする?DTP WEB
↑ここの記事で、AdobeCS間で通信するメソッドがあるのを知った。
indesign5.executeScript("alert(\"こんにちはInDesign\")");

だけども、scriptがレアなままでは渡せない、一度Stringになっている必要がある。
変数はどうやって渡すの?
同じブログの記事で、executeScriptの正体はBridgeTalkだと知る。
BridgeTalkって何? - なにする?DTP WEB
BridgeTalk!!

それを使って、functionと変数をなんとか渡そうとしてるうちに、それもfunctionになった。
とりあえず、InD側の単位は全部ポイントに合わせ、線幅や色も決めうち。
あっはっは!

2008年11月16日日曜日

AdobeCS3のJavaScriptでガベージコレクション

$.gc () 

これだけ。
WIKIPEDIA: ガベージコレクション
ガベージコレクションというのは、いらなくなったメモリを解放する処理で、ようするにメモリ関連のエラーに効果があるらしいんだけど、実際の所どれほど効果があるものなのかよくわからない。

今自分の会社でお客さんに渡しているスクリプトが
「使用するとだんだんInDesignが重くなる」
と言われていたので、これを処理の末尾にそっと挿入。
おまじない。

不具合が解消されたかはまだ不明。こんど聞いてみないとな…。

2008年10月26日日曜日

MacでXindiceを使う 2

続いて、Xindiceを使ってみる。
@ITの記事は古いのか、そのままでは試せなかった。
theylive.jp:XMLデータベース 「Xindice」にチャレンジ
↑ここの記事がすごく参考になった。
$ xindice add_collection -c /db -n sampledb
trying to register database
Created : /db/sampledb

$ xindice lc -c /db
trying to register database

sampledb
system
meta

Total collections: 3

$ xindice ad -c /db/sampledb -f problem1.xml -n prob1
trying to register database
Added document /db/sampledb/prob1

$ xindice ad -c /db/sampledb -f problem2.xml -n prob2
trying to register database
Added document /db/sampledb/prob2

$ xindice xpath -c /db/sampledb -q "/problem[@status='open']"
trying to register database
<problem date="2001-12-28" id="ID0002" src:col="/db/sampledb" src:key="prob2"
status="open" title="core dump" xmlns:src="http://xml.apache.org/xindice/Query">
<description>
サーバがコア・ダンプする。
</description>
<actions>
<action who="A_company">
<description>
開発元に問合せ。
</description>
</action>
<action who="C_customer">
<description>
情報収集
</description>
</action>
</actions>
</problem>

$ xindice xpath -c /db/sampledb -q "/problem//action[@who='B_corporation']"
trying to register database
<action src:col="/db/sampledb" src:key="prob1" who="B_corporation"
xmlns:src="http://xml.apache.org/xindice/Query">
<description>
レスポンスセンターに問い合わせる。
</description>
</action>

MacでXindiceを使う

Xindice(じんでぃーちぇ)はjavaで書かれたXMLデータベース。

@IT:Xindice:無料で使えるXMLデータベース(1) ネイティブXMLデータベースを立ち上げる!

↑ここの記事を参考に、MacでXindiceの起動に挑戦してみる。

まず、Xindiceのダウンロードページからバイナリファイルをダウンロードする。
今回ダウンロードしたのは、xml-xindice-1.2m1-bin.tar.gz
新しい方が良いと思って。

解凍して、いつもこの手のファイルを入れている/optディレクトリにコピー。
フォルダ名をxindiceにする。
Javaはインストール済。
パスを通す。~/.bash_profile に以下を記述。
export XINDICE_HOME=/opt/xindice
export PATH=$XINDICE_HOME/bin:$PATH


iTermを立ち上げ、起動を試す。
$ cd /opt/xindice
$ ./start
-bash: ./start: No such file or directory

動かない…そもそも/opt/xindiceディレクトリの中にstartってファイルないし。
いろいろ検索するが情報なし。
よく見ると、ディレクトリ直下にxindicedってファイルがある。
これシェルスクリプトだよな…
$ ./xindiced
Xindice Server Startup Script
Usage:
./xindiced
Actions:
start Start Xindice server
stop Stop Xindice server
debug Start Xindice server with remote debugging on

おっ
$ ./xindiced start

Starting Xindice. Log files are under /opt/xindice/logs

Xindice is running with PID 27403

当たり!v1.2だと、startとstopはxindicedにまとまってるのか。

簡単に書いてるけどこれに気づくまで数時間…
あとはたぶん、上の記事通りやれば動くと思うので、今日はここまで。

2008年10月20日月曜日

Macでxalanを使う

勝手にしやがれ:Macintosh(Panther)でXSLTを扱う
↑この記事を参考に、Macにもともと入っているXalanを使ってみる。
環境はMacOS X 10.4.11。

java version "1.5.0_16"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b06-275)
Java HotSpot(TM) Client VM (build 1.5.0_16-132, mixed mode, sharing)

まず、ターミナルの表示をSJISにする。
自分の使ってるiTermは最初からSJIS設定なのでOK。
$ java org.apache.xalan.xslt.Process

と打つと、マニュアルがずらずらと出てくる。
出てくるからそのまま使えると思い、
サンプルのtest.xslとtest.xmlを用意して
$ java org.apache.xalan.xslt.Process -xsl test.xsl -in test.xml -out test.txt

と打つとtest.txtができた。OK。

次に、.bash_profileにエイリアスを書く。
alias xalan='java org.apache.xalan.xslt.Process'

と追加して、
$ xalan -xsl test.xsl -in test.xml -out test.txt

で動いた。OK。

2008年10月14日火曜日

functionをreturnするfunction、それがクロージャ

ちょっとブレイクスルーがあったのでメモ。
JavaScriptでのクロージャの話。

Greeting = function(aisatsu){
 return function(name){
  alert (aisatsu + "、" + name + "さん!");
  return;
 }
}

morning = new Greeting("おはよう");
morning("佐藤");


クロージャは関数を返す関数なのだ。
上の例だとGreetingに"おはよう"を渡す事で、
中のfunctionは
function(name){
 alert ("おはよう" + "、" + name + "さん!");
 return;
};

になって、それをmorningに代入してるというわけか。
ようやく理解できた。なるほど!

2008年10月12日日曜日

やさしいJavaとGroovy

Groovyの勉強をはじめたが、Groovyの本や解説サイトには「まずGroovyとJavaとの違いから」「Javaの基本的知識はあるものとして説明」という言葉だらけになっている。
自分はJava素人なので、まずJavaから勉強することにした。

用意した本は、会社にあった「やさしいJava 第3版」、「Groovyイン・アクション」の2冊。
まず、やさしいJavaのサポートページから、サンプルコードをダウンロードする。

やさしいJavaのサンプルコードを開けてみると、文字コードがShift-JISになっている。
会社で支給されているテキストエディタはTextMate。日本語化してもUTF-8しか表示できない。
なので、全部UTF-8に変換する。
Mac用でテキストエンコードの一括変換できるソフトで、MultiTextConverterというのがあったのでそれを使用。

なんかエラーが出て、全部を変換できない……。
しょうがないので1フォルダづつ変換して、上手くいかないものはJedit Xで開いて別名保存。

無事全てをUTF-8にできたので、iTermを立ち上げ、サンプルコードのディレクトリへ行く。
自分はルート以下に/work/projects/ディレクトリを作って入れている。

$ cd /work/projects/YJSample/
$ mate .



TextMateが立ち上がって、メニュー表示される。OK。

次、Javaの設定。
JavaはMacに標準でインストールされるので、「パスを通す」。この言葉は始めの頃ずいぶん悩んだけど、要はシェルで使えるようにする事なんだと気づいて納得した。

ホームディレクトリにある.bash_profileに以下を記述する。

export JAVA_HOME=/Library/Java/Home
export PATH=$JAVA_HOME/bin:$PATH


iTermから

$ java -version
java version "1.5.0_16"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b06-275)
Java HotSpot(TM) Client VM (build 1.5.0_16-132, mixed mode, sharing)


これでOK。

次、Groovyのインストールと設定。
groovyのdownloadページから最新のgroovyをダウンロードしてきて展開。
こういうのは/opt/ディレクトリを作って入れているので、そこに入れる。
パスを通す。.bash_profileに以下を記述。

export GROOVY_HOME=/opt/groovy-1.5.6
export PATH=$GROOVY_HOME/bin:$PATH


iTermから

$ groovy -version
Groovy Version: 1.5.6 JVM: 1.5.0_16-132


OK。

javacをやってみる。

$ cd /work/projects/YJSample/01
$ javac Sample1.java
Sample1.java:5: #x##:###̕####́A#G###R#[#f#B###O SJIS #Ƀ}#b#v#ł##܂######
System.out.println("ようこそJavaへ?#?");
^
Sample1.java:5: #x##:###̕####́A#G###R#[#f#B###O SJIS #Ƀ}#b#v#ł##܂######
System.out.println("ようこそJavaへ?#?");
^
#x## 2 ###
$ java Sample1
ようこそJavaへ?#?


なんか文字が化ける。。。iTermの表示はちゃんとUTF-8にしてある。

たくさんぐぐって調べると、どうもjavacはエンコーディングを明示しないとOSのデフォルト・エンコーディングで変換する様子。MacはSJISになっていて、OSのデフォルトは変更できないっぽい。
ここに書いてある方法をもとに、エンコードを指定してやってみる。

$ javac -encoding UTF-8 Sample1.java
$ java -Dfile.encoding=UTF-8 Sample1

ようこそJavaへ!

次はgroovycを試す。
試しにSample1g.groovyを書いて、以下のようにする。

println "ようこそGroovyへ!"


これをgroovycしてみる。

$ groovyc Sample1g.groovy
$ java -cp $GROOVY_HOME/embeddable/groovy-all-1.5.6.jar: Sample1g
ようこそGroovyへ?#?


javacの時と同じことが起こっているので、encodingを指定する。

$ groovyc --encoding UTF-8 Sample1g.groovy
$ java -Dfile.encoding=UTF8 -cp $GROOVY_HOME/embeddable/groovy-all-1.5.6.jar: Sample1g
ようこそGroovyへ!


毎回javacとgroovycのときに同じ事を書くのはめんどいので、.bash_profileにエイリアスを書く。

alias javac="javac -encoding UTF-8"
alias groovyc="groovyc --encoding UTF-8"
alias java="java -Dfile.encoding=UTF8 -cp $GROOVY_HOME/embeddable/groovy-all-1.5.6.jar:"


これで、JavaとGroovyを完全に同じに扱えるようになった。※追記2で変更↓

追記:
ひとつ問題発見。コンパイルじゃなく.groovyをそのまま走らせようとすると、

$ groovy Sample1g.groovy
ようこそGroovyへ?#?


という風に化ける。ああ、こっちもUTF指定しなきゃだめかと思い、

$ groovy -c UTF8 Sample1g.groovy
#悤####Groovy#ցI


はいい?もしやと思いiTermの表示をS-JISにしてみると

$ groovy -c UTF8 Sample1g.groovy
ようこそGroovyへ!


groovyコマンドは内部でコンパイルしてるわけだから、groovyc→javaってやってるわけで、→javaのときにエンコード指定を拾ってない???

追記2:
そもそも、Javaの思想に「一度書いたらどこでも動く」てのがあるわけで、各プラットフォームがそれぞれ別のデフォルトエンコーディングを持っていたら、そのエンコーディングに合わせて動かなくちゃいけない。そのためにJavaの内部的には文字コードは全てUnicodeで持っていて、各プラットフォームごとに合わせているらしい。

それを考えると、groovyコマンドがコンパイル時にだけエンコードを指定できて、中身のJavaバイトコードはUnicodeで持ち、出力はデフォルトプラットフォームに合わせる、って動きなのも合ってるような気がしてきた。

なので、iTermの画面はShift-JIS表示にして、Javaコマンドのエイリアスからは-Dfile.encoding=UTF8の指示は取る。残った.bash_profileのエイリアスは

alias javac="javac -encoding UTF-8"
alias groovyc="groovyc --encoding UTF-8"
alias java="java -cp $GROOVY_HOME/embeddable/groovy-all-1.5.7.jar:"
alias groovy="groovy -c UTF-8"


この状態で運用することに決定。
疲れた……。

追記3:2008年11月23日
さらに追記。
MacOSX 10.5で、この条件で動かしたら文字が化ける!
Mac OS 10.5で、論理工房のJava関連4Dプラグイン
Apple社のJavaバーチャルマシンでは、Mac OS 8〜10.4まで、デフォルトの文字エンコーディングとして「Shift_JIS」が採用されていましたが、Mac OS 10.5では、「UTF-8」が採用されています。

おぉ…。

そういうわけで、
・プログラムのエンコードをUTF8に統一するには、上記のエイリアスを記述する
・ターミナルコンソールは、10.4以前はShift-JIS、10.5以降はUTF8表示にする
で、こんどこそOKです。あしからず。

追記4:2010年5月11日
Java6からは、デフォルトエンコーディングがShift-JISに戻ってるみたいです。
Appleの意図がわからない……。
Groovyのエンコード設定については、@uehajさんが以下のページで詳しく書いてくれています。
groovyでスクリプトのエンコーディングを指定する - Grな日々(uehajの日記)
結論としては、/bin/startGroovy(.bat) に
export JAVA_OPTS='-Dgroovy.source.encoding=UTF-8 -Dfile.encoding=UTF-8'

の1行を書き加えるのがいいようです。

2008年9月3日水曜日

OS固有のパス表記は使いたくない時

InDesignって、
filename = "~/Desktop/sampleFile.indd";
app.open(filename);
と書いてもファイルを開けないんです。開くには、
filename = "Macintosh HD:Users:kanemu:Desktop:sampleFile.indd";
app.open(filename);
みたいに、OS固有表記で書かなきゃいけない。
これではスクリプトをMac,WIN共有で使いたい時、よろしくない。
ではどうするか?
filename = "~/Desktop/sampleFile.indd";
app.open(File(filename));

これでOK。File()でくくって、Fileオブジェクトにして渡してやればいい。

もっと早く気づいていれば…orz

グループをさかのぼれ

追記20090218:
この記事のスクリプトには間違いがありました!
正しいスクリプトは、別エントリ「pageItemsとallPageItems」に書きましたので、そちらをご確認下さいm(_ _)m

#target "InDesign"
selObjs=app.activeDocument.selection;
//↓toolkitのJavaScriptコンソールに表示するよ
$.writeln ("------Groupを1コとするなら------"+selObjs.length);

var count=0;
groupRoop=function(objs){
for(var i=0;i<objs.length;i++){
var obj=objs[i];
if(obj.constructor.name=="Group"){
var groupObjs=obj.allPageItems;
//↓groupRoop(groupObjs);でいいけど一応
arguments.callee(groupObjs);
}else{
//↓ここの処理を書き換えれば、処理が変わる!
count++;
}
}
return count;
}

groupRoop(selObjs);
$.writeln ("------Groupの中を数えるなら------"+count);

某所の選択したアイテムを数えるスクリプトのInDesign版。
selObjs[i]がグループだった場合は再帰してその中をループし、
そうでなかった場合はcountに1を足す。

これ、elseにcount++じゃなくて他の処理を入れれば、
グループの中全てに処理をかけるスクリプトができる。たとえば、
#target "InDesign"
selObjs=app.activeDocument.selection;

groupRoop=function(objs){
for(var i=0;i<objs.length;i++){
var obj=objs[i];
if(obj.constructor.name=="Group"){
var groupObjs=obj.allPageItems;
arguments.callee(groupObjs);
}else{
if(obj.constructor.name=="TextFrame"){
obj.parentStory.contents="ほげ";
}
}
}
return;
}

groupRoop(selObjs);

これで選択したテキストフレームの中身がぜんぶ「ほげ」になる。

2008年4月6日日曜日

ExtendScriptでJSON

ExtendScriptはECMA準拠のJavaScriptなので、json2.jsがそのまま使えます。
そういうわけで実験。

ここからjson2.jsを落としてきて、スクリプトと同階層に保存する。
#include "json2.js"

var myObject=[
{x:8, y:8,fileName:"a.eps"},
{x:8, y:16,fileName:"b.eps"},
{x:8, y:24,fileName:"c.eps"},
{x:8, y:16,fileName:""}
];

alert(myObject.toSource());

var myJson = JSON.stringify(myObject);
alert(myJson);

var myJsonParse = JSON.parse(myJson);
alert(myJsonParse.toSource());


まず最初に、myObjectの中身が出る。


次に、JSON.stringifyでJSON化されたmyObjectが出る。


エンコードされちゃうけど気にしない。
それをJSON.parseで読み込む。


もとに戻る。以上。

2008年3月30日日曜日

フォルダ指定いろいろ

alert("マイドキュメント\n"+Folder.myDocuments);
alert("デスクトップ\n"+Folder.desktop);
alert("ゴミ箱\n"+Folder.trash);
alert("実行中のアプリのパッケージ\n"+Folder.appPackage);
alert("OSの種類\n"+Folder.fs);
alert("システムフォルダ\n"+Folder.system);
alert("ユーザ別アプリケーションデータの場所\n"+Folder.userData);
alert("システム用アプリケーションデータの場所\n"+Folder.appData);
alert("コモンファイルフォルダ\n"+Folder.commonFiles);
alert("テンプフォルダ\n"+Folder.temp);
alert("アプリケーションの実行イメージの場所\n"+Folder.startup);
alert("現在のフォルダ\n"+Folder.current);

ライブラリ見ながら全部やってみる。
知っておくと便利。保存先をデスクトップにしたくても、WINDOWSで動かないと困るもんね。

2008年3月20日木曜日

FizzBuzz問題.jsx

/*

FizzBuzz問題

1から100までの数をプリントするプログラムを書け。
ただし3の倍数のときは数の代わりに「Fizz」と、
5の倍数のときは「Buzz」とプリントし、
3と5両方の倍数の場合には「FizzBuzz」とプリントすること。

*/

var i
for(i=1;i<101;i++){
if(i%3==0 & i%5==0){
print("FizzBuzz");
}else if(i%3==0){
print("Fizz");
}else if(i%5==0){
print("Buzz");
}else{
print(i);
}
}

ネットで見かけたんでなんとなくやってみた。
合ってるかな、合ってるよね?
コンソール見ればちゃんとなってるし。

2008年3月15日土曜日

AdobeCS3のJavaScriptでXPathを使う

ExtendScript Toolkit 2 のライブラリを見ていると、なんか聞いた事のある言葉を見つけた。


XPath?
先日のスクリプトを流用して試してみる。
myXpath=myXml.xpath("/");
alert(myXpath);

???なんで2回言われる?
myXpath=myXml.xpath("/");
alert(myXpath[0]);

ふむ。
myXpath=myXml.xpath("/");
alert(myXpath[1]);

おっ
myXpath=myXml.xpath("/Koma/FileName");
alert(myXpath[1]);

おおっ
myXpath=myXml.xpath("/Koma/@name");
alert(myXpath[0]);

おおおっ!

2008年3月9日日曜日

AdobeCS3でJavaScriptにXMLを読み込む

AdobeCS3付属の「JavaScript Tools Guide」を読むと、
ExtendScript defines the XML object, which allows you to process XML with your JavaScript scripts. This
feature offers a subset of the functionality specified by the ECMA-357 specification (E4X).
と書いてある。

英語は苦手だけど、とにかくExtendScript内でXMLを使えるよ、と書いてあるのはわかる。
それを試してみた。

用意したXMLはこんな感じ。"test.xml"
<?xml version="1.0" encoding="UTF-8"?>
<Page>
<Koma name="コマA">
<FileName>testA.pdf</FileName>
<Xzahyou>10</Xzahyou>
<Yzahyou>10</Yzahyou>
</Koma>
<Koma name="コマB">
<FileName>testB.pdf</FileName>
<Xzahyou>20</Xzahyou>
<Yzahyou>10</Yzahyou>
</Koma>
<Koma name="コマC">
<FileName>testC.pdf</FileName>
<Xzahyou>30</Xzahyou>
<Yzahyou>10</Yzahyou>
</Koma>
</Page>

それをデスクトップに置いて、スクリプト。
var openFile=new File("~/Desktop/test.xml");
openFile.open ("r");
src=openFile.read();
myXml = new XML(src);

ここまででXMLファイルを読み込み、XMLを定義する。
alert(myXml);
するとこうなる。


要素を呼び出してみる。
alert(myXml.Koma[1].FileName[0]);
alert(myXml.Koma[0].@name);



すばらしい!

一応CS2でも試してみたが、やっぱり使えなかった。まあしょうがないか。

2008年3月8日土曜日

自分のブログをぐぐってみて

なんとなく、自分のブログタイトルをぐぐってみたら、
「カネムーメモ に一致する情報は見つかりませんでした。」
と出た……。

別にBlogger使ってるからって、自動でGoogleが拾ってくれるわけじゃないんだね。
どこからのリンクもなければそのページは存在しない。さすがグーグル。

アーカイブ残してもぐぐれなきゃ誰の役にもたたない、こりゃやばいってんで、自分のはてなブックマークに登録してみた。
これで拾ってくれるかな。

−−−追記−−−
翌朝9時、ちゃんと拾ってくれました。
さすがグーグル。

Adobe製品で外部JavaScriptをインクルードする

OpenSpaceさんとこの
■別ファイルに書かれたスクプトをリンクする
を実験してみる。

まず読み込まれる方、"shisyagonyu.jsx"
function shousu1(p){
var myVal=Math.round(p*10);
myVal=myVal/10;
return myVal
}

function shousu2(p){
var myVal=Math.round(p*100);
myVal=myVal/100;
return myVal
}

function shousu3(p){
var myVal=Math.round(p*1000);
myVal=myVal/1000;
return myVal
}

それで読み込む方、"ensyu.jsx"
//@include "shisyagonyu.jsx";

var enshu=3.141592653589793238462643383279502884;
alert(shousu2(enshu));

で、出た結果がこれ。

うん、よし。

外部スクリプトを読み込んで利用できるってことは、Ajaxでいうprototype.jsみたいに、Adobe製品でも使いやすいライブラリを作成して公開できるってこと。

InDesignはどうしてもユーザが限られちゃうけど、PhotoshopやIllustratorでやればかなり需要ありそうじゃないかい?

2008.04.05追記。
AdobeCS3のExtendScriptだと、この書き方は奨励しないみたい。正しくは、
#include "shisyagonyu.jsx"
と書くのだそうです。

2008年2月24日日曜日

新規カラースウォッチ作成

app.activeDocument.colors.add ({name:"新規",colorValue:[20,0,0,0]});

「スウォッチを新規作成」だと思ってSwatchのメソッドを探してると深みにハマります。
カラーを新規作成する。

ほらね。

2008年2月20日水曜日

選択したオブジェクトのプロパティをテキスト保存

たまたま書けたスクリプト。これは使えるかも……
selObj = app.activeDocument.selection;
for (i=0; i<selObj.length; i++)
{
var pTextName="propaties"+"_"+(selObj.length-i);
var fileObj = new File("/"+pTextName+".txt");
var flag = fileObj.open("w");
if (flag){
fileObj.write(selObj[i].properties.toSource());
}
}

適当なオブジェクト(テキストフレームとか)を選択して実行すると、HD直下に「propaties_(番号).txt」を書き出す。開けてみるとこんな感じ。
({transparencySettings:resolve("/document[@name=¥"名称未設定-1¥"]//text-frame[@id=238]/@transparency-settings"), strokeTransparencySettings:resolve("/document[@name=¥"名称未設定-1¥"]//text-frame[@id=238]/@stroke-transparency-settings"), fillTransparencySettings:resolve("/document[@name=¥"名称未設定-1¥"]//text-frame[@id=238]/@fill-transparency-settings"), contentTransparencySettings:resolve("/document[@name=¥"名称未設定-1¥"]//text-frame[@id=238]/@content-transparency-settings"), geometricBounds:[76.5, 56, 119, 118], visibleBounds:[76.5, 56, 119, 118], parentStory:resolve("/document[@name=¥"名称未設定-1¥"]//story[@id=220]"), startTextFrame:resolve("/document[@name=¥"名称未設定-1¥"]//text-frame[@id=238]"), endTextFrame:resolve("/document[@name=¥"名称未設定-1¥"]//text-frame[@id=238]"), textFrameIndex:0, overflows:false, previousTextFrame:null, nextTextFrame:null, contents:"", textFramePreferences:resolve("/document[@name=¥"名称未設定-1¥"]//text-frame[@id=238]/@text-frame-preferences"), anchoredObjectSettings:resolve("/document[@name=¥"名称未設定-1¥"]//text-frame[@id=238]/@anchored-object-settings"), baselineFrameGridOptions:resolve("/document[@name=¥"名称未設定-1¥"]//text-frame[@id=238]/@baseline-frame-grid-options"), textWrapPreferences:resolve("/document[@name=¥"名称未設定-1¥"]//text-frame[@id=238]/@text-wrap-preferences"), contentType:1952412773, gridData:resolve("/document[@name=¥"名称未設定-1¥"]//text-frame[@id=238]/@grid-data"), associatedXMLElement:null, overridden:false, overriddenMasterPageItem:null, fillColor:resolve("/document[@name=¥"名称未設定-1¥"]//swatch[@id=14]"), fillTint:-1, strokeWeight:0, miterLimit:4, endCap:1650680176, endJoin:1835691886, strokeType:resolve("/document[@name=¥"名称未設定-1¥"]/stroke-style[@id=23081]"), leftLineEnd:1852796517, rightLineEnd:1852796517, strokeColor:resolve("/document[@name=¥"名称未設定-1¥"]//swatch[@id=14]"), strokeTint:-1, cornerRadius:4.23333333333333, gradientFillStart:[87, 97.75], gradientFillLength:0, gradientFillAngle:0, gradientStrokeStart:[87, 97.75], gradientStrokeLength:0, gradientStrokeAngle:0, gapColor:resolve("/document[@name=¥"名称未設定-1¥"]//swatch[@id=14]"), gapTint:-1, strokeAlignment:1936998723, nonprinting:false, itemLayer:resolve("/document[@name=¥"名称未設定-1¥"]//layer[@id=196]"), locked:false, localDisplaySetting:1147563124, allPageItems:[], allGraphics:[], rotationAngle:0, shearAngle:0, horizontalScale:100, verticalScale:100, absoluteRotationAngle:0, absoluteShearAngle:0, absoluteHorizontalScale:100, absoluteVerticalScale:100, frameFittingOptions:resolve("/document[@name=¥"名称未設定-1¥"]//text-frame[@id=238]/@frame-fitting-options"), flip:1852796517, absoluteFlip:1852796517, cornerOption:1852796517, appliedObjectStyle:resolve("/document[@name=¥"名称未設定-1¥"]//object-style[@id=135]"), lockState:1852796517, id:238, label:"", parent:resolve("/document[@name=¥"名称未設定-1¥"]//page[@id=204]"), index:0})

ずら〜りとプロパティの値が。
これでもう手探りでプロパティを探さなくてすむよ。

2008年2月18日月曜日

AppleScriptの中にJavaScriptを書き込む

set myJavaScript to "alert(\"成功です!\");"
tell application "Adobe InDesign CS3"
activate
do script myJavaScript language javascript
end tell

これでも良かった。
ダブルクォーテーションはバックスラッシュでエスケープ。

CS3付属の「InDesign CS3 スクリプティング ガイド AS.pdf」に詳しく書いてあったよ。

2008年2月17日日曜日

ターミナル、AutomatorからAdobeアプリ用JavaScriptを呼び出す

AppleScriptはできたので、今度はそれをターミナルから呼び出してみる。

InDesign用のAppleScriptを「sample.scpt」としてHD直下に保存。
ターミナルを立ち上げ、
$ osascript "/sample.scpt"
「成功です!」

おお、動いた。
今度は直接コマンドにAppleScriptを書き込む。
$ osascript -e 'tell application "Adobe InDesign CS3"'
-e 'activate' -e 'do script file "MacHD:sample.jsx" language javascript' -e 'end tell'
「成功です!」

OK。次。
Automatorには、「AppleScriptを実行」って項目があるので、そこに書き込んでみる。


「成功です!」
できた。これでいろいろできそう。

AppleScriptからAdobeアプリ用JavaScriptを呼び出す

OpenSpaceさんとこにあった
AppleScriptを使ってJavaScriptファイルを実行する
をCS3でやろうとしていた。

とりあえず、sample.jsxに
alert("成功です!");
とだけ書いてホーム直下に保存し、スクリプトエディタを立ち上げる。
tell application "Adobe Photoshop CS3"
activate
do javascript file "~/sample.jsx"
end tell
「成功です!」
tell application "Adobe Illustrator CS3"
activate
do javascript file "~/sample.jsx"
end tell
「成功です!」
tell application "Adobe InDesign CS3"
activate
do script file "~/sample.jsx" language javascript
end tell
「Adobe InDesign CS3 でエラーが起きました:構文エラー」
あれ?なぜ動かん。

いろいろ考えたあげく(2時間ぐらい)、例文通りにHD直下にsample.jsxを置いて、
tell application "Adobe InDesign CS3"
activate
do script file "MacHD:sample.jsx" language javascript
end tell
「成功です!」

……UNIX表記のパスを読み込んでくれないのかInDesign。
なんだかなぁ。

20100315追記:
tell application "Adobe InDesign CS3"
activate
do script "/Users/kanemu/Desktop/sample.jsx" as POSIX file language javascript
end tell
でいけるみたいです。
フルパスじゃないと通らないけれど…

2008年2月15日金曜日

小数点3桁以下を四捨五入

どうやっていいかわからなくてさんざん悩んで、わかってしまえばすごく簡単だったという事がある。

InDesignのJavaScriptであちこちの数値を取っていたのだが、きちんと整数になっていることは少なくて、小数点以下がだーーーっと並んでしまう。なので小数点3桁以下を四捨五入しようと考えた。
ところが、四捨五入する命令は「小数点以下を四捨五入」するroundしかない。
じゃあどうすればいいの?整数と少数部分に分けて、少数は3桁以降は切り捨てて、それを四捨五入?その方法は?
……その事で数時間ムダにしたのだけれど、出た結論はこんなふうだった。
function shousu2(p){
var myVal=Math.round(p*100);
myVal=myVal/100;
return myVal
}

var mathObj=132.6759258803;
shousuIka2Obj=shousu2(mathObj);
alert(shousuIka2Obj);

なんのことはない、数値に100かけて四捨五入した後、100で割ればいいだけ。
簡単じゃん!そりゃあroundしかいらないわけだ。プログラマーの人というのはこういう事をちゃんと知ってるんだな、きっと。