リンクをクリップボードにコピー
コピー完了
OS:Windows 11
InDesgin ver:ver.19
後ルビのテキストにルビを振るスクリプトをUXPで書きましたが、「rubyFlagのプロパティがない」と エラーが出てしまいます。
元々同じ用途で書いていたスクリプトはエラーを吐かなかったのですが、「𠮷」のような文字がJavaScriptの仕様上ズレてしまうのに対応するため、ルビをチェックする部分を改変しました。
親文字部分が「ズレる漢字」が0~1文字の場合しか現状対応はできていないのですが、**rubyPositions**の値はブラウザ上でJSとして実行しても、カウントは問題ありませんでした。(なぜブラウザでテストしたかは後述)
itemByRangeで範囲が誤っていて(あり得ない区間になっている?)、返り値にObjectが設定されていないのかもしれないと考えています。
Characters.itemByRange()はInDesignに実際に表示されている文字(グリフ)でカウントされていて、かつ閉区間[a,b]での指定だと思っていたのですが、なにぶん公式リファレンスだと情報が足りず、また事情があってInDesignが入っていない環境でコーディング・テストをしなければならないためテストができなくお手上げ状態になってしまいました…。
もしUXPでのCharacters.itemByRange()の挙動についてお詳しい方がおられればアドバイスをいただきたいです。
// 省略
const START_RUBY_CHAR = "(";
const END_RUBY_CHAR = ")";
main();
function main() {
const selected = doc.selection;
selected.forEach((s) => {
const rubyPositions = checkRuby(s);
setRuby(s, rubyPositions);
});
}
function checkRuby(textFrame) {
// 省略
rubyPositions.push({
kanjiStart: j + 1, // 漢字以外にマッチした時にここに到達するので +1 する。文頭かつ漢字の場合は j=-1 なので 0。
rubyStart: rubyStartIndex + 1, // ふりがなの先頭インデックス
rubyEnd: rubyEndIndex, // ")"のインデックス
shiftCount: shiftCount, // このルビでの"("までに出てくる文字のズレのカウント
curCount: curCount, // 親文字開始部分とふりがな開始部分でのズレのカウントの差
});
// 省略
return rubyPositions;
}
function setRuby(textFrame, rubyPositions) {
// positionがずれていくため、後ろから操作する
for (let i = rubyPositions.length - 1; i > -1; i--) {
let rubyString = "";
try {
rubyString = textFrame.parentStory.contents
.substring(rubyPositions[i].rubyStart - rubyPositions[i].shiftCount, rubyPositions[i].rubyEnd) // contentsの返り値はstringなのでshiftCountは使わない
.trim();
} catch (error) {
alert(error.message);
return;
}
textFrame.parentStory.texts
.itemByRange(
rubyPositions[i].rubyStart - 1 - rubyPositions[i].shiftCount,
rubyPositions[i].rubyEnd - rubyPositions[i].shiftCount
)
.remove();
const rubyObject = textFrame.parentStory.characters.itemByRange(
rubyPositions[i].kanjiStart -
rubyPositions[i].shiftCount +
rubyPositions.curCount,
rubyPositions[i].rubyStart - 2 - rubyPositions[i].shiftCount
);
rubyObject.rubyFlag = true; // ここでエラー?
rubyObject.rubyType = 1249011570; // グループルビ定数
// rubyObject.rubyType = RubyTypes.GROUP_RUBY; // 定数はエラーになってしまう?
rubyObject.rubyString = rubyString;
}
}
// InDesignにアラートを表示する関数
// 省略
リンクをクリップボードにコピー
コピー完了
Characters.itemByRange()の戻り値はCharacterオブジェクトの配列です。
ですから、変数rubyObjectは配列([Character, Character, Character, ...])になりますよね。
従ってエラー部分はArray.rubyFlagを取得しようとしているので、それは無理ですよねって話です。
リンクをクリップボードにコピー
コピー完了
https://developer.adobe.com/indesign/dom/api/c/Characters/
公式リファレンスによればCharacters.itemByRange()メソッドの戻り値はCharacterオブジェクトと書いています。
実際に複数文字の場合だとしても配列としては返ってきておらず、複数文字を指すCharacterとして返ってきており、修正前ではルビを振れたことを確認しています。
配列として返っているからできない、ということではないかと思います。
リンクをクリップボードにコピー
コピー完了
失礼しました。私は随分長い間勘違いしてました。
確かにCharacterオブジェクトとして返ってきてますね。
リンクをクリップボードにコピー
コピー完了
あと、そのケースでテキストがずれるのはサロゲートペア処理を行っていないからです。characterの文字コードをチェックして上位サロゲートのレンジを検知した時は次の文字は下位サロゲートとして処理する必要があります。また、テキストの内容が必要ない場合でも上位サロゲートのチェックは必要で検知した場合、次のcharacterはスキップする必要があります。
リンクをクリップボードにコピー
コピー完了
すみません、書き方が雑だったかもしれません。
サロゲートペアなどの処理や異体字セレクタ(SVSやIVS)の処理は省略部分で施してあり、具体的には
という処理がなされています。実際にIndDesignではない環境では
// 「𠮷野家の𠮷田(よしだ)」という文字列の場合
rubyPosition[0] ={
kanjiStart: 5
rubyStart: 8
rubyEnd: 12
shiftCount: 2
curCount: 1
});
// となって
rubyPosition.kanjiStart - rubyPosition.shiftCount +rubyPosition.curCount = 4;
rubyPosition.rubyStart - 2 - rubyPosition.shiftCount = 4;
// となることを確認しています。InDesign上で、親文字は「𠮷野家の𠮷田(よしだ)」の4番目「𠮷」(0-indexed)となると想定していました。
リンクをクリップボードにコピー
コピー完了
複数形にするのと、添字を書き忘れていました。すみません。
rubyPositions[0].kanjiStart - rubyPositions[0].shiftCount +rubyPositions[0].curCount = 4;
rubyPositions[0].rubyStart - 2 - rubyPositions[0].shiftCount = 4;
リンクをクリップボードにコピー
コピー完了
>サロゲートペアとSVS(1つずらす)
>IVS(2つずらす)
これは普通に間違ってる(サロゲートペアはあってる)気がしますが、範囲がずれてたところで「rubyFlagのプロパティがない」というエラーにはならないようなので、他のところで書き間違いがありそうですね。