文字にルビがある場合、ルビを含めた文字列を取得する
考え方: 選択しているtextFrame内の文字がルビを含むかどうかを判定: textFrame.characters.everyItem().rubyFlag -->list of boolean
・全てがfalseならば、ルビはない。この場合、textFrame.contentsをそのまま返す。
・trueがある(ルビが存在)場合:
InDesignの正規表現検索機能を使ってで、ルビ(モノルビとグループルビ1回ずつ)を検索、
その親文字のindex(文字がtextFrame内の順番)を取得、親文字の後に挿入
initFindChangeGrepPreferences();
var tf = app.selection[0];
var text = getContentsIncludingRuby(tf);
$.writeln(text);
function getContentsIncludingRuby(tf) {
//textFrameの内容を取得する(ルビを含む)
if (tf.characters.everyItem().rubyFlag.join().indexOf("true") === -1) {
return tf.contents;//ルビがない場合はそのまま返す
}
var rubyTypes = {
"monoRuby": RubyTypes.PER_CHARACTER_RUBY,//モノルビ
"groupRuby": RubyTypes.GROUP_RUBY,//グループルビ
}
var rubyInfos = [];
for (var k in rubyTypes) {
app.findGrepPreferences.findWhat = "";
app.findGrepPreferences.rubyType = rubyTypes[k];
var rubys = tf.findGrep();
var len = rubys.length;//該当tf内のモノルビ+グループルビの数
for (var i = len - 1; i >= 0; i--) {
//ルビと該当親文字のindexを抽出
rubyInfos.push({
"rubyString": rubys[i].rubyString,
"startPos": rubys[i].characters.firstItem().index,
"endPos": rubys[i].characters.lastItem().index,
});
//
/*
//直接InDesignに書き込むときは、以下のようにする
//(?<=.{x}):肯定的後読み。現在の位置の直前にx文字ある場合にマッチする。
//実際の文字列をマッチさせるものではなく、位置を特定するために使用される。
var rubyStrLen = rubys[i].length;//ルビ文字列の長さ
app.findGrepPreferences.findWhat = "(?<=.{" + rubyStrLen + "})";
var result = rubys[i].findGrep();
result[0].contents = "(" + rubys[i].rubyString + ")";//該当位置(ルビ親文字の最終文字の後)にルビ文字列を挿入
*/
//
}
}
rubyInfos.sort(sortBy('startPos'));//ルビの順番でソート
return mergeRubyToContents(tf.contents, rubyInfos);;
}
function mergeRubyToContents(contents, rubyList) {
//ルビと親文字を結合する
var len = rubyList.length;
var slicePos;
for (var i = len - 1; i >= 0; i--) {
slicePos = rubyList[i]["endPos"] + 1;
contents = contents.slice(0, slicePos) + "(" + rubyList[i]["rubyString"] + ")" + contents.slice(slicePos);
}
return contents;
}
function sortBy(k1, k2) {
return function (o, p) {
var a, b;
if (o && p && typeof o === 'object' && typeof p === 'object') {
a = o[k1];
b = p[k1];
if (a === b) {
return typeof k2 === 'function' ? k2(o, p) : 0;
}
if (typeof a === typeof b) {
return a < b ? -1 : 1;
}
return typeof a < typeof b ? -1 : 1;
} else {
thro("error");
}
}
}
function initFindChangeGrepPreferences() {
//検索置換の設定をリセット
app.findGrepPreferences = NothingEnum.nothing;//検索をリセット(検索文字列、検索形式)
app.changeGrepPreferences = NothingEnum.nothing;//置換をリセット(置換文字列、置換形式)
app.findChangeGrepOptions.includeLockedLayersForFind = true;
app.findChangeGrepOptions.includeLockedStoriesForFind = true;
app.findChangeGrepOptions.includeHiddenLayers = false;
app.findChangeGrepOptions.includeMasterPages = false;
app.findChangeGrepOptions.includeFootnotes = false;
app.findChangeGrepOptions.kanaSensitive = true;//カナを区別
app.findChangeGrepOptions.widthSensitive = true;//全角・半角を区別
}
