[ 掲示板に戻る ]

記事No.9944に関するスレッドです

InDesignのchangeText()について / まるこめ
初めて投稿させていただきます。どうぞよろしくお願いいたします。

InDesignのスクリプトに関しての質問です。
changeText()の戻り値をとろうとすると、最後の1文字がきちんと取得できません。
例えば"test"を"abc"で置換する場合、app.changeText()[0].contentsが"ab"となります。
changeGrep()では"abc"となります。
どこか書き方を間違っていますでしょうか。
changeGrep()を使えば望む結果が得られるので火急の問題というわけではないのですが、気になったため質問させていただきました。
ご教示いただけますと幸いです。
どうぞよろしくお願いいたします。

# 環境
Windows 10
InDesgin 14.0.3
VSCode 1.46.1

# コード
```
function myChangeText(findStr, changeStr) {
app.findTextPreferences = app.changeTextPreferences = NothingEnum.NOTHING;
app.findTextPreferences.findWhat = findStr;
app.changeTextPreferences.changeTo = changeStr;
var result = app.changeText()[0];
app.findTextPreferences = app.changeTextPreferences = NothingEnum.NOTHING;
return result;
}

function myChangeGrep(findRgx, changeStr) {
app.findGrepPreferences = app.changeGrepPreferences = NothingEnum.NOTHING;
app.findGrepPreferences.findWhat = findRgx;
app.changeGrepPreferences.changeTo = changeStr;
var result = app.changeGrep()[0];
app.findGrepPreferences = app.changeGrepPreferences = NothingEnum.NOTHING;
return result;
}

// テスト1
// var tmp1 = myChangeText("test", "abc");
// $.writeln(tmp1.toSpecifier())
// $.writeln(tmp1.contents); // ab

// テスト2
var tmp2 = myChangeGrep("test", "abc");
$.writeln(tmp2.toSpecifier())
$.writeln(tmp2.contents); // abc

```

No.9937 2020/06/25(Thu) 09:00:15
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36

Re: InDesignのchangeText()について / Uske_S URL
まるこめさん:
僕も InDesign 2019、2020 で再現しました。
しかし調べた限りでは原因がイマイチわかりませんでした。
changeText()[0].contents は確かに "ab" になってしまいますね。
一方で、以下のように findText() したものを後から参照すると正しく contents を取得できます。

function myChangeText(findStr, changeStr) {
app.findTextPreferences = app.changeTextPreferences = NothingEnum.NOTHING;
app.findTextPreferences.findWhat = findStr;
app.changeTextPreferences.changeTo = changeStr;
var fd = app.activeDocument.findText();
var ch = app.activeDocument.changeText();
app.findTextPreferences = app.changeTextPreferences = NothingEnum.NOTHING;
return fd;
}

function myChangeGrep(findRgx, changeStr) {
app.findGrepPreferences = app.changeGrepPreferences = NothingEnum.NOTHING;
app.findGrepPreferences.findWhat = findRgx;
app.changeGrepPreferences.changeTo = changeStr;
var result = app.changeGrep()[0];
app.findGrepPreferences = app.changeGrepPreferences = NothingEnum.NOTHING;
return result;
}

// テスト1
var tmp1 = myChangeText("test", "abc");
$.writeln(tmp1[0].toSpecifier())
$.writeln(tmp1[0].contents); // abc

元の検索語句から置換後の文字列 "abc" を取得できるのに、changeText() では取得できないというのは不具合な気がします…。
(なぜ検索語句の contents が "test" ではないか、の説明は必要でしょうか?)

僕自身は普段から(よほどの事情がない限り) changeGrep() しか使っていないので、この件は知りませんでした。 一応、Adobeのスクリプティングガイド等も当たってみましたがそれらしい記述は見つからず。

おっしゃるように changeGrep() で対処されるほかないのですが、ちょっと気持ち悪いですね……

No.9938 2020/06/25(Thu) 12:00:50
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36

Re: InDesignのchangeText()について / まるこめ
Uske_Sさま

早速お教えいただきありがとうございます!
自分の環境でも、findText()から取得することができました。

重ね重ね恐縮ですが、もう一点お教えいただけないでしょうか…。
>検索語句の contents が "test" ではないか
についてです。
戻り値が、toSpecifier()で示されるように「どのテキストフレームの何文字目から何文字目」という参照先の指示だからではないかと思ったのですが、

