修飾文字の置換え2

以前、
このサイトでお世話になって、

修飾文字の置換えjavascriptを教えていただきました。

//検索/置換設定のクリア
app.findPreferences = NothingEnum.nothing;
app.changePreferences = NothingEnum.nothing;
// 検索条件の設定
app.findPreferences.findText = "(i)";
// 検索(範囲:カーソルを立ててあるストーリー全体)
var range = app.selection[0].parentStory;
// 検索の実行
var findList = range.search();
// 後ろから置換を実行
for (var i=findList.length-1; i>=0; i--){
with (findList[i]){
contents = String.fromCharCode(0x2170);
opentypeFeatures = [["nalt",1]];
}
}

という感じなのですが、

検索する文字数分置換えされてしまうのです。

普通に置換えしたいのですが、

どなたか、
教えてください。

宜しくお願いいたします。
» 001
*http://dtp-bbs.com/dtpbbs/archives/indesign_cs2nalt_20070525114211.html
この件ですね。
ミニカーさんにとってはつい先日のことかもしれませんが、環境を書いていただかないと。
上記のトピックでは InDesign CS2 とのことでしたね。

もし InDesign CS3 なら、findPreferences など廃止(変更)されたプロパティがありますのでそのままではスクリプトが動きませんが……
> 検索する文字数分置換えされてしまうのです。
との事なのでバージョンアップされたわけではないのだろうと想像します。

読解力がなくて申し訳ありませんが、ご質問の意図自体を理解できておりません。
もしかして、文字列をひとつずつ置換したいということでしょうか?
» 002
ご説明が足りず、
申し訳ございませんでした。

環境はWin CS2です。

用件としては、

検索の文字数は複数字(例えば「111」)ですが、

置き換えしたい文字は、

修飾文字(1文字)なのです。

ですが、

文字数分、
修飾文字(nalt)に変換されてしまいます。

(漢字以外の文字)

まだscriptは初心者なので、

どこがいけないのかわかりません。

宜しくお願いいたします。
» 003
> どこがいけないのかわかりません。

そのスクリプトは検索文字と置換文字が1対1でないと正常に動きません。
n対1で置換しようとしているからです。
» 004
迅速なご返答、
感謝しております。

ちょっとやってみます。

いき様、
ありがとうございました。
» 005
すみません。
なかなかうまくいきません。

具体的にどの部分が悪いのか、
教えていただけますか?
宜しくお願いいたします。
» 006
要は、3文字ある"(i)"を、1文字の
contents = String.fromCharCode(0x2170);
opentypeFeatures = [["nalt",1]];
で置き換えようとしているために意図通りの置換ができないのです。

スクリプト先頭に

keyword = "(i)";
repWord = "●";
result = app.selection[0].parentStory.search(keyword, false, false, false, false, repWord);

を挿入し、元のスクリプトの
app.findPreferences.findText = "(i)";

app.findPreferences.findText = "●";

