/** * @fileoverview InDesign共通ライブラリ * @author Kenshi Muto <kmuto@debian.org> * @version 2,3 */ /* Copyright: 2008-2016 Kenshi Muto ---------------------------------------------------------------------- ソフトウェア使用許諾同意書 本ソフトウェアの利用・変更・再配布にあたっては、下記の使用許諾同意書に 同意する必要があります。 1. 本使用許諾同意書における「ソフトウェア」とは、機械可読の資料 (ライブ ラリ、スクリプト、ソースファイル、データファイル)、実行形式、および 文書を意味します。 2. 本ソフトウェアの使用許諾同意書に同意する限りにおいて、使用者は 本ソフトウェアを自由に利用、変更することができます。 3. 本ソフトウェアに変更を加えない限りにおいて、使用者は本ソフトウェアを 自由にコピー、再配布することができます。 4. 本ソフトウェアは無保証です。作者およびそれに関連する組織、配布者は、 本ソフトウェアの使用に起因する一切の直接損害、間接損害、偶発的損害、 特別損害、懲戒的損害、派生的損害について何らの責任・保証も負いません。 5. 本ソフトウェアを変更した上で再配布するときには、下記の事項すべてに 従わなければなりません。 - 使用許諾同意書の内容に変更を加えてはなりません。技術上の理由で 文字エンコーディングの変換を行うことは許可しますが、その使用者が 特殊な技術的措置なしに可読な形でなければなりません。 - 技術上の理由でバイナリ化・難読化を行う場合も、変更箇所を含めた ソフトウェアを、その使用者が可読可能な形式の形で同一のメディアで 提供しなければなりません。本使用許諾同意書の2条および3条により、 使用者が可読形式の該当ソフトウェアを変更、コピー、再配布することを 妨げてはなりません。 - ソフトウェア構成物の所定の作者名の欄に、変更者のクレジット (個人名、企業名、所属、連絡先など)を「追加」しなければなりません。 6. 本ソフトウェアを変更した上で再配布するときには、変更理由および その内容を明記することが推奨されます。 7. 使用者がソフトウェアに適用可能な特許に対して特許侵害にかかわる何らか の行動を開始した時点で、この使用許諾同意書は自動的に終了し、以降 使用者はこの使用許諾書によって与えられた一切の権利を放棄するものと します。 著作権所有者 Copyright (C) 2008-2016 Kenshi Muto. All rights reserved. 使用許諾同意書バージョン1.0 著作権所有者による書面での事前の許可がない限り、この使用許諾同意書 に変更を加えてはなりません。 ---------------------------------------------------------------------- */ // #target "InDesign" __do_benchmark__ = null; /** * InDesignのCSバージョンを返す * @type Float * @return CSバージョン数値 */ function getCSVersion() { if (isNaN(app.version)) { if (parseInt(app.version) > 8) { // Over CC (CC=9?, CC2016=10?, CC2017=12, CC2018=13) return parseInt(app.version); } else if (parseInt(app.version) >= 8) { // CS6 return 6; } else if (parseInt(app.version) >= 7) { // CS5 return 5; } else if (parseInt(app.version) >= 6) { // CS4 return 4; } else if (parseInt(app.version) >= 5) { // CS3 return 3; } else if (parseInt(app.version) >= 4) { // CS2 return 2; } else { // FIXME: とりあえずCS2と想定 return 2; } } else { // FIXME:とりあえずCS2と想定 return 2; } } /** * スクリプトフォルダのパスを返す * @type String * @return フォルダパス */ function getCSPath() { if (getCSVersion() >= 3) { return app.scriptPreferences.scriptsFolder + "/hwj-Scripts/"; } else { return app.filePath + "/Presets/Scripts/"; } } /** * スクリプト名の配列順にスクリプトを実行する * @param {String} sarray[] スクリプト名の配列(.jsxは省略する) * @return Nothing */ function callScripts(sarray) { var fpath = getCSPath(); var start = null; for (var _i = 0; _i < sarray.length; _i++) { var f = new File(fpath + sarray[_i] + ".jsx"); try { if (__do_benchmark__ == true) { start = startBenchMark(); } if (getCSVersion() > 4) { app.doScript(f, ScriptLanguage.javascript); } else { app.doScript(f, ScriptLanguage.javascript, null, UndoModes.ENTIRE_SCRIPT, f.replace(/.+\//, "")); } if (__do_benchmark__ == true) { alert(endBenchMark(start, f + ": ")); } } catch(e) { alert(f + ": " + e); exit(0); } } } /** * 指定のファイルを探すのに1つ上のディレクトリも探す * @param {Document} document ドキュメントオブジェクト * @param {String} filename ファイル名 * @type String * @return ファイルパス */ function getFilePath(document, filename) { if (document instanceof Document) { var file = new File(document.filePath + "/" + filename); if (file.exists == true) { return file.absoluteURI; } var file = new File(document.filePath.parent + "/" + filename); if (file.exists == true) { return file.absoluteURI; } var file = new File(document.filePath.parent.parent + "/" + filename); if (file.exists == true) { return file.absoluteURI; } alert(filename + " は見つかりませんでした。ドキュメントと同一ディレクトリまたは親ディレクトリに存在している必要があります。"); return null; } else if (document instanceof File) { var file = new File(document.path + "/" + filename); if (file.exists == true) { return file.absoluteURI; } var file = new File(document.parent.path + "/" + filename); if (file.exists == true) { return file.absoluteURI; } var file = new File(document.parent.parent.path + "/" + filename); if (file.exists == true) { return file.absoluteURI; } alert(filename + " は見つかりませんでした。ドキュメントと同一ディレクトリまたは親ディレクトリに存在している必要があります。"); return null; } else { alert("指定されたベース文書ファイルは、InDesignドキュメントでもファイルでもありません。"); return null; } } /** * mmに単位を変更する * @param {Document} document ドキュメントオブジェクト * @type Long[2] * @return 古いX方向単位とY方向単位 */ function toMmMode(document) { var backunitx = document.viewPreferences.horizontalMeasurementUnits; var backunity = document.viewPreferences.verticalMeasurementUnits; var backunitline; try { backunitline = document.viewPreferences.lineMeasurementUnits; } catch (e) { backunitline = document.viewPreferences.strokeMeasurementUnits; } document.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.millimeters; document.viewPreferences.verticalMeasurementUnits = MeasurementUnits.millimeters; try { document.viewPreferences.lineMeasurementUnits = MeasurementUnits.MILLIMETERS; } catch(e) { document.viewPreferences.strokeMeasurementUnits = MeasurementUnits.MILLIMETERS; } return [ backunitx, backunity, backunitline ]; } /** * mmから単位を元に戻す * @param {Document} document ドキュメントオブジェクト * @param {Long[2]} unit 戻す単位配列 * @type Nothing */ function revertMmMode(document, unit) { document.viewPreferences.horizontalMeasurementUnits = unit[0]; document.viewPreferences.verticalMeasurementUnits = unit[1]; try { document.viewPreferences.lineMeasurementUnits = unit[2]; } catch(e) { document.viewPreferences.strokeMeasurementUnits = unit[2]; } } /** * ベンチマーク用に開始時間を返す * @type Long * @return 開始時間(ミリ秒) */ function startBenchMark() { return new Date().getTime(); } /** * ベンチマーク用に時間差を返す * @param {Long} starttime 開始時間 * @param {String} prefix 付加する先頭文字列 * @type String * @return 結果文字列 */ function endBenchMark(starttime, prefix) { return prefix + "" + ((new Date().getTime() - starttime) / 100) + "秒"; } /** * 特定の段落スタイルに指定の先頭文字を挿入する * @param {Document} document ドキュメントオブジェクト * @param {String[]} pnames 段落スタイル名の配列 * @param {String} prefix 挿入文字列 * @param {String} cname 挿入文字列の文字スタイル名 * @param {String} postfix 挿入文字後に入れる文字列(cnameの文字スタイルは適用されない) * @type Nothing */ function insertItemMark(document, pnames, prefix, cname, postfix) { var pages = document.pages; for (var i = 0; i < pages.length; i++) { var paragraph = findContentFromObjectByStyles(document.pages[i], pnames, "byraw"); for (var i2 = 0; i2 < paragraph.length; i2++) { insertPrefix(document, paragraph[i2], prefix, cname, postfix, true); } } } /** * コンテンツオブジェクトの前に文字列を挿入する * @param {Document} document ドキュメントオブジェクト * @param {Object} obj コンテンツオブジェクト(Paragraphなど) * @param {String} chars 挿入文字列 * @param {String} cname 文字スタイル * @param {String} postfix 挿入文字後に入れる文字列 * @param {boolean} remove 挿入前に既存の挿入文字列の削除の有無(true=削除する、false=削除しない) * @type Nothing */ function insertPrefix(document, obj, chars, cname, postfix, remove) { if (remove == true) { obj.search(chars + postfix, false, false, false, false, ""); } obj.characters[0].insertionPoints[0].contents = chars + postfix; setCharacterStyle(document, obj, postfix, cname); } /** * 区切り文字が現れるまで文字スタイルを割り当てる * @param {Document} document ドキュメントオブジェクト * @param {Object} obj コンテンツオブジェクト(Paragraphなど) * @param {String} splitter 区切り文字 * @param {String} cname 文字スタイル * @param {boolean} limit 数値、.、-、A-Zの文字のみに割り当てする制限の有無(true=制限する、false=制限しない) * @type Long * @return 割り当てた文字数 */ function setCharacterStyle(document, obj, splitter, cname, limit) { if (obj.contents.match(splitter)) { style = getCharacterStyleByName(document, cname); if (style == null) { alert("スタイル" + cname + "がありません。"); return null; } var chars = obj.characters; for (var i = 0; i < chars.length; i++) { if (chars[i].contents == splitter) return i; if (limit == false || chars[i].contents.match(/[0-9\.\-A-Z]/)) { chars[i].appliedCharacterStyle = style; } } return i; } return null; } /** * 指定の名前の文字スタイルオブジェクトを返す * @param {Document} document ドキュメントオブジェクト * @param {String} name 文字スタイル名 * @type CharacterStyle * @return 文字スタイルオブジェクト */ function getCharacterStyleByName(document, name) { // XXX: CS2ではitem(String)では名前を取れない模様 var styles = document.characterStyles; for (var i = 0; i < styles.length; i++) { if (styles[i].name == name) return styles[i]; } if (getCSVersion() > 2) { return getCharacterStyleByNameFromGroup(document.characterStyleGroups, name); } return null; } /** * グループを含め、全文字スタイルオブジェクトの配列を返す * @param {Document} document ドキュメントオブジェクト * @type CharacterStyle[] * @return 文字スタイル配列 */ function getAllCharacterStyles(document) { var array = []; for (var i = 0; i < document.characterStyles.length; i++) { array.push(document.characterStyles[i]); } getAllCharacterStylesFromGroup(document.characterStyleGroups, array); return array; } /** * getAllCharacterStylesの実体として、再帰で文字スタイルグループを処理する * @param {CharacterStyleGroups} cgroups 文字スタイルグループ群 * @param {CharacterStyle} array[] 文字スタイル配列 * @type Nothing */ function getAllCharacterStylesFromGroup(cgroups, array) { for (var i = 0; i < cgroups.length; i++) { for (var i2 = 0; i2 < cgroups[i].characterStyles.length; i2++) { array.push(cgroups[i].characterStyles[i2]); getAllCharacterStylesFromGroup(cgroups[i].characterStyleGroups, array); } } } /** * 指定の名前の文字スタイルオブジェクトを返す(文字スタイルグループ) * @param {CharacterStyleGroups} cgroups 文字スタイルグループ群 * @param {String} name 文字スタイル名 * @type CharacterStyle * @return 文字スタイルオブジェクト */ function getCharacterStyleByNameFromGroup(cgroups, name) { for (var i = 0; i < cgroups.length; i++) { var styles = cgroups[i].characterStyles; for (var i2 = 0; i2 < styles.length; i2++) { if (styles[i2].name == name) return styles[i2]; } return getCharacterStyleByNameFromGroup(cgroups[i].characterStyleGroups, name); } return null; } /** * 指定の名前の段落スタイルオブジェクトを返す * @param {Document} document ドキュメントオブジェクト * @param {String} name 段落スタイル名 * @type ParagraphStyle * @return 段落スタイルオブジェクト */ function getParagraphStyleByName(document, name) { // XXX: CS2ではitem(String)では名前を取れない模様 var styles = document.paragraphStyles; for (var i = 0; i < styles.length; i++) { if (styles[i].name == name) return styles[i]; } if (getCSVersion() > 2) { return getParagraphStyleByNameFromGroup(document.paragraphStyleGroups, name); } return null; } /** * 指定の名前の段落スタイルオブジェクトを返す(段落スタイルグループ) * @param {ParagraphStyleGroups} pgroups 段落スタイルグループ群 * @param {String} name 段落スタイル名 * @type ParagraphStyle * @return 段落スタイルオブジェクト */ function getParagraphStyleByNameFromGroup(pgroups, name) { for (var i = 0; i < pgroups.length; i++) { var styles = pgroups[i].paragraphStyles; for (var i2 = 0; i2 < styles.length; i2++) { if (styles[i2].name == name) return styles[i2]; } return getParagraphStyleByNameFromGroup(pgroups[i].paragraphStyleGroups, name); } return null; } /** * 指定の名前のオブジェクトスタイルオブジェクトを返す * @param {Document} document ドキュメントオブジェクト * @param {String} name オブジェクトスタイル名 * @type ObjectStyle * @return オブジェクトスタイルオブジェクト */ function getObjectStyleByName(document, name) { // XXX: CS2ではitem(String)では名前を取れない模様 var styles = document.objectStyles; for (var i = 0; i < styles.length; i++) { if (styles[i].name == name) return styles[i]; } if (getCSVersion() > 2) { return getObjectStyleByNameFromGroup(document.objectStyleGroups, name); } return null; } /** * 指定の名前のオブジェクトスタイルオブジェクトを返す(オブジェクトスタイルグループ) * @param {ObjectStyleGroups} ogroups オブジェクトスタイルグループ群 * @param {String} name オブジェクトスタイル名 * @type ObjectStyle * @return オブジェクトスタイルオブジェクト */ function getObjectStyleByNameFromGroup(ogroups, name) { for (var i = 0; i < ogroups.length; i++) { var styles = ogroups[i].objectStyles; for (var i2 = 0; i2 < styles.length; i2++) { if (styles[i2].name == name) return styles[i2]; } return getObjectStyleByNameFromGroup(ogroups[i].objectStyleGroups, name); } return null; } /** * 指定の名前の表スタイルオブジェクトを返す * @param {Document} document ドキュメントオブジェクト * @param {String} name 表スタイル名 * @type TableStyle * @return 表スタイルオブジェクト */ function getTableStyleByName(document, name) { var styles = document.tableStyles; for (var i = 0; i < styles.length; i++) { if (styles[i].name == name) return styles[i]; } if (getCSVersion() > 2) { return getTableStyleByNameFromGroup(document.tableStyleGroups, name); } return null; } /** * 指定の名前の表スタイルオブジェクトを返す(表スタイルグループ) * @param {TableStyleGroups} tgroups 表スタイルグループ群 * @param {String} name 表スタイル名 * @type TableStyle * @return 表スタイルオブジェクト */ function getTableStyleByNameFromGroup(tgroups, name) { for (var i = 0; i < tgroups.length; i++) { var styles = tgroups[i].tableStyles; for (var i2 = 0; i2 < styles.length; i2++) { if (styles[i2].name == name) return styles[i2]; } return getTableStyleByNameFromGroup(tgroups[i].tableStyleGroups, name); } return null; } /** * 指定の名前のセルスタイルオブジェクトを返す * @param {Document} document ドキュメントオブジェクト * @param {String} name セルスタイル名 * @type CellStyle * @return セルスタイルオブジェクト */ function getCellStyleByName(document, name) { var styles = document.cellStyles; for (var i = 0; i < styles.length; i++) { if (styles[i].name == name) return styles[i]; } if (getCSVersion() > 2) { return getCellStyleByNameFromGroup(document.cellStyleGroups, name); } return null; } /** * 指定の名前のセルスタイルオブジェクトを返す(セルスタイルグループ) * @param {CellStyleGroups} egroups セルスタイルグループ群 * @param {String} name セルスタイル名 * @type CellStyle * @return セルスタイルオブジェクト */ function getCellStyleByNameFromGroup(egroups, name) { for (var i = 0; i < egroups.length; i++) { var styles = egroups[i].cellStyles; for (var i2 = 0; i2 < styles.length; i2++) { if (styles[i2].name == name) return styles[i2]; } return getCellStyleByNameFromGroup(egroups[i].cellStyleGroups, name); } return null; } /** * 文字スタイルのハッシュリストを返す * @param {Document} document ドキュメントオブジェクト * @type CharacterStyle[] * @return スタイル名をキー、文字スタイルオブジェクトを値とするハッシュ */ function getCharacterStyles(document) { var styles = new Array(); for (var i = 0; i < document.characterStyles.length; i++) { styles[document.characterStyles[i].name] = document.characterStyles[i]; } return styles; } /** * 段落スタイルのハッシュリストを返す * @param {Document} document ドキュメントオブジェクト * @type ParagraphStyle[] * @return スタイル名をキー、段落スタイルオブジェクトを値とするハッシュ */ function getParagraphStyles(document) { var styles = new Array(); for (var i = 0; i < document.paragraphStyles.length; i++) { styles[document.paragraphStyles[i].name] = document.paragraphStyles[i]; } return styles; } /** * オブジェクトスタイルのハッシュリストを返す * @param {Document} document ドキュメントオブジェクト * @type ObjectStyle[] * @return スタイル名をキー、オブジェクトスタイルオブジェクトを値とするハッシュ */ function getObjectStyles(document) { var styles = new Array(); for (var i = 0; i < document.objectStyles.length; i++) { styles[document.objectStyles[i].name] = document.objectStyles[i]; } return styles; } /** * 表スタイルのハッシュリストを返す * @param {Document} document ドキュメントオブジェクト * @type TableStyle[] * @return スタイル名をキー、表スタイルオブジェクトを値とするハッシュ */ function getTableStyles(document) { var styles = new Array(); for (var i = 0; i < document.tableStyles.length; i++) { styles[document.tableStyles[i].name] = document.tableStyles[i]; } return styles; } /** * セルスタイルのハッシュリストを返す * @param {Document} document ドキュメントオブジェクト * @type CellStyle[] * @return スタイル名をキー、セルスタイルオブジェクトを値とするハッシュ */ function getCellStyles(document) { var styles = new Array(); for (var i = 0; i < document.cellStyles.length; i++) { styles[document.cellStyles[i].name] = document.cellStyles[i]; } return styles; } /** * ページから指定の段落スタイルを検索し、コンテンツを返す * @param {Page} page ページオブジェクト * @param {String[]} pnames 段落スタイル名 * @param {String} type 検索タイプ("bycontent"=完全一致による文字列取得、"byregexp"=正規表現一致による文字列取得、"byraw"=完全一致による段落オブジェクトの取得) * @type Object[] * @return オブジェクト(StringまたはParagraph)の配列 */ function findContentFromPageByStyles(page, pnames, type) { var carray = new Array(); var pi = page.pageItems; if (pi.length > 0) { for (var i = 0; i < pi.length; i++) { carray = carray.concat(findContentFromObjectByStyles(pi[i], pnames, type)); } } carray = carray.concat(findContentFromObjectByStyles(page, pnames, type)); return carray; } /** * オブジェクトから指定の段落スタイルを検索し、コンテンツを返す * @param {Object} obj オブジェクト(通常はPageなどのTextFrameオブジェクトを含むもの) * @param {String[]} pnames 段落スタイル名 * @param {String} type 検索タイプ("bycontent"=完全一致による文字列取得、"byregexp"=正規表現一致による文字列取得、"byraw"=完全一致による段落オブジェクトの取得) * @type Object[] * @return オブジェクト(StringまたはParagraph)の配列 */ function findContentFromObjectByStyles(obj, pnames, type) { var carray = new Array(); var tfs = obj.textFrames; if (tfs.length == 0) return carray; for (var i = 0; i < tfs.length; i++) { var paras = tfs[i].paragraphs; for (var i2 = 0; i2 < paras.length; i2++) { try { var item = paras[i2].appliedParagraphStyle.name; for (var i3 = 0; i3 < pnames.length; i3++) { switch(type) { case "bycontents", "bycontent": if (item == pnames[i3]) carray.push(paras[i2].contents.replace("\n", "")); break; case "byregexp": if (item.match(new RegExp(pnames[i3]))) carray.push(paras[i2].contents.replace("\n", "")); break; case "byraw": if (item == pnames[i3]) carray.push(paras[i2]); } } } catch (e) { } // XXX: paragraphsは1を返すが、実際はコンテンツがないことがある } } return carray; } /** * グループオブジェクトから指定の文字列を検索し、テキストフレームの配列を返す * @param {Object} obj オブジェクト(通常はPageなどのTextFrameオブジェクトを含むもの) * @param {String} search 検索文字列 * @type TextFrame[] * @return 指定文字列を含むテキストフレームオブジェクト */ function findStringFromObjectWithGroup(obj, search) { var tfsresult = new Array(); var tmp = findStringFromObject(obj, search); if (tmp.length > 0) tfsresult = tfsresult.concat(tmp); groups = obj.groups; for (var i = 0; i < groups.length; i++) { var tmp = findStringFromObjectWithGroup(groups[i], search); if (tmp.length > 0) tfsresult = tfsresult.concat(tmp); } return tfsresult; } /** * オブジェクトから指定の文字列を検索し、テキストフレームの配列を返す * @param {Object} obj オブジェクト(通常はPageなどのTextFrameオブジェクトを含むもの) * @param {String} search 検索文字列 * @type TextFrame[] * @return 指定文字列を含むテキストフレームオブジェクト */ function findStringFromObject(obj, search) { var tfsresult = new Array(); var tfs = obj.textFrames; for (var i = 0; i < tfs.length; i++) { if (tfs[i].contents == search) tfsresult.push(tfs[i]); } return tfsresult; } /** * スプレッドから指定の文字列を検索し、スプレッドの配列を返す * @param {Object} spreads オブジェクト(通常はSpreadなどのTextFrameオブジェクトを含むもの) * @param {String} search 検索文字列 * @param {String} type 検索タイプ(bycontent=完全一致による文字列取得、byregexp=正規表現一致による文字列取得) * @type Object[] * @return 指定文字列のあるテキストフレームを含むオブジェクト */ function findMasterSpread(spreads, search, type) { var sarray = new Array(); for (var i = 0; i < spreads.length; i++) { switch(type) { case "bycontents", "bycontent": var tfs = findStringFromObject(spreads[i], search); if (tfs.length > 0) sarray.push(spreads[i]); break; case "byregexp": if (spreads[i].name.match(new RegExp(search))) sarray.push(spreads[i]); break; } } return sarray; } /** * 指定のラベルを持つグループを削除する * @param {Document} document ドキュメントオブジェクト * @param {String} name ラベル名 * @type Nothing */ function removeGroupObjectByLabel(document, name) { var g = document.groups; for (var i = 0; i < g.length; i++) { if (g[i].label == name) g[i].remove(); } } /** * オブジェクトをコピーして指定の位置に配置する * @param {Document} document ドキュメントオブジェクト * @param {Page} page ページオブジェクト * @param {Object} obj コピー元オブジェクト * @param {Long[4]} unit 配置座標(mm、常にページ左上が0x0とする) * @type Object * @return コピーしたオブジェクト */ function locateObject(document, page, obj, unit) { var orgorigin = document.viewPreferences.rulerOrigin; document.viewPreferences.rulerOrigin = RulerOrigin.pageOrigin; var backunit = toMmMode(document); var newobj = obj.duplicate(); newobj.move(page); newobj.geometricBounds = unit; document.viewPreferences.rulerOrigin = orgorigin; revertMmMode(document, backunit); return newobj; } /** * XML要素のストーリーオブジェクト上の終端オフセット値を返す * @param {XMLElement|XMLItem} element XML要素またはXMLノード * @type Long * @return 終端オフセット値(CS3の場合にはinsertionPoint) */ function getEndStoryPoint(element) { var nextitem = element.parent.xmlItems.nextItem(element); var endpoint = null; if (nextitem == null) { if (getCSVersion() == 2) { endpoint = element.parentStory.length - 1; // 弟要素が見つからなければストーリーの終端 } else { // CS3 endpoint = element.parentStory.insertionPoints[element.parentStory.length - 1]; } } else { var nextelement = element.parent.xmlElements.itemByID(nextitem.id); var nextinstruction = element.parent.xmlInstructions.itemByID(nextitem.id); if (nextelement != null) { if (getCSVersion() == 2) { endpoint = nextelement.storyOffset - 1; } else { // CS3 try { endpoint = nextelement.parentStory.characters[nextelement.storyOffset.index - 1].insertionPoints[0]; } catch (e) { if (nextinstruction != null) { endpoint = nextinstruction.parent.characters[nextinstruction.storyOffset.index - 1].insertionPoints[0]; } } } } else if (nextinstruction != null) { if (getCSVersion() == 2) { endpoint = nextinstruction.storyOffset - 1; } else { // CS3 endpoint = nextinstruction.parent.characters[nextinstruction.storyOffset.index - 1].insertionPoints[0]; } } } return endpoint; } /** * XML要素のストーリーオブジェクト上の終端オフセット値を返す。終端オフセットの文字が65279(タグ等)であれば、さらに前にさかのぼる * @param {XMLElement|XMLItem} element XML要素またはXMLノード * @type insertionPoint * @return 終端オフセットポイント */ function getEndStoryPoint2(element) { var nextitem = element.parent.xmlItems.nextItem(element); var endpoint = null; if (nextitem == null) { // 見つからなければ最後の位置 endpoint = element.parentStory.insertionPoints[element.parentStory.length - 1]; } else { var nextelement = element.parent.xmlElements.itemByID(nextitem.id); var nextinstruction = element.parent.xmlInstructions.itemByID(nextitem.id); if (nextelement != null) { try { endpoint = nextelement.parentStory.characters[nextelement.storyOffset.index - 1].insertionPoints[0]; } catch (e) { if (nextinstruction != null) { endpoint = nextinstruction.parent.characters[nextinstruction.storyOffset.index - 1].insertionPoints[0]; } } } else if (nextinstruction != null) { endpoint = nextinstruction.parent.characters[nextinstruction.storyOffset.index - 1].insertionPoints[0]; } while (endpoint.index > element.storyOffset.index + 1 && element.parentStory.characters[endpoint.index].contents.charCodeAt(0) == 65279) { endpoint = element.parentStory.characters[endpoint.index - 1].insertionPoints[0]; } } return endpoint; } /** * XML要素のストーリーオブジェクト上の終端オフセット値を返す。終端オフセットの文字が65279(タグ等)であれば、さらに後ろを探す * @param {XMLElement|XMLItem} element XML要素またはXMLノード * @type insertionPoint * @return 終端オフセットポイント */ function getEndStoryPoint3(element) { // if (element.characters.length == 0) return element.parentStory.characters[index + 1].insertionPoints[0]; var index = element.storyOffset.index + element.characters.length - 1; try { while (element.parentStory.characters[index].contents.charCodeAt(0) == 65279) { index++; } } catch(e) {} // SpecialCharactersのときにはcharCodeAtがとれない if (index > element.parentStory.characters.length - 1) index = element.parentStory.characters.length - 1; return element.parentStory.characters[index].insertionPoints[0]; } /** * XML要素のストーリーオブジェクト上の終端オフセット値を返す。終端オフセットの文字が65279(タグ等)であれば、さらに前にさかのぼる * @param {XMLElement|XMLItem} element XML要素またはXMLノード * @type insertionPoint * @return 終端オフセットポイント */ function getEndStoryPoint4(element) { var index = element.characters.length - 1; try { while (element.characters[index].contents.charCodeAt(0) == 65279) { index--; } } catch(e) {} // SpecialCharactersのときにはcharCodeAtがとれない return element.characters[index].insertionPoints[0]; } /** * 最初に登場するコメントをメタ情報として取得し、指定属性名の値を返す * @param {Document} document ドキュメントオブジェクト * @param {String} key 属性名 * @type String * @return 値 */ function getMetaInfo(document, key) { if (document.xmlItems[0].xmlComments.length > 0) { var s = document.xmlItems[0].xmlComments[0].value; var sa = s.replace(/^ \[Comment\]\s*/, "").split(/\s*,\s*/); for (var i = 0; i < sa.length; i++) { var sv = sa[i].split("=", 2); if (sv[0] == key) { return sv[1]; } } } return null; } /** * ポイント値をmm値に変換して返す * @param {Float} pt ポイント値 * @type Float * @return mm値 */ function pttomm(pt) { return pt * 0.351; } /** * ダイアログ表示モードの有無を指定する * @param {Boolean} flag フラグ。trueのときはすべてのダイアログを表示し、falseのときはすべて抑制する。スクリプト終了後には必ずtrueで戻すこと * @type Nothing */ function showInteraction(flag) { if (flag == true) { app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL; } else { app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT; } } /** * ページ中のマスターページアイテムのうち、指定ラベルを持つオブジェクトをオーバライドする * @param {Page} page 対象ページオブジェクト * @param {String} items[] ラベル名の配列 * @type Nothing */ function overridePageItems(page, items) { for (var i = page.pageItems.length - 1; i >= 0; i--) { var item = page.pageItems[i]; for (var i2 = 0; i2 < items.length; i2++) { if (items[i2] == item.label) { item.removeOverride(); } } } for (var i = page.masterPageItems.length - 1; i >= 0; i--) { var item = page.masterPageItems[i]; for (var i2 = 0; i2 < items.length; i2++) { if (items[i2] == item.label) { item.override(page); } } } } /** * ページまたはマスターページ中のページアイテムのうち、指定ラベルを持つオブジェクトを返す。本来はitemメソッドで取れるはずなのだが、CSのバグがある模様 * @param {Page} page 対象ページオブジェクト。MasterSpreadでもよい * @param {String} item 探索ラベル名 * @type PageItem * @return ページアイテム */ function getPageItem(page, label) { for (var i = 0; i < page.pageItems.length; i++) { if (page.pageItems[i].label == label) { return page.pageItems[i]; } } return null; } /** * ドキュメントのルート要素の属性値を取得する * @param {Document} document ドキュメントオブジェクト * @param {String} attrname 属性名 * @type String * @return 属性値またはnull */ function getDocAttr(document, attrname) { try { return document.xmlElements[0].xmlAttributes.item(attrname).value; } catch (e) { return null; } } /** * ~/.hwj-Scripts内設定ファイルのオブジェクトを取得する * @param {String} name 設定ファイル名 * @type File * @return オブジェクトまたはnull */ function getHwjStateFileObj(name) { if (!Folder("~/.hwj-Scripts").exists) { if (!Folder("~/.hwj-Scripts").create()) { alert("設定フォルダ ~/.hwj-Scripts を作成できませんでした。"); return null; } } var fObj = new File("~/.hwj-Scripts/" + name); fObj.encoding = "UTF8"; fObj.lineFeed = "Unix"; return fObj; } /** * ファイルオブジェクトから各行を配列で返し、オブジェクトを閉じる * @param {String} fObj ファイルオブジェクト * @type String[] * @return 文字列配列またはnull */ function readHwjStateFile(fObj) { var array = []; if (fObj.exists) { if (fObj.open("r")) { while (!fObj.eof) { array.push(fObj.readln()); } } } fObj.close(); if (array.length > 0) return array; return null; } /** * ファイルオブジェクトから各行を配列で返し、オブジェクトを閉じる * @param {String} fObj ファイルオブジェクト * @type boolean * @return 成功可否 */ function writeHwjStateFile(fObj, array) { if (fObj.open("w")) { for (var i = 0; i < array.length; i++) { fObj.writeln(array[i]); } } else { fObj.close(); return null; } fObj.close(); return true; }