var tmp1 = myChangeText("test", "abcdef");
$.writeln(tmp1[0].toSpecifier())
$.writeln(tmp1[0].contents);

を実行すると、下記のようになります。

(/document[@id=12]//story[@id=113195]/character[0] to /document[@id=12]//story[@id=113195]/character[3])
cdef

自分の仮説が正しいなら、「abcd」となるように思います。
どこかに誤解がありますでしょうか。それとも根本的に間違っていますでしょうか。

もし気が向かれましたら、またお教えいただけますと幸いです。
何卒よろしくお願いいたします。

No.9941 2020/06/25(Thu) 14:50:34
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36

Re: InDesignのchangeText()について / Uske_S URL
おっしゃるとおりの理解でいいと思います。
これについては僕自身も「結果からの予測」なので確実なことは言えないのですが、僕もそういう理解です。
要するに「何文字目」を参照するから test ではなく abc が参照できるというわけです。
ただし、これは置換後の文字列が置換前の文字列と同数か少ない場合です。提示されたように、置換後の文字列のほうが多い場合は結果が異なります。

僕が掲示したコードの一部を下記のように書き換えた上で、test という文字列を選択した状態でテストしてみてください。

var fd = app.activeDocument.selection[0].findText();

選択範囲が cdef に移ることが分かっていただけるかと思います。

実は話がややこしくなるので前回の回答には書いていないのですが、InDesignの検索置換の都合上このようになります。これが最初にお問い合わせいただいた "ab" としてしか contents を取得できないことと関係があるような気はしています。

なぜこうなるかですが、以下についても「結果からの予測」です。あしからず。
InDesignの検索置換の特性上、test という文字列に対して abcdef という文字列が直接挿入されるわけではありません。
t の代わりに a 、 e の代わりに b 、s の代わりに c 、また t の代わりに d というように、文字それぞれの contents プロパティを置き換えるようにして置換されます。それぞれ別々の色の文字色を当てて置換してみるとそれが分かると思います。
しかし、残りの ef はもう入るべき文字がありません。なので最後の文字 d (元は2回目の t )と同じ文字属性を用意し、そこに e と f も入れられます。
この時、選択範囲も同じように e 、f 、と引きずられます。
しかし選択していた範囲は4文字なので、2文字増えた分だけずれてcdef に選択範囲が移ってしまった、というのが僕の理解です。

このことがスクリプトの結果からも言えるのです。
ただ changeText() と changeGrep() の結果の違いの説明にはならないので、これが先の問題とどこまで関係しているかはわかりません。

いずれにせよ、スクリプトで検索置換を行う場合はこういうケースもあります(選択範囲が後ろへずれる)のでご注意ください。

なんとなく伝わったでしょうか?

No.9942 2020/06/25(Thu) 19:35:28
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36

Re: InDesignのchangeText()について / まるこめ
Uske_S様

お返事が遅くなり申し訳ございません。

文字色を変えて試してみて、おっしゃっていることがよく分かりました。
character1つずつのcontentsを置換しているというのは、個人的には驚きでした。
スクリプトを書き始めて日が浅いので、こういったことが起こりうると事前に知っておくことができて良かったです。
大変勉強になりました。
重ね重ね、本当にありがとうございました!

No.9943 2020/06/26(Fri) 14:49:02
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36

Re: InDesignのchangeText()について / Uske_S URL
伝わったようで良かったです。

検索置換では、置換前後で文字数が変わる場合に注意が必要です。せっかくなので置換後に文字数が減る場合のリスクもお伝えしておきます(ご存知でしたらすみません)。

正規表現検索置換でもテキスト検索置換でも、先般お伝えした通り、InDesignの検索置換は検索マッチした文字に対して頭から順番に contents の中身を置換していきます。
文字属性が途中から変わる、そして文字数が減る場合、添付画像のような結果になることがあります。
(端 の字の色が変わっています)
先の検索置換の仕組み?を理解していればこの結果もご理解いただけると思います。このような事があるので検索置換は気をつけなばなりませんし、ましてやスクリプトで一括ドン! は本当に気をつけてください。

この例では 釜戸(?=端次郎) で検索し、 竈 だけで置換すれば「端」の文字属性は変わりません。
検索置換は便利ですが安易に行うと痛い目を見るので、スクリプトで操作する場合は本当に注意してくださいね。
蛇足ながら失礼しました。

No.9944 2020/06/29(Mon) 09:56:42
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36