2011年8月28日日曜日

お題3に燃料投下されて

8月18日、#dtpstudySP2にNAOIさんが燃料投下
8月20日、続けてkmutoさんが燃料投下

ひと通り課題を終えて安心しきっていたアチキは自分の大きな勘違いに気づく。
お題3って人様の作ったスクリプトを使ってはダメなんだ~。コメント欄を読むと
「ドキュメントの文字すべてを対象にして、指定した文字にルビをつける」というテーマでしょうか? ものすごく難易度が高いっすね! 宿題の想定レベルをはるかに超えてます!
kmutoさんは
「楽しく」の「楽」だけを正規表現で取り出すのはちょっとコツがある。それが後方肯定「(?=STRING)」。これで、文字列としては「楽しく」に一致するけれども「マッチした文字列」として返されるのが「楽」だけ、という挙動を実現できる。
ということは「楽チンな楽曲を選んで楽しく演奏♪」の楽しく部分にだけルビを振るというお題だったのかぁ~~~(絶叫 しかも「ドキュメントの文字すべてを対象にして、指定した文字にルビをつける」というテーマなら、もう無理、無理。古旗サイトや本を参考にしたけど全滅。
実際、選択された文字が特定の文字の場合のみルビを振るを正規表現を使って書き換えてみたけど動作しない。↓
sel = app.activeDocument.selection;
chr = sel[0].characters[0];
if (chr.contents == "楽(?=しく)" )
{
chr.rubyFlag = true;
chr.rubyString = "たの";
}

以下は失敗例のひとつ
var txtObj=app.activeDocument.selection[0];
str = "楽しく";
chr = str.charAt(0);
txtObj.contents = "楽";
txtObj.characters[0].rubyFlag = true;
txtObj.characters[0].rubyString = "たの";
//↑これだとテキストフレーム内の文字が楽(たの)に替わってしまい、他部分が削除されてしまう。裏づけ理論無しに適当に探して弄ったからどうしてそうなるのか分からない。


んで、困っていた。
NAOIさんのコメント欄を見るとカル様のライブラリのアイテムを自動で配置する(InDesign CS3~)が紹介されていた。正規表現を使ってテキストをライブラリアイテムに検索・置換するものだから、応用できそう(^^

ふむ、正規表現を使う場合は

app.findGrepPreferences = NothingEnum.nothing;

と宣言する必要があるようだ。Adobe InDesign CS4 Scripting Guideのp90にも載っている。でもどう書き換えたらいいか分からない。。。orz

そこでapp.findGrepPreferences = NothingEnum.nothing;でググる。

インライングラフィックをファイル名に置き換える

に辿り着く。

こっ、これはカル様の逆パターンなのでは。で、構文が短い^^ これは試す価値はある。
app.findGrepPreferences = NothingEnum.nothing;
app.changeGrepPreferences = NothingEnum.nothing;
app.findGrepPreferences.findWhat = "~a";
var inObj = app.activeDocument.findGrep();
for (var i = inObj.length - 1; i > -1; i--) {
try {
inObj[i].contents = inObj[i].allGraphics[0].itemLink.name;
} catch(inObj) {}
}
赤字部分に検索文字、青字部分をルビ付きに置き換えた。
app.findGrepPreferences = NothingEnum.nothing;
app.changeGrepPreferences = NothingEnum.nothing;
//9/11追記:以下は正規表現が違ってました。
app.findGrepPreferences.findWhat = "楽(=?しく)";

//9/11追記:こちらが正解(^^;
app.findGrepPreferences.findWhat = "楽(?=しく)";
var inObj = app.activeDocument.findGrep();
for (var i = inObj.length - 1; i > -1; i--) {
try {
inObj[i].characters[0].rubyFlag = true;
inObj[i].characters[0].rubyString = "たの"
;
} catch(inObj) {}
}
で動いた。ヾ(〃^∇^)ノわぁい♪

でもどうしてそうなるのか分からない。分からないがこの構文は暗記するに値するものだということは分かる。かなり応用の利きそうな素敵なスクリプトです^^

ps. 余談です。楽(=?しく)をエディタの正規表現で検索すると楽しくにマッチするのはどうしてでしょう? 正規表現を正確に反映してくれるエディタを探してます。

9/11自分で気付く:正規表現が間違っていたから。。。orz 楽(=?しく)は間違い楽(?=しく)が正解。それでもJavaScriptでマッチするのはど~ゆ~理由???

8/31追記:フレーム選択で置換したい時は4行目を
var inObj = app.activeDocument.selection[0].findGrep();
にする。

さらに追記:ドキュメント全体、1つのテキストフレームの処理は上記でOKだが、複数選択された場合は[InDesign][JavaScript]【改変】テキストを正体に戻すを参考に冒頭に以下を加え
var selObj = app.activeDocument.selection;
var textFrameCount = 0 ;
for (s = 0 ; s < selObj.length ; s++) {
if (selObj[s].constructor.name =="TextFrame") {
textFrameCount ++ ;
var inObj = app.activeDocument.findGrep(); を
var inObj = selObj[s].findGrep(); に書き換える。

3 件のコメント:

  1. try { と} catch(inObj) {} の行を削除しても動くんだよなぁ~

    返信削除
  2. 間違えてif文を入れても動作しやがる。

    app.findGrepPreferences=NothingEnum.nothing;
    app.changeGrepPreferences=NothingEnum.nothing;
    app.findGrepPreferences.findWhat="楽(?=しく)";

    var inObj=app.activeDocument.findGrep();

    for(var i=0; i<inObj.length; i++){
    if(inObj[i].characters[0]="楽"){
    inObj[i].characters[0].rubyFlag=true;
    inObj[i].characters[0].rubyString="たの";
    }
    }
    Grep検索だから「楽」にしかマッチしないのだからifは不要なんだよなぁ~

    返信削除
  3. 最短はこれだけか?
    app.findGrepPreferences.findWhat = "楽しく";
    var inObj=app.activeDocument.findGrep();
    for(var i=0; i<inObj.length; i++){
    inObj[i].rubyFlag=true;
    inObj[i].characters[0].rubyString="たの";
    }

    返信削除