├── sample.png ├── doc ├── scripts │ ├── linenumber.js │ └── prettify │ │ ├── lang-css.js │ │ ├── Apache-License-2.0.txt │ │ └── prettify.js ├── styles │ ├── prettify-jsdoc.css │ ├── prettify-tomorrow.css │ └── jsdoc-default.css ├── index.html ├── kanbun.js.html └── global.html ├── LICENSE ├── README.md ├── kanbun.html └── kanbun.js /sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kawabata/kanbun-javascript/HEAD/sample.png -------------------------------------------------------------------------------- /doc/scripts/linenumber.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var counter = 0; 3 | var numbered; 4 | var source = document.getElementsByClassName('prettyprint source'); 5 | 6 | if (source && source[0]) { 7 | source = source[0].getElementsByTagName('code')[0]; 8 | 9 | numbered = source.innerHTML.split('\n'); 10 | numbered = numbered.map(function(item) { 11 | counter++; 12 | return '' + item; 13 | }); 14 | 15 | source.innerHTML = numbered.join('\n'); 16 | } 17 | })(); 18 | -------------------------------------------------------------------------------- /doc/scripts/prettify/lang-css.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n"]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", 2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Teruyuki Kobayashi koba1014@gmail.com 4 | Copyright (c) 2018 kawabata 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /doc/styles/prettify-jsdoc.css: -------------------------------------------------------------------------------- 1 | /* JSDoc prettify.js theme */ 2 | 3 | /* plain text */ 4 | .pln { 5 | color: #000000; 6 | font-weight: normal; 7 | font-style: normal; 8 | } 9 | 10 | /* string content */ 11 | .str { 12 | color: #006400; 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | 17 | /* a keyword */ 18 | .kwd { 19 | color: #000000; 20 | font-weight: bold; 21 | font-style: normal; 22 | } 23 | 24 | /* a comment */ 25 | .com { 26 | font-weight: normal; 27 | font-style: italic; 28 | } 29 | 30 | /* a type name */ 31 | .typ { 32 | color: #000000; 33 | font-weight: normal; 34 | font-style: normal; 35 | } 36 | 37 | /* a literal value */ 38 | .lit { 39 | color: #006400; 40 | font-weight: normal; 41 | font-style: normal; 42 | } 43 | 44 | /* punctuation */ 45 | .pun { 46 | color: #000000; 47 | font-weight: bold; 48 | font-style: normal; 49 | } 50 | 51 | /* lisp open bracket */ 52 | .opn { 53 | color: #000000; 54 | font-weight: bold; 55 | font-style: normal; 56 | } 57 | 58 | /* lisp close bracket */ 59 | .clo { 60 | color: #000000; 61 | font-weight: bold; 62 | font-style: normal; 63 | } 64 | 65 | /* a markup tag name */ 66 | .tag { 67 | color: #006400; 68 | font-weight: normal; 69 | font-style: normal; 70 | } 71 | 72 | /* a markup attribute name */ 73 | .atn { 74 | color: #006400; 75 | font-weight: normal; 76 | font-style: normal; 77 | } 78 | 79 | /* a markup attribute value */ 80 | .atv { 81 | color: #006400; 82 | font-weight: normal; 83 | font-style: normal; 84 | } 85 | 86 | /* a declaration */ 87 | .dec { 88 | color: #000000; 89 | font-weight: bold; 90 | font-style: normal; 91 | } 92 | 93 | /* a variable name */ 94 | .var { 95 | color: #000000; 96 | font-weight: normal; 97 | font-style: normal; 98 | } 99 | 100 | /* a function name */ 101 | .fun { 102 | color: #000000; 103 | font-weight: bold; 104 | font-style: normal; 105 | } 106 | 107 | /* Specify class=linenums on a pre to get line numbering */ 108 | ol.linenums { 109 | margin-top: 0; 110 | margin-bottom: 0; 111 | } 112 | -------------------------------------------------------------------------------- /doc/styles/prettify-tomorrow.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Theme */ 2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 3 | /* Pretty printing styles. Used with prettify.js. */ 4 | /* SPAN elements with the classes below are added by prettyprint. */ 5 | /* plain text */ 6 | .pln { 7 | color: #4d4d4c; } 8 | 9 | @media screen { 10 | /* string content */ 11 | .str { 12 | color: #718c00; } 13 | 14 | /* a keyword */ 15 | .kwd { 16 | color: #8959a8; } 17 | 18 | /* a comment */ 19 | .com { 20 | color: #8e908c; } 21 | 22 | /* a type name */ 23 | .typ { 24 | color: #4271ae; } 25 | 26 | /* a literal value */ 27 | .lit { 28 | color: #f5871f; } 29 | 30 | /* punctuation */ 31 | .pun { 32 | color: #4d4d4c; } 33 | 34 | /* lisp open bracket */ 35 | .opn { 36 | color: #4d4d4c; } 37 | 38 | /* lisp close bracket */ 39 | .clo { 40 | color: #4d4d4c; } 41 | 42 | /* a markup tag name */ 43 | .tag { 44 | color: #c82829; } 45 | 46 | /* a markup attribute name */ 47 | .atn { 48 | color: #f5871f; } 49 | 50 | /* a markup attribute value */ 51 | .atv { 52 | color: #3e999f; } 53 | 54 | /* a declaration */ 55 | .dec { 56 | color: #f5871f; } 57 | 58 | /* a variable name */ 59 | .var { 60 | color: #c82829; } 61 | 62 | /* a function name */ 63 | .fun { 64 | color: #4271ae; } } 65 | /* Use higher contrast and text-weight for printable form. */ 66 | @media print, projection { 67 | .str { 68 | color: #060; } 69 | 70 | .kwd { 71 | color: #006; 72 | font-weight: bold; } 73 | 74 | .com { 75 | color: #600; 76 | font-style: italic; } 77 | 78 | .typ { 79 | color: #404; 80 | font-weight: bold; } 81 | 82 | .lit { 83 | color: #044; } 84 | 85 | .pun, .opn, .clo { 86 | color: #440; } 87 | 88 | .tag { 89 | color: #006; 90 | font-weight: bold; } 91 | 92 | .atn { 93 | color: #404; } 94 | 95 | .atv { 96 | color: #060; } } 97 | /* Style */ 98 | /* 99 | pre.prettyprint { 100 | background: white; 101 | font-family: Menlo, Monaco, Consolas, monospace; 102 | font-size: 12px; 103 | line-height: 1.5; 104 | border: 1px solid #ccc; 105 | padding: 10px; } 106 | */ 107 | 108 | /* Specify class=linenums on a pre to get line numbering */ 109 | ol.linenums { 110 | margin-top: 0; 111 | margin-bottom: 0; } 112 | 113 | /* IE indents via margin-left */ 114 | li.L0, 115 | li.L1, 116 | li.L2, 117 | li.L3, 118 | li.L4, 119 | li.L5, 120 | li.L6, 121 | li.L7, 122 | li.L8, 123 | li.L9 { 124 | /* */ } 125 | 126 | /* Alternate shading for lines */ 127 | li.L1, 128 | li.L3, 129 | li.L5, 130 | li.L7, 131 | li.L9 { 132 | /* */ } 133 | -------------------------------------------------------------------------------- /doc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |吾《われ》嘗《かつ》テ終《しゅう》日《じつ》不《ず》[#レ]食《く》ラハ、終夜《しゅうや》不《ず》[#レ]寝《い》ネ、以《もつ》テ思《おも》フ。
38 | 39 | ## 利用方法 40 | 41 | HTMLで利用する場合は、kanbun.js を読み込むだけで利用可能です。 42 | 43 | 44 | 45 | 以下の関数を呼び出すことで、漢文を整形します。IDを空文字列にすれば、全てのkanbunクラスのタグが処理対象になります。 46 | 47 | - kanbun_html_to_original("#ID") … 入力テキストを表示します。 48 | - kanbun_html_to_kanbun("#ID",bool,bool,bool,bool,bool) … 漢文を表示します。 49 | - kanbun_html_to_kakikudashi("#ID",bool,bool,bool) … 書き下し文を表示します。 50 | 51 | 関数の詳細については、付属の [jsdoc](./doc/index.html) を確認ください。 52 | 53 | ## 漢文の例 54 | 55 | 再読文は、『【漢字】《【よみ】》【送り仮名】〈【再読よみ】〉【再読送り仮名】』で表現します。 56 | 57 | - 原データ: 引キテ[#レ]酒ヲ且《》二〈ス〉[#レ]飲マント[#レ]之ヲ。 58 | * 漢文:引酒且飲之。 59 | * 書き下し:酒ヲ引キテ且二之ヲ飲マントス。 60 | 61 | - 原データ: 孤之〈ノ〉有ルハ[#二]孔明[#一]、猶《な》ホ〈ゴト〉シ[#二]魚之〈ノ〉有ルガ[#一レ]水。 62 | * 漢文: 孤之有孔明、猶魚之有水。 63 | * 書き下し: 孤ノ孔明有ルハ、猶《な》ホ魚ノ水有ルガゴトシ。 64 | 65 | 置き字は、その漢字の後ろに空の〈〉を付します。 66 | 67 | - 原データ:青ハ取リテ[#二]之ヲ於〈〉藍ヨリ[#一]而〈〉青シ[#二]於〈〉藍ヨリモ[#一] 68 | * 漢文: 青取之於藍而青於藍 69 | * 書き下し:青ハ之ヲ藍ヨリ取リテ藍ヨリモ青シ 70 | 71 | 対応する訓点には、上中下・甲乙丙丁・天地人があります。 72 | 73 | - 原データ: 使〈シ〉メヨ[#人]籍《せき》ヲシテ誠《まこと》ニ不〈〉〈ズ〉[#乙]以《もつ》テ[#下]蓄《やしな》ヒ[#二]妻子ヲ[#一]憂《うれ》フルヲ[#中]飢寒《きかん》ヲ[#上]乱サ[#甲レ]心ヲ、有リテ[#レ]銭《ぜに》以《もつ》テ済《な》サ[#地]医薬ヲ[#天]。 74 | * 漢文:使籍誠不以蓄妻子憂飢寒乱心有銭以済医薬。 75 | * 書き下し: 籍《せき》ヲシテ誠《まこと》ニ妻子ヲ蓄《やしな》ヒ飢寒《きかん》ヲ憂《うれ》フルヲ以《もつ》テ心ヲ乱サズ、銭《ぜに》有リテ以《もつ》テ医薬ヲ済《な》サシメヨ。 76 | 77 | 78 | ## HTMLの例 79 | 80 | 付属の kanbun.html を参照ください。 81 | 82 | ## 漢文の書式 83 | 84 | 漢文は以下の書式で記述します。改行などの特殊記号は使えないのでご注意ください。 85 | 86 | 漢文 := 漢文単位+ 87 | 漢文単位 := 漢字単位 読み仮名? 送り仮名* 再読仮名? 再読送り* 竪点? 訓点? 88 | 漢字単位 := 漢字 異体字選択? | 句読点 89 | 漢字 := "[㐀-\9fff]|[豈-\faff]|[\ud840-\ud87f][\udc00-\udfff]" 90 | 句読点 := "[。、]" 91 | 異体字選択 := "\udb40[\udd00-\uddef]" (異体字選択子:U+E0100...U+E01EF) 92 | 読み仮名 := 表示読み | 非表示読み 93 | 表示読み := "《" 仮名漢字* "》" 94 | ※ 表示読みは、漢文・書き下し文の両方で漢字の脇に読みを表示する。 95 | 仮名漢字 := 仮名 | 漢字 96 | 仮名 := [ぁ-ヿ] 97 | 非表示読み := "〈" 仮名漢字* "〉" 98 | ※ 非表示読みは、漢文では読みを表示せず、書き下し文では読みのみ表示する。 99 | ※ 置き字は非表示読みを空の〈〉として表現する。 100 | 送り仮名 := 仮名+ | "[#(" 仮名漢字+ ")]" 101 | ※ 万葉仮名がある場合は、後者を使用する。 102 | 再読仮名 := 表示読み | 非表示読み 103 | 再読送り := 仮名+ | "[#(" 仮名漢字+ ")]" 104 | ※ 万葉仮名がある場合は、後者を使用する。 105 | 竪点 := "‐" ※ (仮定)竪点は2つ連続しない。 106 | 訓点 := "[#" 訓点文字 "]" 107 | 訓点文字 := 順序点 | "[一上天甲]?レ" 108 | 順序点 := [一二三四上中下天地人甲乙丙丁] 109 | 110 | -------------------------------------------------------------------------------- /kanbun.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 || 漢文 | 解説 |
|---|---|
| 秦王、以テ[#二]十五城ヲ[#一]請フ[#レ]易《か》ヘンコトヲ[#二]寡人之璧ニ[#一]。可キヤ[#レ]予《あた》フ不《いな》ヤ。 | 49 |レ点や一・二点はかならず送りがなの後ろに付加します。 | 50 |
| 吾《われ》嘗《かつ》テ終《しゅう》日《じつ》不〈ズ〉[#レ]食《く》ラハ、終《しゅう》夜《や》不〈ズ〉[#レ]寝《い》ネ、以《もつ》テ思《おも》フ。 | 54 |書き下しの時に漢字ではなく読み仮名のみを表示させたい場合は、ルビに"《》"ではなく"〈〉"を用います。 | 55 |
| 使〈シ〉メヨ[#人]籍《せき》ヲシテ誠《まこと》ニ不〈〉〈ズ〉[#乙]以《もつ》テ[#下]蓄《やしな》ヒ[#二]妻子ヲ[#一]憂《うれ》フルヲ[#中]飢《き》寒《かん》ヲ[#上]乱サ[#甲レ]心ヲ、有リテ[#レ]銭《ぜに》以《もつ》テ済《な》サ[#地]医薬ヲ[#天]。 | 59 |対応する訓点には、上中下・甲乙丙丁・天地人があります。 | 60 |
| 未《いま》ダ〈ざ〉ル[#レ]足《た》ラ[#二]与《とも》ニ議スルニ[#一]也。 | 64 |再読文は、『【漢字】《【よみ】》【送り仮名】〈【再読よみ】〉【再読送り仮名】』で表現します。 | 65 |
| 盍《なん》ゾ〈ザ〉ル[#レ]反《かへ》ラ[#二]其ノ本ニ[#一]矣〈〉。 | 69 | 70 |置き字は、その漢字の後ろに空の〈〉を付します。 | 71 |
| 盍《なん》[#(ゾ)]〈ザ〉[#(ル)][#レ]反《かへ》[#(ラ)][#二]其[#(ノ)]本[#(ニ)][#一]矣〈〉。 | 74 | 75 |送り仮名は、[#(…)]の記法でも記述できます。再読文字の送り仮名も同様に書けます。 | 76 |
| 引キテ[#レ]酒ヲ且ニ〈ス〉[#レ]飲マント[#レ]之ヲ。 | 79 | 80 |再読文字で、最初の読みがない場合は省略できます。 | 81 |
| 孤之〈ノ〉有ルハ[#二]孔明[#一]、猶《な》ホ〈ゴト〉シ[#二]魚之〈ノ〉有ルガ[#一レ]水。 | 84 | 85 |再読文字で、再読文字に送り仮名がある場合は、〈…〉の後ろに送り仮名を入れます。 | 86 |
/** @fileoverview
29 | * 漢文訓読 JavaScript --
30 | * 注記を施した漢文を、漢文または書き下し文のHTMLに変換する。
31 | *
32 | * @author KAWABATA, Taichi
33 | * @version 0.1
34 | */
35 |
36 | /*
37 | 漢文注記記法:
38 | 漢文 := 漢文単位+
39 | 漢文単位 := 漢字単位 読み仮名? 送り仮名* 再読仮名? 再読送り* 竪点? 訓点?
40 | 漢字単位 := 漢字 異体字選択? | 句読点
41 | 漢字 := "[㐀-\9fff]|[豈-\faff]|[\ud840-\ud87f][\udc00-\udfff]"
42 | 句読点 := "[。、]"
43 | 異体字選択 := "\udb40[\udd00-\uddef]" (異体字選択子:U+E0100...U+E01EF)
44 | 読み仮名 := 表示読み | 非表示読み
45 | 表示読み := "《" 仮名漢字* "》"
46 | ※ 表示読みは、漢文・書き下し文の両方で漢字の脇に読みを表示する。
47 | 仮名漢字 := 仮名 | 漢字
48 | 仮名 := [ぁ-ヿ]
49 | 非表示読み := "〈" 仮名漢字* "〉"
50 | ※ 非表示読みは、漢文では読みを表示せず、書き下し文では読みのみ表示する。
51 | ※ 置き字は非表示読みを空の〈〉として表現する。
52 | 送り仮名 := 仮名+ | "[#(" 仮名漢字+ ")]"
53 | ※ 万葉仮名がある場合は、後者を使用する。
54 | 再読仮名 := 表示読み | 非表示読み
55 | 再読送り := 仮名+ | "[#(" 仮名漢字+ ")]"
56 | ※ 万葉仮名がある場合は、後者を使用する。
57 | 竪点 := "‐" ※ (仮定)竪点は2つ連続しない。
58 | 訓点 := "[#" 訓点文字 "]"
59 | 訓点文字 := 順序点 | "[一上天甲]?レ"
60 | 順序点 := [一二三四上中下天地人甲乙丙丁]
61 | */
62 | var kanbun_regex;
63 |
64 | (function kanbun_regex_setup () {
65 | var kanji = "[㐀-\u9fff]|[豈-\ufaff]|[\ud840-\ud87f][\udc00-\udfff]";
66 | var vselector = "\udb40[\udd00-\uddef]";
67 | var kutouten = "[。、]";
68 | var kanji_unit = "(?:" + kanji+"(?:"+vselector+")?|"+kutouten+")";
69 | var kana = "[ぁ-ヿ]";
70 | var kana_kanji = kana+"|(?:"+kanji_unit+")";
71 | var hyouji = "《(?:"+ kana_kanji + ")*》";
72 | var hihyouji = "〈(?:"+ kana_kanji + ")*〉";
73 | var yomi = "(?:" + hyouji +")|(?:" + hihyouji +")";
74 | var okuri = kana + "+|[#((?:" + kana_kanji + ")+)]";
75 | var saidoku = "(?:" + hyouji +")|(?:" + hihyouji +")";
76 | var saiokuri = kana + "+|[#((?:" + kana_kanji + ")+)]";
77 | var tateten = "‐";
78 | var junjo = "[一二三四上中下天地人甲乙丙丁]";
79 | var kunten = "[#(?:"+junjo+"|[一上天甲]?レ)]";
80 |
81 | var kanbun = "(" +kanji_unit +")(" + yomi + ")?(" + okuri + ")?(" + saidoku +
82 | ")?(" + saiokuri + ")?(" + tateten +")?(" + kunten + ")?";
83 | kanbun_regex = new RegExp (kanbun);
84 | } ());
85 |
86 | // ******** 基本機能 ********
87 |
88 | /**
89 | * 配列からの要素の削除
90 | * @private
91 | */
92 | Array.prototype.remove = function() {
93 | var what, a = arguments, L = a.length, ax;
94 | while (L && this.length) {
95 | what = a[--L];
96 | while ((ax = this.indexOf(what)) !== -1) {
97 | this.splice(ax, 1);
98 | }
99 | }
100 | return this;
101 | };
102 |
103 | /**
104 | * 配列の複製(配列要素の複製はしない)
105 | * @private
106 | */
107 | Array.prototype.clone = function(){
108 | return Array.apply(null,this);
109 | };
110 |
111 |
112 | // ******** 漢文の分割と関連ツール ********
113 |
114 | /**
115 | * 漢文を漢字単位に分割する。
116 | * @private
117 | * @param {string} text 元データ
118 | * @returns matchの配列
119 | * @type {Array}
120 | */
121 | function kanbun_split (text) {
122 | var result=[];
123 | while (text.length > 0) {
124 | var match = text.match(kanbun_regex);
125 | if (match == null) {
126 | console.log(text);
127 | alert("Parse Error! see console log.");
128 | return -1;
129 | }
130 | if (match["index"]!=0) {
131 | console.log(match);
132 | alert("Parse Error! see console log.");
133 | return -1;
134 | }
135 | text=text.substring(match[0].length);
136 | result = result.concat([match]);
137 | }
138 | return result;
139 | }
140 |
141 | /**
142 | * match の漢字・読みの部分をHTMLにする。
143 | * @private
144 | * @param {Array} match
145 | * @param {boolean} yomi_p 漢字に読みを表示する。
146 | * @param {boolean} kanbun_p 漢文ならtrue, 書き下し文ならfalse。
147 | * trueなら、〈…〉は、漢字のみを表示し、falseなら仮名のみを表示する。
148 | * @param {boolean} saidoku_p 再読文字をHTML5 左ルビ仕様で表示する。
149 | * @returns {string} 読み付き漢字。rubyがfalseか読みがない場合は漢字のみ。
150 | * 〈…〉は kanbun がtrueなら漢字のみ。falseなら読みのみ。
151 | * 《…》なら<ruby>タグで返す。
152 | */
153 | // TODO 再読文字の左ルビは未対応。
154 | function kanbun_match_yomi(match,yomi_p,kanbun_p) {
155 | var kanji=match[1];
156 | var yomi=match[2];
157 | var saidoku=match[4];
158 | // 特殊ケース
159 | if (yomi != undefined && yomi.match(/^〈/)) {
160 | if (kanbun_p) {
161 | return kanji;
162 | } else {
163 | return yomi.slice(1,-1);
164 | }
165 | } else if (!yomi_p) return kanji;
166 | // ruby
167 | if (yomi == undefined && saidoku==undefined) {return kanji;}
168 | var result="<ruby>"+kanji+
169 | ((yomi == undefined)?
170 | "<rt></rt>":"<rp>(</rp><rt>"+yomi.slice(1,-1)+"</rt><rp>)</rp>")+
171 | // 書き下しでは再読文字にルビは入れない。
172 | ((kanbun_p==false || saidoku==undefined)?
173 | "":"<rp>[</rp><rt>"+saidoku.slice(1,-1)+"</rt><rp>]</rp>")+
174 | "</ruby>";
175 | return result;
176 | }
177 |
178 | var kanbun_unicode = {"‐":"㆐","レ":"㆑","一":"㆒","二":"㆓",
179 | "三":"㆔","四":"㆕","上":"㆖","中":"㆗",
180 | "下":"㆘","甲":"㆙","乙":"㆚","丙":"㆛",
181 | "丁":"㆜","天":"㆝","地":"㆞","人":"㆟"};
182 |
183 | /**
184 | * match の送り仮名部分を返す。
185 | * (送り仮名がない場合は空文字を返す。)
186 | * @private
187 | * @param {Array} match
188 | * @returns {string} 送り仮名部分
189 | */
190 | function kanbun_match_okuri (match) {
191 | var okuri = (match[3] != undefined)? match[3] : "";
192 | return (okuri.match(/^[#(/)) ? okuri.slice(3,-2):okuri;
193 | }
194 |
195 | /**
196 | * match の送り・訓点部分をHTMLにする。(漢文訓読)
197 | * @private
198 | * @param {Array} match
199 | * @param {boolean} unicode_p 訓点をUniocodeで表示する
200 | * @param {boolean} okuri_p 送り仮名を表示する
201 | * @param {boolean} ten_p 訓点を表示する
202 | * @returns {string} 訓点HTML。
203 | */
204 | function kanbun_match_okuri_ten(match,unicode_p,okuri_p,ten_p) {
205 | // 送り文字
206 | var okuri = (okuri_p == false) ? "" : kanbun_match_okuri(match);
207 | var tate= ((ten_p == false) || (match[6] == undefined))? "" : match[6];
208 | var ten = ((ten_p == false) || (match[7] == undefined))? "" : match[7].slice(2,-1);
209 |
210 | if (okuri == "" && ten != "") okuri = " ";
211 | if (okuri != "" && ten == "") ten = " ";
212 | if (okuri != "" && ten != "") {
213 | return "<table cellspacing='0' cellpadding='0' style='vertical-align: middle; display: inline-block; font-size: 50%;'><tr><td>"
214 | + okuri + "</td></tr><tr><td>" + ten + "</td></tr></table>";
215 | // TODO tate shori.
216 | } else
217 | return "";
218 | }
219 |
220 | // ******** 漢文 ********
221 |
222 | /**
223 | * 文字列中のカタカナを平仮名にする。
224 | * @private
225 | * @param {string} text 元文字列
226 | * @returns 変換文字列
227 | * @type string
228 | */
229 | function kanbun_katakana_to_hiragana (text) {
230 | var result=text.replace(/[ァ-ヶ]/g,function(whole) {
231 | var hiragana= whole.charCodeAt(0)-96;
232 | return String.fromCharCode(hiragana);
233 | });
234 | return result;
235 | }
236 |
237 | /**
238 | * 句読点の前の<wbr>を除去する。
239 | * @private
240 | * @param {string} html 元HTML
241 | * @returns 変換HTML
242 | * @type string
243 | */
244 | function kanbun_remove_kutou_break(html) {
245 | var result=html.replace(/<\/nobr><wbr\/><nobr>([。、])/g,"$1");
246 | return result;
247 | }
248 |
249 | /**
250 | * 漢文をHTMLに変換する。
251 | * @param {string} text 元データ
252 | * @param {boolean} yomi 読み表示
253 | * @param {boolean} okuri 送り仮名表示
254 | * @param {boolean} ten 漢文順序点表示
255 | * @param {boolean} kutou 句読点表示
256 | * @param {boolean} unicode 漢文順序にユニコードを使用
257 | * @returns HTMLデータ
258 | * @type string
259 | */
260 | function kanbun_to_kanbun (text, yomi, okuri, ten, kutou, unicode) {
261 | var split=kanbun_split(text);
262 | var result="";
263 | split.forEach(function(match) {
264 | if (!(!kutou && match[1].match(/[。、]/))) {
265 | var kanji_part = kanbun_match_yomi(match,yomi,true);
266 | var okuri_ten_part = kanbun_match_okuri_ten(match,unicode,okuri,ten);
267 | result+="<nobr>"+ kanji_part + okuri_ten_part +"</nobr><wbr/>";
268 | }
269 | });
270 | return kanbun_remove_kutou_break(result);
271 | }
272 |
273 | // ******** 書き下し文 ********
274 |
275 | /**
276 | * 漢文の順序を書き下し文の順序の分割した配列に変換する。
277 | * @private
278 | * @param {string} text 入力
279 | * @param {boolean} unicode 訓点文字
280 | * @returns {array} 順序を入れ替えた配列
281 | */
282 | function kanbun_reorder (text){
283 | var kunten_flag="", reten_flag=false, tate_flag=false;
284 | var split_text=kanbun_split (text);
285 | var kanbun_two=null, kanbun_three=null, kanbun_four=null;
286 | var kanbun_middle=null, kanbun_down=null;
287 | var kanbun_otsu=null, kanbun_hei=null, kanbun_tei=null;
288 | var kanbun_chi=null, kanbun_jin=null;
289 | var stock=new Array();
290 | var result=new Array();
291 |
292 | split_text.forEach(function (match) {
293 | var tateten=(typeof match[6] != 'undefined')?match[6]:"";
294 | var kunten=(typeof match[7] != 'undefined')?match[7].slice(2,-1):"";
295 | var saidoku = match[4];
296 | var saiyomi = match[5];
297 | if (typeof saidoku != 'undefined') {
298 | // 再読処理。matchをそのままresultに入れ、
299 | // matchはclone()してそこの読み・送りを再読・再送りにする。
300 | result.push(match);
301 | match = match.clone();
302 | match[2]=saidoku;
303 | match[3]=saiyomi;
304 | }
305 | // 前の漢字のレ点・竪点への対応
306 | if (reten_flag) {
307 | stock.unshift(match);
308 | reten_flag=false;
309 | } else if (tate_flag) {
310 | stock.push(match);
311 | tate_flag=false;
312 | } else {
313 | stock = new Array(match);
314 | }
315 | // 訓点処理
316 | if (kunten.match(/[一二三四上中下天地人甲乙丙丁]/)) {
317 | kunten_flag = RegExp.lastMatch;
318 | }
319 | if (kunten.match(/レ/)) {
320 | reten_flag=true; // 「一レ」の場合は reten_flag だけ true にして次に。
321 | } else if (tateten == "‐") {
322 | tate_flag=true;
323 | } else if (kunten_flag.length > 0) {
324 | // 現在漢字にレ点・竪点がない場合は訓点処理に入る
325 | if (kunten_flag.match(/一/)) {
326 | result = result.concat(stock).concat(kanbun_two);
327 | result = result.concat(kanbun_three).concat(kanbun_four);
328 | kanbun_two=null;
329 | kanbun_three=null;
330 | kanbun_four=null;}
331 | else if (kunten_flag.match(/二/)) kanbun_two=stock;
332 | else if (kunten_flag.match(/三/)) kanbun_three=stock;
333 | else if (kunten_flag.match(/四/)) kanbun_four=stock;
334 | else if (kunten_flag.match(/上/)) {
335 | result = result.concat(stock).concat(kanbun_middle);
336 | result = result.concat(kanbun_down);
337 | kanbun_middle=null;
338 | kanbun_down=null;}
339 | else if (kunten_flag.match(/中/)) kanbun_middle=stock;
340 | else if (kunten_flag.match(/下/)) kanbun_down=stock;
341 | else if (kunten_flag.match(/甲/)) {
342 | result = result.concat(stock).concat(kanbun_otsu);
343 | result = result.concat(kanbun_hei).concat(kanbun_tei);
344 | kanbun_otsu=null;
345 | kanbun_hei=null;
346 | kanbun_tei=null;
347 | }
348 | else if (kunten_flag.match(/乙/)) kanbun_otsu=stock;
349 | else if (kunten_flag.match(/丙/)) kanbun_hei=stock;
350 | else if (kunten_flag.match(/丁/)) kanbun_tei=stock;
351 | else if (kunten_flag.match(/天/)) {
352 | result = result.concat(stock).concat(kanbun_chi);
353 | result = result.concat(kanbun_jin);
354 | kanbun_chi=null;
355 | kanbun_jin=null;}
356 | else if (kunten_flag.match(/地/)) kanbun_chi=stock;
357 | else if (kunten_flag.match(/人/)) kanbun_jin=stock;
358 | else console.log ("error! match="+match);
359 | kunten_flag="";
360 | } else {
361 | result = result.concat(stock);
362 | }
363 | });
364 | return result.remove(null);
365 | }
366 |
367 | /**
368 | * 漢文を書き下し文に変換する。
369 | * @param {string} text 元データ
370 | * @param {boolean} yomi 読み表示
371 | * @param {boolean} hiragana カタカナを平仮名に変換
372 | * @returns HTMLデータ
373 | * @type string
374 | */
375 | function kanbun_to_kakikudashi (text,yomi,hiragana){
376 | var reordered=kanbun_reorder(text);
377 | var result="";
378 | reordered.forEach(function(match) {
379 | var kanji_part = kanbun_match_yomi(match,yomi,false);
380 | var okuri_part = kanbun_match_okuri(match);
381 | result+="<nobr>"+kanji_part+okuri_part +"</nobr><wbr/>";
382 | });
383 | if (hiragana) result=kanbun_katakana_to_hiragana(result);
384 | return kanbun_remove_kutou_break(result);
385 | }
386 |
387 |
388 | // ******** HTML処理(要jquery) ********
389 | //
390 | // 元のデータを <!--XXXX--> とコメントに入れて保存する。
391 | //
392 |
393 | /**
394 | * text中の <!--XXXX--> の部分を返す。
395 | * @private
396 | */
397 | function kanbun_orig_text (text) {
398 | var orig_text;
399 | if (text.match(/<!--([^>]+)-->/)) {
400 | orig_text=RegExp.$1;
401 | } else {
402 | orig_text=text;
403 | }
404 | return orig_text;
405 | };
406 |
407 | /**
408 | * HTMLのIDノードの、<!--XXXX--> で保存されている原データをもとに戻す。
409 | * @private
410 | * @param {string} id HTML node
411 | * @returns {none}
412 | */
413 | function kanbun_html_to_original (id) {
414 | $(id+"[class=kanbun]").each(function () {
415 | var orig_text=kanbun_orig_text($(this).html());
416 | $(this).html(orig_text);
417 | });
418 | }
419 |
420 | /**
421 | * HTMLのIDノードを漢文に変換する。(要jQuery)
422 | * @param {string} id HTML node
423 | * @param {boolean} yomi 読み仮名表示
424 | * @param {boolean} okuri 送り仮名表示
425 | * @param {boolean} ten 漢文順序点表示
426 | * @param {boolean} kutou 句読点表示
427 | * @param {boolean} unicode 漢文順序にユニコードを使用
428 | * @type {none}
429 | */
430 | function kanbun_html_to_kanbun (id,yomi,okuri,ten,kutou,unicode) {
431 | $(id+"[class=kanbun]").each(function () {
432 | var orig_text=kanbun_orig_text($(this).html());
433 | var new_text=kanbun_to_kanbun(orig_text,yomi,okuri,ten,kutou,unicode);
434 | $(this).html(new_text+"<!--"+orig_text+"-->");
435 | });
436 | }
437 |
438 | /**
439 | * HTMLのIDノードを書き下し文に変換する。(要jQuery)
440 | * @param {string} id HTML node
441 | * @param {boolean} yomi 読み表示
442 | * @param {boolean} hiragana カタカナを平仮名に変換
443 | * @type {none}
444 | */
445 | function kanbun_html_to_kakikudashi (id,yomi,hiragana) {
446 | $(id+"[class=kanbun]").each(function () {
447 | var orig_text=kanbun_orig_text($(this).html());
448 | var new_text=kanbun_to_kakikudashi(orig_text,yomi,hiragana);
449 | $(this).html(new_text+"<!--"+orig_text+"-->");
450 | });
451 | }
452 |
453 |