/** * @fileoverview XPathにマッチする要素がページをまたいでいる場合、右下/左上にアイコンを置く * @author Kenshi Muto <kmuto@debian.org> * @requires glue code.jsx * @requires libCommon.jsx * @requires libGetBoundsOfPage.jsx * @version 3 */ /* Copyright: 2009-2012 Kenshi Muto ---------------------------------------------------------------------- ソフトウェア使用許諾同意書 本ソフトウェアの利用・変更・再配布にあたっては、下記の使用許諾同意書に 同意する必要があります。 1. 本使用許諾同意書における「ソフトウェア」とは、機械可読の資料 (ライブ ラリ、スクリプト、ソースファイル、データファイル)、実行形式、および 文書を意味します。 2. 本ソフトウェアの使用許諾同意書に同意する限りにおいて、使用者は 本ソフトウェアを自由に利用、変更することができます。 3. 本ソフトウェアに変更を加えない限りにおいて、使用者は本ソフトウェアを 自由にコピー、再配布することができます。 4. 本ソフトウェアは無保証です。作者およびそれに関連する組織、配布者は、 本ソフトウェアの使用に起因する一切の直接損害、間接損害、偶発的損害、 特別損害、懲戒的損害、派生的損害について何らの責任・保証も負いません。 5. 本ソフトウェアを変更した上で再配布するときには、下記の事項すべてに 従わなければなりません。 - 使用許諾同意書の内容に変更を加えてはなりません。技術上の理由で 文字エンコーディングの変換を行うことは許可しますが、その使用者が 特殊な技術的措置なしに可読な形でなければなりません。 - 技術上の理由でバイナリ化・難読化を行う場合も、変更箇所を含めた ソフトウェアを、その使用者が可読可能な形式の形で同一のメディアで 提供しなければなりません。本使用許諾同意書の2条および3条により、 使用者が可読形式の該当ソフトウェアを変更、コピー、再配布することを 妨げてはなりません。 - ソフトウェア構成物の所定の作者名の欄に、変更者のクレジット (個人名、企業名、所属、連絡先など)を「追加」しなければなりません。 6. 本ソフトウェアを変更した上で再配布するときには、変更理由および その内容を明記することが推奨されます。 7. 使用者がソフトウェアに適用可能な特許に対して特許侵害にかかわる何らか の行動を開始した時点で、この使用許諾同意書は自動的に終了し、以降 使用者はこの使用許諾書によって与えられた一切の権利を放棄するものと します。 著作権所有者 Copyright (C) 2008-2012 Kenshi Muto. All rights reserved. 使用許諾同意書バージョン1.0 著作権所有者による書面での事前の許可がない限り、この使用許諾同意書 に変更を加えてはなりません。 ---------------------------------------------------------------------- */ #include "../libs/glue code.jsx" #include "../libs/libCommon.jsx" #include "../libs/libGetBoundsOfPage.jsx" var _myDocument; var _obj; /** * XPathに基づいてアイコン配置を実行する * @param {Document} document ドキュメントオブジェクト * @param {String} xpath 対象XPath * @param {Object} obj パラメータ引き渡しオブジェクト * @param {String} obj.layername 配置レイヤー(nullのときは現在のレイヤー) * @param {File} obj.nextfile 前ページ側に使うアイコンファイル。nullの場合は配置しない * @param {ObjectStyle} obj.nextostyle 前ページ側に使うアイコンまたはテキストのオブジェクトスタイル * @param {Float} obj.nextoffset[4] 前ページ側アイコンまたはテキスト配置(右下)からのオフセット * @param {Number} obj.nextframeup 前ページ側テキストフレームの上げ幅 * @param {File} obj.tofile 次ページ側に使うアイコンファイル。nullの場合は配置しない * @param {ObjectStyle} obj.toostyle 次ページ側に使うアイコンまたはテキストのオブジェクトスタイル * @param {Float} obj.tooffset[4] 次ページ側アイコンまたはテキスト配置(左上)からのオフセット * @param {boolean} obj.spread 見開きの変更時のみにアイコンを配置するかどうか(true:見開きのみ) * @param {String} obj.captionelement キャプション抜き出し時に使う要素名 * @param {String} obj.captionsplit 抜き出したキャプションから利用する部分の終端文字列 * @param {String} obj.nextcaptionprefix 前ページ側テキストの前文字列 * @param {String} obj.nextcaptionpostfix 前ページ側テキストの後文字列 * @param {String} obj.nexttext 前ページ側テキスト。AUTOの場合はキャプション文字列を切り出したものが入る。nullの場合は配置しない * @param {String} obj.tocaptionprefix 後ページ側テキストの前文字列 * @param {String} obj.tocaptionpostfix 後ページ側テキストの後文字列 * @param {String} obj.totext 後ページ側テキスト。AUTOの場合はキャプション文字列を切り出したものが入る。nullの場合は配置しない * @param {Number} obj.toframedown 後ページ側テキストフレームの下げ幅 * @type Nothing */ function processXMLforNextToIcon(document, xpath, obj) { _myDocument = document; _obj = obj; var myRuleSet = new Array(new ProcessNextToIconSubset(xpath)); __processRuleSet(_myDocument.xmlElements.item(0), myRuleSet); } /** * XPathに基づいてアイコン配置を実行するための内部XMLルールセット * @param {String} xpath 対象XPath * @type Nothing */ function ProcessNextToIconSubset(xpath) { this.name = "ProcessSubset"; this.xpath = xpath; this.apply = function(myElement, myRuleProcessor) { var startpoint = myElement.storyOffset; var endpoint = getEndStoryPoint2(myElement); var startpage = startpoint.parentTextFrames[0].parent; var endpage = endpoint.parentTextFrames[0].parent; if (_obj.captionelement != null) { var x = myElement.xmlElements; if (x.length > 0 && x[0] != null && x[0].markupTag.name == _obj.captionelement) { _obj.captiontext = x[0].contents.replace(/(\n|\r)/, ""); } } if (startpage.documentOffset != endpage.documentOffset) { for (var i = startpage.documentOffset; i < endpage.documentOffset; i++) { var nextbounds = getBoundsOfPage(_myDocument, _myDocument.pages[i]); var tobounds = getBoundsOfPage(_myDocument, _myDocument.pages[i + 1]); if (_obj.spread != true || _myDocument.pages[i].side == PageSideOptions.RIGHT_HAND) { // スプレッド属性が付いていないか右ページの場合にはアイコンを付ける if (_obj.nextfile != null) placeNextToIcon(0, _myDocument.pages[i], _obj.nextfile, _obj.nextostyle, _obj.layername, nextbounds, _obj.nextoffset); if (_obj.nexttext != null) placeNextToText(0, _myDocument.pages[i], _obj, nextbounds); if (_obj.nextframeup != null) { var tf = _myDocument.pages[i].textFrames.item("main-content"); if (tf != null) { var backunit = toMmMode(_myDocument); var unit = tf.geometricBounds; unit[2] = unit[2] - _obj.nextframeup; tf.geometricBounds = unit; revertMmMode(_myDocument, backunit); } } if (_obj.tofile != null) placeNextToIcon(1, _myDocument.pages[i + 1], _obj.tofile, _obj.toostyle, _obj.layername, tobounds, _obj.tooffset); if (_obj.totext != null) placeNextToText(1, _myDocument.pages[i + 1], _obj, tobounds); if (_obj.toframedown != null) { var tf = _myDocument.pages[i + 1].textFrames.item("main-content"); if (tf != null) { var backunit = toMmMode(_myDocument); var unit = tf.geometricBounds; unit[0] = unit[0] + _obj.toframedown; tf.geometricBounds = unit; revertMmMode(_myDocument, backunit); } } } } } return true; } } /** * 指定位置にアイコンを配置する * @param {Integer} place 配置位置。0:右下、1:左上 * @param {Page} page ドキュメントページオブジェクト * @param {File} file 配置画像ファイル * @param {ObjectStyle} ostyle 画像のオブジェクトスタイル * @param {String} layername レイヤー名 * @param {Float} bounds[4] ページのサイズ * @param {Float} offset[4] アイコン配置からのオフセット * @type Nothing */ function placeNextToIcon(place, page, file, ostyle, layername, bounds, offset) { if (ostyle == null || file == null) return; var rect; if (offset == null) { offset = [0, 0, 0, 0]; } if (layername != null) { var layer = page.parent.parent.layers.item(layername); if (layer == null) { layer = page.parent.parent.layers.add(); layer.label = layername; layer.name = layername; } rect = page.rectangles.add({itemLayer: layer}); } else { rect = page.rectangles.add(); } rect.contentType = ContentType.graphicType; rect.appliedObjectStyle = ostyle; rect.geometricBounds = bounds; rect.place(file); rect.fit(FitOptions.FRAME_TO_CONTENT); var unit = rect.geometricBounds; var backunit = toMmMode(_myDocument); switch (place) { case 0: // 右下 rect.geometricBounds = [bounds[2] + offset[0], bounds[3] - (unit[3] - unit[1]) + offset[1], bounds[2] + (unit[2] - unit[0]) + offset[2], bounds[3] + offset[3]]; break; case 1: // 左上 rect.geometricBounds = [bounds[0] - (unit[2] - unit[0]) + offset[0], bounds[1] + offset[1], bounds[0] + offset[2], bounds[1] + (unit[3] - unit[1]) + offset[3]]; break; } rect.fit(FitOptions.CONTENT_TO_FRAME); revertMmMode(_myDocument, backunit); } /** * 指定位置にテキストを配置する * @param {Integer} place 配置位置。0:右下、1:左上 * @param {Page} page ドキュメントページオブジェクト * @param {Object} obj パラメータオブジェクト * @param {String} obj.captionelement キャプション抜き出し時に使う要素名 * @param {String} obj.captionsplit 抜き出したキャプションから利用する部分の終端文字列 * @param {String} obj.nextcaptionprefix 前ページ側テキストの前文字列 * @param {String} obj.nextcaptionpostfix 前ページ側テキストの後文字列 * @param {String} obj.nexttext 前ページ側テキスト。AUTOの場合はキャプション文字列を切り出したものが入る。nullの場合は配置しない * @param {String} obj.tocaptionprefix 後ページ側テキストの前文字列 * @param {String} obj.tocaptionpostfix 後ページ側テキストの後文字列 * @param {String} obj.totext 後ページ側テキスト。AUTOの場合はキャプション文字列を切り出したものが入る。nullの場合は配置しない * @param {Float} bounds[4] ページのサイズ * @param {Float} offset[4] アイコン配置からのオフセット * @type Nothing */ function placeNextToText(place, page, obj, bounds) { var rect; var offset = [0, 0, 0, 0]; var ostyle = null; var content = ""; switch (place) { case 0: if (obj.nexttext == "AUTO") { if (obj.captionsplit != null) { content = obj.nextcaptionprefix + obj.captiontext.split(obj.captionsplit)[0] + obj.nextcaptionpostfix; } else { content = obj.nextcaptionprefix + obj.captiontext + obj.nextcaptionpostfix; } } else { content = obj.nexttext; } if (obj.nextoffset != null) offset = obj.nextoffset; if (obj.nextostyle != null) ostyle = obj.nextostyle; break; case 1: if (obj.totext == "AUTO") { if (obj.captiontext == null) return false; if (obj.captionsplit != null) { content = obj.tocaptionprefix + obj.captiontext.split(obj.captionsplit)[0] + obj.tocaptionpostfix; } else { content = obj.tocaptionprefix + obj.captiontext + obj.tocaptionpostfix; } } else { content = obj.totext; } if (obj.tooffset != null) offset = obj.tooffset; if (obj.toostyle != null) ostyle = obj.toostyle; break; } if (obj.layername != null) { var layer = page.parent.parent.layers.item(obj.layername); if (layer == null) { layer = page.parent.parent.layers.add(); layer.label = obj.layername; layer.name = obj.layername; } rect = page.textFrames.add({itemLayer: layer}); } else { rect = page.textFrames.add(); } rect.appliedObjectStyle = ostyle; rect.geometricBounds = bounds; rect.contents = content; rect.fit(FitOptions.FRAME_TO_CONTENT); var unit = rect.geometricBounds; var backunit = toMmMode(_myDocument); switch (place) { case 0: // 右下 rect.geometricBounds = [bounds[2] + offset[0], bounds[3] - (unit[3] - unit[1]) + offset[1], bounds[2] + (unit[2] - unit[0]) + offset[2], bounds[3] + offset[3]]; break; case 1: // 左上 rect.geometricBounds = [bounds[0] - (unit[2] - unit[0]) + offset[0], bounds[1] + offset[1], bounds[0] + offset[2], bounds[1] + (unit[3] - unit[1]) + offset[3]]; break; } rect.fit(FitOptions.CONTENT_TO_FRAME); revertMmMode(_myDocument, backunit); }