/** * @fileoverview 指定のXML要素を子要素を含めてコメントをテキストフレーム化し、線を引く * @author Kenshi Muto <kmuto@debian.org> * @requires libCommon.jsx * @requires libGetBoundsOfPage.jsx * @requires libGetFrameIDs.jsx */ /* Copyright: 2008 Kenshi Muto ---------------------------------------------------------------------- ソフトウェア使用許諾同意書 本ソフトウェアの利用・変更・再配布にあたっては、下記の使用許諾同意書に 同意する必要があります。 1. 本使用許諾同意書における「ソフトウェア」とは、機械可読の資料 (ライブ ラリ、スクリプト、ソースファイル、データファイル)、実行形式、および 文書を意味します。 2. 本ソフトウェアの使用許諾同意書に同意する限りにおいて、使用者は 本ソフトウェアを自由に利用、変更することができます。 3. 本ソフトウェアに変更を加えない限りにおいて、使用者は本ソフトウェアを 自由にコピー、再配布することができます。 4. 本ソフトウェアは無保証です。作者およびそれに関連する組織、配布者は、 本ソフトウェアの使用に起因する一切の直接損害、間接損害、偶発的損害、 特別損害、懲戒的損害、派生的損害について何らの責任・保証も負いません。 5. 本ソフトウェアを変更した上で再配布するときには、下記の事項すべてに 従わなければなりません。 - 使用許諾同意書の内容に変更を加えてはなりません。技術上の理由で 文字エンコーディングの変換を行うことは許可しますが、その使用者が 特殊な技術的措置なしに可読な形でなければなりません。 - 技術上の理由でバイナリ化・難読化を行う場合も、変更箇所を含めた ソフトウェアを、その使用者が可読可能な形式の形で同一のメディアで 提供しなければなりません。本使用許諾同意書の2条および3条により、 使用者が可読形式の該当ソフトウェアを変更、コピー、再配布することを 妨げてはなりません。 - ソフトウェア構成物の所定の作者名の欄に、変更者のクレジット (個人名、企業名、所属、連絡先など)を「追加」しなければなりません。 6. 本ソフトウェアを変更した上で再配布するときには、変更理由および その内容を明記することが推奨されます。 7. 使用者がソフトウェアに適用可能な特許に対して特許侵害にかかわる何らか の行動を開始した時点で、この使用許諾同意書は自動的に終了し、以降 使用者はこの使用許諾書によって与えられた一切の権利を放棄するものと します。 著作権所有者 Copyright (C) 2008 Kenshi Muto. All rights reserved. 使用許諾同意書バージョン1.0 著作権所有者による書面での事前の許可がない限り、この使用許諾同意書 に変更を加えてはなりません。 ---------------------------------------------------------------------- */ #include "../libs/libCommon.jsx" #include "../libs/libGetBoundsOfPage.jsx" #include "../libs/libGetFrameIDs.jsx" var _commentarray = new Array(); // XXX: グローバル変数 /** * 指定のXML要素を探して、新規作成したテキストフレームに移動する * @param {Document} document ドキュメントオブジェクト * @param {XMLItems} items XMLItemsオブジェクト * @param {String} layername 構成レイヤー名 * @param {String} tagname 側注化XML要素名 * @param {ObjectStyle} ostyle コメントテキストフレームのオブジェクトスタイル。コメントに使いたい段落スタイルを割り当てておくこと * @param {String} reftagname コメントへの参照XML要素名 * @param {Float} width テキストフレームの横幅 * @param {Float} xmargin 小口からの相対位置 * @param {Float} ymargin 各フレーム間の最低間隔 * @param {Float} yoffset 参照ベースラインからのコメントの縦方向オフセット * @type boolean * @return 再帰のために関数処理を継続するか(true=継続する、false=継続しない) */ function processXMLforComment(document, items, layername, tagname, ostyle, reftagname, width, xmargin, ymargin, yoffset) { if (items == null || items.length == 0) { return false; } for (var i = 0; i < items.length; i++) { if (items[i].xmlElements != null && items[i].xmlElements.length > 0) { for (var i2 = 0; i2 < items[i].xmlElements.length; i2++) { var e = items[i].xmlElements[i2]; if (e.markupTag.name == tagname) { var refe; if (e.parent.xmlElements.nextItem(e) != null && e.parent.xmlElements.nextItem(e).markupTag.name == reftagname) { if (getCSVersion() > 3) { refe = e.parent.xmlElements.nextElement(e); } else { refe = e.parent.xmlElements.nextItem(e); } } else { try { refe = items[i].parent.xmlElements.add(reftagname); } catch(e) { refe = items[i].parent.parent.xmlElements.add(reftagname); } } // refe.paragraphs[0].appliedParagraphStyle = e.paragraphs[0].appliedParagraphStyle; var attr = refe.xmlAttributes.itemByRange("idref", "idref"); try { if (attr != null) { attr.value = (_commentarray.length + 1).toString(); } else { refe.xmlAttributes.add("idref", (_commentarray.length + 1).toString()); } } catch (e) { refe.xmlAttributes.add("idref", (_commentarray.length + 1).toString()); } try { refe.move(LocationOptions.after, e); } catch(e) { } var page; if (getCSVersion() == 2) { page = e.parentStory.characters[e.storyOffset - 1].insertionPoints[0].parentTextFrames[0].parent; } else if (getCSVersion() == 3) { page = e.storyOffset.insertionPoints[0].parentTextFrames[0].parent; } else { page = e.storyOffset.insertionPoints[0].parentTextFrames[0].parentPage; } var backunit = toMmMode(document); var backruler = document.viewPreferences.rulerOrigin; document.viewPreferences.rulerOrigin = RulerOrigin.pageOrigin; var y0; if (getCSVersion() == 2) { y0 = refe.parentStory.characters[e.storyOffset - 1].insertionPoints[0].baseline + yoffset; } else { y0 = e.storyOffset.baseline + yoffset; } var tf, x0, x1, y1; if (layername != null) { var layer = e.parentStory.parent.layers.itemByRange(layername, layername); if (layer == null) { layer = document.layers.add(); layer.label = layername; layer.name = layername; layer.move(LocationOptions.atBeginning); } tf = page.textFrames.add({itemLayer: layer}); } else { tf = page.textFrames.add(); } tf.contentType = ContentType.textType; tf.appliedObjectStyle = ostyle; var unit = getBoundsOfPage(myDocument, page); if (page.side == PageSideOptions.leftHand) { // 左配置 tf.geometricBounds = [ y0, xmargin, unit[2], xmargin + width ]; } else { // 右 tf.geometricBounds = [ y0, document.documentPreferences.pageWidth - xmargin - width, unit[2], document.documentPreferences.pageWidth - xmargin ]; } tf.placeXML(e); for (var i3 = 0; i3 < tf.paragraphs.length; i3++) { tf.paragraphs[i3].appliedParagraphStyle = ostyle.appliedParagraphStyle; } tf.fit(FitOptions.frameToContent); tf.label = "tmp-com-" + (_commentarray.length + 1); if (getCSVersion() > 3) { tf.name = "tmp-com-" + (_commentarray.length + 1); } var unit2 = tf.geometricBounds; _commentarray.push([page.documentOffset, tf.id, y0, unit2[2]]); revertMmMode(document, backunit); document.viewPreferences.rulerOrigin = backruler; } } } if (getCSVersion() > 3) { processXMLforComment(document, items[i].xmlElements, layername, tagname, ostyle, reftagname, width, xmargin, ymargin, yoffset); } else { processXMLforComment(document, items[i].xmlItems, layername, tagname, ostyle, reftagname, width, xmargin, ymargin, yoffset); } } return true; } /** * 指定のXML参照要素を探して、コメントの場所を変更する * @param {Document} document ドキュメントオブジェクト * @param {XMLItems} items XMLItemsオブジェクト * @param {String} reftagname コメントへの参照XML要素名 * @param {Float} xmargin 小口からの相対位置 * @param {Float} ymargin 各フレーム間の最低間隔 * @param {Float} yoffset 参照ベースラインからの側注の縦方向オフセット * @type boolean * @return 再帰のために関数処理を継続するか(true=継続する、false=継続しない) */ function redrawProcessXMLforComment(document, items, reftagname, xmargin, ymargin, yoffset) { if (items == null || items.length == 0) { return false; } for (var i = 0; i < items.length; i++) { if (items[i].xmlElements != null && items[i].xmlElements.length > 0) { for (var i2 = 0; i2 < items[i].xmlElements.length; i2++) { var e = items[i].xmlElements[i2]; if (e.markupTag.name == reftagname) { var attr = e.xmlAttributes.itemByRange("idref", "idref"); if (attr != null) { var backunit = toMmMode(document); var backruler = document.viewPreferences.rulerOrigin; document.viewPreferences.rulerOrigin = RulerOrigin.pageOrigin; var page; if (getCSVersion() == 2) { page = e.parentStory.characters[e.storyOffset - 1].insertionPoints[0].parentTextFrames[0].parent; } else if (getCSVersion() == 3) { page = e.storyOffset.parentTextFrames[0].parent; } else { page = e.storyOffset.parentTextFrames[0].parentPage; } var tf = document.textFrames.item("tmp-com-" + attr.value); var page2; if (getCSVersion() <= 3) { page2 = tf.parent; } else { page2 = tf.parentPage; } var unit = getBoundsOfPage(myDocument, page); if (page.documentOffset != page2.documentOffset) { // ページが変わった tf.move(page); } var y0; if (getCSVersion() == 2) { y0 = e.parentStory.characters[e.storyOffset - 1].insertionPoints[0].baseline + yoffset; } else { y0 = e.storyOffset.baseline + 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, xmargin, y0 + height, xmargin + width ]; } else { // 右 tf.geometricBounds = [ y0, document.documentPreferences.pageWidth - xmargin - width, y0 + height, document.documentPreferences.pageWidth - xmargin ]; } _commentarray.push([page.documentOffset, tf.id, y0, y0 + height]); revertMmMode(document, backunit); document.viewPreferences.rulerOrigin = backruler; } } } } if (getCSVersion() > 3) { redrawProcessXMLforComment(document, items[i].xmlElements, reftagname, xmargin, ymargin, yoffset); } else { redrawProcessXMLforComment(document, items[i].xmlItems, reftagname, xmargin, ymargin, yoffset); } } } /** * 指定のXML参照要素を探して、参照するテキストフレームと参照位置との間に線を引く * @param {Document} document ドキュメントオブジェクト * @param {XMLItems} items XMLItemsオブジェクト * @param {String} reftagname コメントへの参照XML要素名 * @param {ObjectStyle} lstyle 線のオブジェクトスタイル * @param {Float} yoffset 参照位置ベースラインからの縦方向オフセット * @type boolean * @return 再帰のために関数処理を継続するか(true=継続する、false=継続しない) */ function redrawProcessXMLforCommentLine(document, items, reftagname, lstyle, yoffset) { if (items == null || items.length == 0) { return false; } for (var i = 0; i < items.length; i++) { if (items[i].xmlElements != null && items[i].xmlElements.length > 0) { for (var i2 = 0; i2 < items[i].xmlElements.length; i2++) { var e = items[i].xmlElements[i2]; if (e.markupTag.name == reftagname) { var attr = e.xmlAttributes.itemByRange("idref", "idref"); if (attr != null) { var backunit = toMmMode(document); var backruler = document.viewPreferences.rulerOrigin; document.viewPreferences.rulerOrigin = RulerOrigin.pageOrigin; var page; if (getCSVersion() == 2) { page = e.parentStory.characters[e.storyOffset - 1].insertionPoints[0].parentTextFrames[0].parent; } else if (getCSVersion() == 3) { page = e.storyOffset.parentTextFrames[0].parent; } else { page = e.storyOffset.parentTextFrames[0].parentPage; } var tf = document.textFrames.item("tmp-com-" + attr.value); var line = document.graphicLines.itemByRange("tmp-comline-" + tf.id, "tmp-comline-" + tf.id); if (line != null) { line.remove(); } line = page.graphicLines.add(tf.itemLayer, undefined, undefined, { label: "tmp-comline-" + tf.id, appliedObjectStyle: lstyle, geometricBounds: [e.storyOffset.baseline + yoffset, tf.geometricBounds[3], e.storyOffset.baseline + yoffset, e.storyOffset.horizontalOffset] }); if (getCSVersion() > 3) { line.name = "tmp-comline-" + tf.id; } line.sendToBack(); revertMmMode(document, backunit); document.viewPreferences.rulerOrigin = backruler; } } } } if (getCSVersion() > 3) { redrawProcessXMLforCommentLine(document, items[i].xmlElements, reftagname, lstyle, yoffset); } else { redrawProcessXMLforCommentLine(document, items[i].xmlItems, reftagname, lstyle, yoffset); } } }