にすればとりあえず置換できます。
●は、たとえば★など、フレーム中の他の文字とかぶらないようなものが望ましいのですが。
もっとも、スクリプト先頭で●を別の文字に置換しておき、スクリプト末尾で戻し置換するのもアリです。
スマートな方法とは言い難いですが(^^;
» 007
修飾字形のopentypeFeaturesを設定する部分を変更してください。

//検索/置換設定のクリア
app.findPreferences = NothingEnum.nothing;
app.changePreferences = NothingEnum.nothing;
// 検索条件の設定
app.findPreferences.findText = "(i)";
// 検索(範囲:カーソルを立ててあるストーリー全体)
var range = app.selection[0].parentStory;
// 検索の実行
var findList = range.search();
// 後ろから置換を実行
for (var i=findList.length-1; i>=0; i--){
with (findList[i]){
contents = String.fromCharCode(0x2170);
characters[0].opentypeFeatures = [["nalt",1]];//ここを修正
}
}
» 008
>007
勉強になりました&板汚し失礼しました。
» 009
お世話になりました。

いき様、
ななし様、
大変感謝しております。

奥深いですね!
初心者の私は、
ただただ感激です。

本当にありがとうございました。
» 010
すみません。
前の質問とちょっと違うのですが、

//検索/置換設定のクリア
app.findPreferences = NothingEnum.nothing;
app.changePreferences = NothingEnum.nothing;
// 検索条件の設定
app.findPreferences.findText = "(i)";
// 検索(範囲:カーソルを立ててあるストーリー全体)
var range = app.selection[0].parentStory;
// 検索の実行
var findList = range.search();
// 後ろから置換を実行
for (var i=findList.length-1; i>=0; i--){
with (findList[i]){
contents = String.fromCharCode(0x2170);
characters[0].opentypeFeatures = [["nalt",1]];//
}
}

を教えていただいて検証していて、

新たに問題が発生しました。
大文字と小文字(例・(A)と(a)など)の区別ができず、
困っています。

大文字でも小文字でも指定した修飾文字に変換されてしまいます。

大文字は大文字で小文字は小文字で変換したいのですが、
色々やってみていますがうまくいきません。

なにが悪いのか教えていただけませんでしょうか。

宜しくお願いいたします。
» 011
// 検索の実行
var findList = range.search();

この行で、大文字・小文字のフラグを入れてあげれば区別しますね。

検索文字列[KanaSensitive][WidthSensitive][WholeWord][CaseSensitive]置換文字列
なので、第5引数にTrueを入れてあげて下さい。
» 012
流星様、
いつもご相談にお答え頂きありがとうございます。

こういうことで、
いいのでしょうか?

// 検索の実行
var findList = range.search('', false, false, false, false, True);
» 013
間違えた。

// 検索の実行
var findList = range.search('', false, false, false, True);

でいいのでしょうか?
» 014
実際に走らせてみて、期待通りに動けば、とりあえずは正解です。
動かなければ、どこかに問題があるということが解ります。

まず、JavaScriptだとTrueではダメで、trueです。
ExtendScript Toolkitなどを使っていれば、色が変わるのでわかるところです。

また、searchメソッドの引数の検索文字列に、''をいれても動かないようですね。
''や""だと空白文字列になります。

こういう場合は、CS2に付いているサンプルスクリプトを参考にするのがよいですね。検索/置換だとTextCleanup_J.jsxが参考に出来るでしょう。
引数の検索文字列にはapp.findPreferences.findTextを入れています。
また、実際に試してみればわかりますが、undefinedでも大丈夫です。

なお、searchメソッドの引数を入れないで、あらかじめプリファレンスの方で必要なものにtrueを代入しておく方法もあります。こちらの方が私の好みではあります。

app.findPreferences.caseSensitive //大文字と小文字を区別
app.findPreferences.kanaSensitive //カナを区別
app.findPreferences.wholeWord //単語として検索
app.findPreferences.widthSensitive //半角・全角を区別
» 015
こういう話でいつも思うのが、一体どこまで試したのだろうか? という点だ。

試して動かないから聞くのと、これでいいのかなぁと思っただけで聞くのでは、ほどの開きがある。

試す、調べる、それでもわからないときに聞くという流れにしないと、あなた自身のためにならないと思う。

聞く当てのないプログラムを書いている身としては、そう感じる。
» 016
ななし様、
ありがとうございます。

しかし、
私がいまいち理解ができていません。

app.findPreferences = NothingEnum.nothing;
app.changePreferences = NothingEnum.nothing;
app.findPreferences.findText = "(A)";
var range = app.selection[0].parentStory;
var findList = range.search(app.findPreferences.findText, false, false, false, true, app.changePreferences.changeText);
for (var i=findList.length-1; i>=0; i--){
with (findList[i]){
contents = String.fromCharCode(0x0041);
characters[0].opentypeFeatures = [["nalt",1]];
}
}

でやってみたのですが、

characters[0].opentypeFeatures = [["nalt",1]];
でエラーになってしまいます。

app.findPreferences.caseSensitive //大文字と小文字を区別
app.findPreferences.kanaSensitive //カナを区別
app.findPreferences.wholeWord //単語として検索
app.findPreferences.widthSensitive //半角・全角を区別

もやってみましたが、
やはり区別なく変換されてしまいます。

具体的に教えていただけると助かります。

宜しくお願いいたします。
» 017
まず、プリファレンスを設定して、という方は、
大文字と小文字を区別したいわけですから、
app.findPreferences.caseSensitive = true;
という文を、3行めの
app.findPreferences.findText = "(A)";
の次あたりに入れておき、
5行め(変更後の6行め)は
var findList = range.search();
でOK。これで動くはず、というか、ちゃんと区別して置換できることを確認して書いています。

さて、問題の
var findList = range.search(app.findPreferences.findText, false, false, false, true, app.changePreferences.changeText);
なのですが、これがちょっと厄介。

こう書くと、実は検索だけでなく、置換まで実行されているのです。
置換されているとダメかというと、そうでもなく3行めの次あたりに
app.changePreferences.changeText = "A";
を入れておけば、大丈夫。あるいは、
app.changePreferences.changeText = "(A)";
であっても、8行めの
contents = String.fromCharCode(0x0041);
で置き換えられるのでOK。

エラーが出る場合は?というと、
app.changePreferences.changeText = "";
とした場合。つまり、一旦、文字列"(A)"が空白文字列に置換されてしまう場合。
これであっても、8行めのところで"A"(=String.fromCharCode(0x0041))が挿入されるのですが、9行めが実行される時には、まだ、その文字の挿入が確定していない。それで、エラーとなるのです。

こういうパターンは時たま遭遇します。
慣れの問題ですね。
まぁ、かくいう私も、単なるいちDTPオペレーターに過ぎません。
スクリプトを書く時間を持てるか否かは、それぞれのおかれた立場、環境によって異なりますから、頑張ってくださいとしか言いようがありませんけれど、いろいろ考えて試してみるのが早道です。

app.changePreferences.changeTextを設定しなくても、
var findList = range.search(app.findPreferences.findText, false, false, false, true);
ないし、
var findList = range.search(app.findPreferences.findText, false, false, false, true, undefined);
だと、検索のみ実行しますからエラーになりません。
» 018
ななし様、
ありがとうございます。

しかし、
私がいまいち理解ができていません。

app.findPreferences = NothingEnum.nothing;
app.changePreferences = NothingEnum.nothing;
app.findPreferences.findText = "(A)";
var range = app.selection[0].parentStory;
var findList = range.search(app.findPreferences.findText, false, false, false, true, app.changePreferences.changeText);
for (var i=findList.length-1; i>=0; i--){
with (findList[i]){
contents = String.fromCharCode(0x0041);
characters[0].opentypeFeatures = [["nalt",1]];
}
}

でやってみたのですが、

characters[0].opentypeFeatures = [["nalt",1]];
でエラーになってしまいます。

app.findPreferences.caseSensitive //大文字と小文字を区別
app.findPreferences.kanaSensitive //カナを区別
app.findPreferences.wholeWord //単語として検索
app.findPreferences.widthSensitive //半角・全角を区別

もやってみましたが、
やはり区別なく変換されてしまいます。

具体的に教えていただけると助かります。

宜しくお願いいたします。
» 019
すみませんでした。

app.findPreferences = NothingEnum.nothing;
app.changePreferences = NothingEnum.nothing;
app.findPreferences.findText = "(A)";
var range = app.selection[0].parentStory;
var findList = range.search(app.findPreferences.findText, false, false, false, true);
for (var i=findList.length-1; i>=0; i--){
with (findList[i]){
contents = String.fromCharCode(0x0041);
characters[0].opentypeFeatures = [["nalt",1]];
}
}

でいけました。

流星様、
ななし様、
ありがとうございました。