/** * @fileoverview 指定のXML要素を子要素を含めて側注テキストフレーム化する * @author Kenshi Muto <kmuto@debian.org> * @requires libCommon.jsx * @requires libGetBoundsOfPage.jsx * @requires libGetFrameIDs.jsx * @requires glue code.jsx */ /* Copyright: 2010 Kenshi Muto ---------------------------------------------------------------------- ソフトウェア使用許諾同意書 本ソフトウェアの利用・変更・再配布にあたっては、下記の使用許諾同意書に 同意する必要があります。 1. 本使用許諾同意書における「ソフトウェア」とは、機械可読の資料 (ライブ ラリ、スクリプト、ソースファイル、データファイル)、実行形式、および 文書を意味します。 2. 本ソフトウェアの使用許諾同意書に同意する限りにおいて、使用者は 本ソフトウェアを自由に利用、変更することができます。 3. 本ソフトウェアに変更を加えない限りにおいて、使用者は本ソフトウェアを 自由にコピー、再配布することができます。 4. 本ソフトウェアは無保証です。作者およびそれに関連する組織、配布者は、 本ソフトウェアの使用に起因する一切の直接損害、間接損害、偶発的損害、 特別損害、懲戒的損害、派生的損害について何らの責任・保証も負いません。 5. 本ソフトウェアを変更した上で再配布するときには、下記の事項すべてに 従わなければなりません。 - 使用許諾同意書の内容に変更を加えてはなりません。技術上の理由で 文字エンコーディングの変換を行うことは許可しますが、その使用者が 特殊な技術的措置なしに可読な形でなければなりません。 - 技術上の理由でバイナリ化・難読化を行う場合も、変更箇所を含めた ソフトウェアを、その使用者が可読可能な形式の形で同一のメディアで 提供しなければなりません。本使用許諾同意書の2条および3条により、 使用者が可読形式の該当ソフトウェアを変更、コピー、再配布することを 妨げてはなりません。 - ソフトウェア構成物の所定の作者名の欄に、変更者のクレジット (個人名、企業名、所属、連絡先など)を「追加」しなければなりません。 6. 本ソフトウェアを変更した上で再配布するときには、変更理由および その内容を明記することが推奨されます。 7. 使用者がソフトウェアに適用可能な特許に対して特許侵害にかかわる何らか の行動を開始した時点で、この使用許諾同意書は自動的に終了し、以降 使用者はこの使用許諾書によって与えられた一切の権利を放棄するものと します。 著作権所有者 Copyright (C) 2008-2010 Kenshi Muto. All rights reserved. 使用許諾同意書バージョン1.0 著作権所有者による書面での事前の許可がない限り、この使用許諾同意書 に変更を加えてはなりません。 ---------------------------------------------------------------------- */ #include "../libs/libCommon.jsx" #include "../libs/libGetBoundsOfPage.jsx" #include "../libs/libGetFrameIDs.jsx" #include "../libs/glue code.jsx" var _sidenotearray = new Array(); // XXX: グローバル変数 /** * 指定のXML要素を探して、新規作成したテキストフレームに移動する * @param {Object} obj パラメータオブジェクト * @param {Document} obj.document ドキュメントオブジェクト * @param {String} obj.layername 構成レイヤー名 * @param {String} obj.footnotetag 側注化XML要素名 * @param {ObjectStyle} obj.ostyle 側注テキストフレームのオブジェクトスタイル * @param {String} obj.reftag 側注への参照XML要素名 * @param {Float} obj.width テキストフレームの横幅 * @return Nothing */ function processXMLforSidenote2(obj) { var myRuleSet = new Array(new processSideNote(obj)); __processRuleSet(obj.document.xmlElements.item(0), myRuleSet); redrawProcessXMLforSidenote2(obj); } /** * processXMLforSidenote2から呼び出され、moveFootnoteToSideを呼び出すコールバック * @param {Object} obj パラメータオブジェクト * @return Nothing */ function processSideNote(obj) { this.name = "ProcessSubset"; this.xpath = "//" + obj.footnotetag; this.apply = function(myElement, myRuleProcessor) { moveFootnoteToSide(myElement, obj); } } /** * processSideNoteから呼び出され側傍注を最初のページにとりあえず配置する * @param {XMLElement} element 側注のXMLオブジェクト * @param {Object} obj パラメータオブジェクト * @param {Document} obj.document ドキュメントオブジェクト * @param {String} obj.layername 構成レイヤー名 * @param {ObjectStyle} obj.ostyle 側注テキストフレームのオブジェクトスタイル * @param {Float} obj.width テキストフレームの横幅 * @return Nothing */ function moveFootnoteToSide(element, obj) { var tf; var page = obj.document.pages[0]; if (obj.layername != null) { var layer = obj.document.layers.itemByRange(obj.layername, obj.layername); if (layer == null) { layer = obj.document.layers.add(); layer.label = obj.layername; layer.name = obj.layername; } tf = page.textFrames.add({itemLayer: layer}); } else { tf = page.textFrames.add(); } tf.contentType = ContentType.textType; tf.appliedObjectStyle = obj.ostyle; tf.geometricBounds = [ 0, 0, obj.document.documentPreferences.pageHeight, obj.width ]; tf.placeXML(element); tf.fit(FitOptions.frameToContent); tf.label = "tmp-fn-" + (element.xmlAttributes.item("id").value); } /** * 指定のXML要素を探して、側注の位置を合わせる * @param {Object} obj パラメータオブジェクト * @param {Document} obj.document ドキュメントオブジェクト * @param {String} obj.reftag 側注への参照XML要素名 * @param {Float} obj.xmargin 小口からの相対位置 * @param {Float} obj.ymargin 各フレーム間の最低間隔 * @param {Float} obj.yoffset 参照ベースラインからの側注の縦方向オフセット * @return Nothing */ function redrawProcessXMLforSidenote2(obj) { var myRuleSet = new Array(new processRedrawSideNote(obj)); __processRuleSet(obj.document.xmlElements.item(0), myRuleSet); } /** * redrawProcessXMLforSidenote2から呼び出され、placeSideNoteを呼び出すコールバック * @param {Object} obj パラメータオブジェクト * @return Nothing */ function processRedrawSideNote(obj) { this.name = "ProcessSubset"; this.xpath = "//" + obj.reftag; this.apply = function(myElement, myRuleProcessor) { placeSideNote(myElement, obj); } } /** * 指定のXML要素を探して、側注の位置を合わせる * @param {XMLElement} element 側注のXMLオブジェクト * @param {Object} obj パラメータオブジェクト * @param {Document} obj.document ドキュメントオブジェクト * @param {Float} obj.xmargin 小口からの相対位置 * @param {Float} obj.ymargin 各フレーム間の最低間隔 * @param {Float} obj.yoffset 参照ベースラインからの側注の縦方向オフセット * @return Nothing */ function placeSideNote(element, obj) { var attr = element.xmlAttributes.itemByRange("idref", "idref"); if (attr != null) { var backunit = toMmMode(obj.document); var backruler = obj.document.viewPreferences.rulerOrigin; obj.document.viewPreferences.rulerOrigin = RulerOrigin.pageOrigin; var page = element.storyOffset.parentTextFrames[0].parent; var tf = obj.document.textFrames.item("tmp-fn-" + attr.value); var page2 = tf.parent; var unit = getBoundsOfPage(obj.document, page); if (page.documentOffset != page2.documentOffset) { // ページが変わった tf.move(page); } var y0; y0 = element.storyOffset.baseline + obj.yoffset; var unit2 = tf.geometricBounds; var width = unit2[3] - unit2[1]; var height = unit2[2] - unit2[0]; if (page.side == PageSideOptions.leftHand) { // 左配置 tf.geometricBounds = [ y0, obj.xmargin, y0 + height, obj.xmargin + width ]; } else { // 右 tf.geometricBounds = [ y0, obj.document.documentPreferences.pageWidth - obj.xmargin - width, y0 + height, obj.document.documentPreferences.pageWidth - obj.xmargin ]; } _sidenotearray.push([page.documentOffset, tf.id, y0, y0 + height]); handleOverwrapSidenotes(obj.document, obj.ymargin); revertMmMode(obj.document, backunit); obj.document.viewPreferences.rulerOrigin = backruler; } } /** * _sidenotearray配列の情報を基に、側注フレームの重なりを調整する * @param {Document} document ドキュメントオブジェクト * @param {Float} ymargin 各フレーム間の最低間隔 * @type Nothing */ function handleOverwrapSidenotes(document, ymargin) { var unit = getBoundsOfPage(document, document.pages[_sidenotearray[_sidenotearray.length - 1][0] - 1]); if (_sidenotearray.length > 1 && _sidenotearray[_sidenotearray.length - 2][0] == _sidenotearray[_sidenotearray.length - 1][0] // ページが同じ && _sidenotearray[_sidenotearray.length - 2][3] + ymargin > _sidenotearray[_sidenotearray.length - 1][2]) { // 前の側注がかぶさっている var tf = document.textFrames.itemByID(Number(_sidenotearray[_sidenotearray.length - 1][1])); var unit2 = tf.geometricBounds; var height = unit2[2] - unit2[0]; unit2[0] = _sidenotearray[_sidenotearray.length - 2][3] + ymargin; unit2[2] = unit2[0] + height; tf.geometricBounds = unit2; _sidenotearray[_sidenotearray.length - 1][2] = unit2[0]; _sidenotearray[_sidenotearray.length - 1][3] = unit2[2]; } if (_sidenotearray.length > 0 && _sidenotearray[_sidenotearray.length - 1][3] > unit[2]) { // 下にはみ出している var tf = document.textFrames.itemByID(Number(_sidenotearray[_sidenotearray.length - 1][1])); var unit2 = tf.geometricBounds; var height = unit2[2] - unit2[0]; unit2[0] = unit[2] - height; unit2[2] = unit2[0] + height; tf.geometricBounds = unit2; _sidenotearray[_sidenotearray.length - 1][2] = unit2[0]; _sidenotearray[_sidenotearray.length - 1][3] = unit2[2]; if (_sidenotearray.length > 1) { // 上の脚注とぶつかるかチェック var unit3 = unit2; for (var i = _sidenotearray.length - 2; i >= 0; i--) { // 再帰で前の側注を上にシフト if (_sidenotearray[i][0] != _sidenotearray[i + 1][0] || _sidenotearray[i][3] + ymargin <= unit3[0]) break; var height = _sidenotearray[i][3] - _sidenotearray[i][2]; _sidenotearray[i][3] = unit3[0] - ymargin; _sidenotearray[i][2] = _sidenotearray[i][3] - height; var prevtf = document.textFrames.itemByID(Number(_sidenotearray[i][1])); var unit4 = prevtf.geometricBounds; prevtf.geometricBounds = [_sidenotearray[i][2], unit4[1], _sidenotearray[i][3], unit4[3]]; unit3 = prevtf.geometricBounds; if (_sidenotearray[i][2] < unit[0]) { // 上にはみ出した alert(getPagenumFromSection(document)[_sidenotearray[i][0]] + "ページ: 側注" + (i + 1) + "が版面をはみ出しました。 "); } } } } }