/** * @fileoverview 見出しdtpインストラクションの箇所にブックマークを入れる。目次中ノンブルなどの指定要素にハイパーリンクを付ける * @author Kenshi Muto <kmuto@debian.org> * @version 3 * @requires glue code.jsx * @requires libArabic2Roman.jsx */ /* Copyright: 2011 Kenshi Muto ---------------------------------------------------------------------- ソフトウェア使用許諾同意書 本ソフトウェアの利用・変更・再配布にあたっては、下記の使用許諾同意書に 同意する必要があります。 1. 本使用許諾同意書における「ソフトウェア」とは、機械可読の資料 (ライブ ラリ、スクリプト、ソースファイル、データファイル)、実行形式、および 文書を意味します。 2. 本ソフトウェアの使用許諾同意書に同意する限りにおいて、使用者は 本ソフトウェアを自由に利用、変更することができます。 3. 本ソフトウェアに変更を加えない限りにおいて、使用者は本ソフトウェアを 自由にコピー、再配布することができます。 4. 本ソフトウェアは無保証です。作者およびそれに関連する組織、配布者は、 本ソフトウェアの使用に起因する一切の直接損害、間接損害、偶発的損害、 特別損害、懲戒的損害、派生的損害について何らの責任・保証も負いません。 5. 本ソフトウェアを変更した上で再配布するときには、下記の事項すべてに 従わなければなりません。 - 使用許諾同意書の内容に変更を加えてはなりません。技術上の理由で 文字エンコーディングの変換を行うことは許可しますが、その使用者が 特殊な技術的措置なしに可読な形でなければなりません。 - 技術上の理由でバイナリ化・難読化を行う場合も、変更箇所を含めた ソフトウェアを、その使用者が可読可能な形式の形で同一のメディアで 提供しなければなりません。本使用許諾同意書の2条および3条により、 使用者が可読形式の該当ソフトウェアを変更、コピー、再配布することを 妨げてはなりません。 - ソフトウェア構成物の所定の作者名の欄に、変更者のクレジット (個人名、企業名、所属、連絡先など)を「追加」しなければなりません。 6. 本ソフトウェアを変更した上で再配布するときには、変更理由および その内容を明記することが推奨されます。 7. 使用者がソフトウェアに適用可能な特許に対して特許侵害にかかわる何らか の行動を開始した時点で、この使用許諾同意書は自動的に終了し、以降 使用者はこの使用許諾書によって与えられた一切の権利を放棄するものと します。 著作権所有者 Copyright (C) 2011 Kenshi Muto. All rights reserved. 使用許諾同意書バージョン1.0 著作権所有者による書面での事前の許可がない限り、この使用許諾同意書 に変更を加えてはなりません。 ---------------------------------------------------------------------- */ #include "../libs/glue code.jsx" #include "../libs/libArabic2Roman.jsx" var __bookcount = 0; var __findpagecount = 0; /** * tmp-autoラベルのあるブックマークおよびハイパーリンクのオブジェクトを削除する * @param {Document} document ドキュメントオブジェクト * @type nothing */ function clearBookmarks(document) { for (var i = document.hyperlinks.length - 1; i >= 0; i--) { if (document.hyperlinks[i].label == "tmp-auto") { document.hyperlinks[i].remove(); } } for (var i = document.hyperlinkTextSources.length - 1; i >= 0; i--) { if (document.hyperlinkTextSources[i].label == "tmp-auto") { document.hyperlinkTextSources[i].remove(); } } for (var i = document.hyperlinkExternalPageDestinations.length - 1; i >= 0; i--) { if (document.hyperlinkExternalPageDestinations[i].label == "tmp-auto") { document.hyperlinkExternalPageDestinations[i].remove(); } } for (var i = document.hyperlinkPageDestinations.length - 1; i >= 0; i--) { if (document.hyperlinkPageDestinations[i].label == "tmp-auto") { document.hyperlinkPageDestinations[i].remove(); } } } /** * 見出しdtpインストラクションの箇所に、しおりのためのブックマークを入れる。obj.currentlevel = 1、obj.parentBookmark = app.activeDocumentを明示的に指定すること * @param {Document} document ドキュメントオブジェクト * @param {XMLItems} items 開始XMLItemsオブジェクト * @param {Object} obj パラメータオブジェクト * @param {Number} obj.level しおりを入れる見出しレベルの最大値 * @param {Number} obj.currentlevel 現在のレベル。呼び出し時には必ず1を指定する * @param {Bookmark} obj.parentBookmark 現在の親ブックマークオブジェクト。呼び出し時には現在のDocumentオブジェクトを指定する * @type nothing */ function processXMLforBookmarks(document, items, obj) { if (items == null || items.length == 0) { return __bookcount; } for (var i = 0; i < items.length; i++) { if (items[i].xmlInstructions != null) { for (var i2 = 0; i2 < items[i].xmlInstructions.length; i2++) { var e = items[i].xmlInstructions[i2]; if (e.target == "dtp") { if (e.data.search(/section=/) != -1 && e.data.search(/level=/) != -1) { var sectname = e.data.match(/section="(.+?)"/)[1].replace("\t", " "); var l = parseInt(e.data.match(/level="(.+?)"/)[1]); if (l <= obj.level) { // ブックマーク埋め込み FIXME:(ページじゃないとうまくいかない) var hyperd = document.hyperlinkPageDestinations.add(e.storyOffset.parentTextFrames[0].parent, {name: String(e.id), hidden: true, label: "tmp-auto"}); if (l > obj.currentlevel) { // 下位レベルなのでサブフォルダ try { var id = obj.parentBookmark.name; // テスト } catch (ev) { document.bookmarks.add(e.storyOffset.parentTextFrames[0].parent, {name: "", hidden: true, label:"tmp-auto"}); // obj.parentBookmark = document.bookmarks[0]; } obj.parentBookmark = obj.parentBookmark.bookmarks[obj.parentBookmark.bookmarks.length - 1]; } else if (l == obj.currentlevel) { // 同一レベルなので何もしない } else { // 上位レベルなので1つ上になる obj.parentBookmark = obj.parentBookmark.parent; } obj.currentlevel = l; obj.parentBookmark.bookmarks.add(hyperd, {name: sectname}); __bookcount++; } } } } } processXMLforBookmarks(document, items[i].xmlItems, obj); } return __bookcount; } /** * 指定要素に外部ハイパーリンクを付ける * @param {Document} document ドキュメントオブジェクト * @param {Object} obj パラメータオブジェクト * @param {String} obj.tagname ハイパーリンク対象の要素名 * @param {Boolean} obj.visible ハイパーリンクを示すボックスを付けるかどうか(falseならば付けない) * @param {Number[]} obj.pre1 前付のノンブルをキー、ファイルページオフセットを値とした配列 * @param {String[]} obj.pre2 前付のノンブルをキー、ファイルパスを値とした配列 * @param {Number[]} obj.content1 本文のノンブルをキー、ファイルページオフセットを値とした配列 * @param {String[]} obj.content2 本文のノンブルをキー、ファイルパスを値とした配列 * @type nothing */ function processXMLforHyperlinks(obj, document) { var myRuleSet = new Array(new processHyperlinks(obj)); __processRuleSet(document.xmlElements.item(0), myRuleSet); } /** * 指定要素に外部ハイパーリンクを付けるコールバック * @param {Object} obj パラメータオブジェクト * @param {String} obj.tagname ハイパーリンク対象の要素名 * @param {Boolean} obj.visible ハイパーリンクを示すボックスを付けるかどうか(falseならば付けない) * @param {Number[]} obj.pre1 前付のノンブルをキー、ファイルページオフセットを値とした配列 * @param {String[]} obj.pre2 前付のノンブルをキー、ファイルパスを値とした配列 * @param {Number[]} obj.content1 本文のノンブルをキー、ファイルページオフセットを値とした配列 * @param {String[]} obj.content2 本文のノンブルをキー、ファイルパスを値とした配列 * @type nothing */ function processHyperlinks(obj) { this.name = "ProcessSubset"; this.xpath = "//" + obj.tagname; this.apply = function(myElement, myRuleProcessor) { obj.point = myElement.storyOffset; obj.story = myElement.parentStory; obj.myelement = myElement; addHyperlink(obj); return true; } } /** * 指定要素に外部ハイパーリンクを付ける実体 * @param {Object} obj パラメータオブジェクト * @param {String} obj.tagname ハイパーリンク対象の要素名 * @param {Boolean} obj.visible ハイパーリンクを示すボックスを付けるかどうか(falseならば付けない) * @param {Number[]} obj.pre1 前付のノンブルをキー、ファイルページオフセットを値とした配列 * @param {String[]} obj.pre2 前付のノンブルをキー、ファイルパスを値とした配列 * @param {Number[]} obj.content1 本文のノンブルをキー、ファイルページオフセットを値とした配列 * @param {String[]} obj.content2 本文のノンブルをキー、ファイルパスを値とした配列 * @type nothing */ function addHyperlink(obj) { var document = obj.story.parent; var h_d; var h_s = document.hyperlinkTextSources.add(obj.myelement.texts[0], {label: "tmp-auto"}); var nmbl = obj.myelement.texts[0].contents; if (nmbl.match(/\d/)) { // アラビア数字(本文)ノンブル h_d = document.hyperlinkExternalPageDestinations.add(undefined, {documentPath: new File(obj.content2[Number(nmbl)]), destinationPageIndex: obj.content1[Number(nmbl)], name: nmbl, label: "tmp-auto"}); } else { // ローマ数字(前付)ノンブル _nmbl = Number(roman2arabic(nmbl)); h_d = document.hyperlinkExternalPageDestinations.add(undefined, {documentPath: new File(obj.pre2[_nmbl]), destinationPageIndex: obj.pre1[_nmbl], name: _nmbl, label: "tmp-auto"}); } document.hyperlinks.add(h_s, h_d, {label: "tmp-auto", visible: obj.visible, name: nmbl}); __findpagecount++; } /** * ノンブルとファイル名のマップを読み込む。ファイル名は、「ノンブル タブ ドキュメントオフセット タブ ファイルパス」(本文)か、「ノンブル タブ ドキュメントオフセット タブ ファイルパス タブ PRE」(前付)の行で構成する * @type Array[] * @return 前付ノンブル-オフセットの配列、前付ノンブル-ファイルパスの配列、本文ノンブル-オフセットの配列、本文ノンブル-ファイルパスの配列 の4つの配列を格納した配列を返す */ function loadDaiwariPageFile() { var filename = File.openDialog("読み込むページ一覧ファイル", "テキストファイル:*.txt,すべてのファイル:*"); if (!filename) exit(0); var fileObj = new File(filename); fileObj.open("r"); var pre1 = []; var pre2 = []; var honbun1 = []; var honbun2 = []; while (!fileObj.eof) { fline = fileObj.readln(); var flines = fline.split(/\t/); if (flines[3] == "PRE") { pre1[flines[0]] = Number(flines[1]); pre2[flines[0]] = flines[2]; } else { honbun1[flines[0]] = Number(flines[1]); honbun2[flines[0]] = flines[2]; } } return [pre1, pre2, honbun1, honbun2]; }