文字にルビがある場合、ルビを含めた文字列を取得する 

考え方: 選択している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;//全角・半角を区別
}