├── LICENSE ├── README.md ├── doc ├── global.html ├── index.html ├── kanbun.js.html ├── scripts │ ├── linenumber.js │ └── prettify │ │ ├── Apache-License-2.0.txt │ │ ├── lang-css.js │ │ └── prettify.js └── styles │ ├── jsdoc-default.css │ ├── prettify-jsdoc.css │ └── prettify-tomorrow.css ├── kanbun.html ├── kanbun.js └── sample.png /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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 漢文訓読JavaScript 2 | 3 | ## 概要 4 | 5 | 漢文訓読JavaScriptは、青空文庫形式で記述した漢文データを「原文」、「訓読」、「読み下し文」などにHTMLで変換するライブラリです。 6 | 7 | ブラウザでも、またはRhinoなどローカル環境でも動作します。 8 | 9 | 例: 10 | 11 | ![例](./sample.png) 12 | 13 | ## 漢文の訓点の例 14 | 15 | 以下の漢文で例を示します。 16 | 17 | 吾嘗終日不食、終夜不寝、以思。 18 | 19 | 訓点を[青空文庫の注記記法](http://kumihan.aozora.gr.jp/kunten.html)で入力します。 20 | 21 | 吾嘗終日不[#レ]食、終夜不[#レ]寝、以思。 22 | 23 | 送り仮名はカタカナ、ひらがなで*漢字と訓点の間に*入れます。 24 | 25 | 吾嘗テ終日不[#レ]食ラハ、終夜不[#レ]寝ネ、以テ思フ。 26 | 27 | 青空文庫形式では、漢文の送り仮名は[#(XX)]という形式で記入することになっていますが、カタカナ・ひらがなの場合は不要です。 28 | (万葉仮名を用いる場合は、[#(XX)]形式も利用可能です。) 29 | 30 | 必要に応じて、読み仮名を「青空文庫形式」で挿入します。 31 | 32 | 吾《われ》嘗《かつ》テ終《しゅう》日《じつ》不《ず》[#レ]食《く》ラハ、 33 | 終夜《しゅうや》不《ず》[#レ]寝《い》ネ、以《もつ》テ思《おも》フ。 34 | 35 | このデータを、"kanbun"クラスのタグに入れると、JavaScript関数の処理対象となります。HTMLタグにidを設定し、個別に制御可能になります。 36 | 37 |

吾《われ》嘗《かつ》テ終《しゅう》日《じつ》不《ず》[#レ]食《く》ラハ、終夜《しゅうや》不《ず》[#レ]寝《い》ネ、以《もつ》テ思《おも》フ。

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 | -------------------------------------------------------------------------------- /doc/global.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Global 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Global

21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 |
29 |

30 | 31 |

32 | 33 |
34 | 35 |
36 |
37 | 38 | 39 | 40 | 41 | 42 | 43 |
44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 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 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 |

Methods

90 | 91 |
92 | 93 |
94 |

kanbun_html_to_kakikudashi(id, yomi, hiragana)

95 | 96 | 97 |
98 |
99 | 100 | 101 |
102 | HTMLのIDノードを書き下し文に変換する。(要jQuery) 103 |
104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 |
Parameters:
112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 |
NameTypeDescription
id 140 | 141 | 142 | string 143 | 144 | 145 | 146 | HTML node
yomi 163 | 164 | 165 | boolean 166 | 167 | 168 | 169 | 読み表示
hiragana 186 | 187 | 188 | boolean 189 | 190 | 191 | 192 | カタカナを平仮名に変換
204 | 205 | 206 | 207 |
208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 |
Source:
228 |
231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 |
239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 |
253 | 254 | 255 | 256 |
257 |

kanbun_html_to_kanbun(id, yomi, okuri, ten, kutou, unicode)

258 | 259 | 260 |
261 |
262 | 263 | 264 |
265 | HTMLのIDノードを漢文に変換する。(要jQuery) 266 |
267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 |
Parameters:
275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 |
NameTypeDescription
id 303 | 304 | 305 | string 306 | 307 | 308 | 309 | HTML node
yomi 326 | 327 | 328 | boolean 329 | 330 | 331 | 332 | 読み仮名表示
okuri 349 | 350 | 351 | boolean 352 | 353 | 354 | 355 | 送り仮名表示
ten 372 | 373 | 374 | boolean 375 | 376 | 377 | 378 | 漢文順序点表示
kutou 395 | 396 | 397 | boolean 398 | 399 | 400 | 401 | 句読点表示
unicode 418 | 419 | 420 | boolean 421 | 422 | 423 | 424 | 漢文順序にユニコードを使用
436 | 437 | 438 | 439 |
440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 |
Source:
460 |
463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 |
471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 |
485 | 486 | 487 | 488 |
489 |

kanbun_to_kakikudashi(text, yomi, hiragana)

490 | 491 | 492 |
493 |
494 | 495 | 496 |
497 | 漢文を書き下し文に変換する。 498 |
499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 |
Parameters:
507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 |
NameTypeDescription
text 535 | 536 | 537 | string 538 | 539 | 540 | 541 | 元データ
yomi 558 | 559 | 560 | boolean 561 | 562 | 563 | 564 | 読み表示
hiragana 581 | 582 | 583 | boolean 584 | 585 | 586 | 587 | カタカナを平仮名に変換
599 | 600 | 601 | 602 |
603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 |
Source:
623 |
626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 |
634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 |
Returns:
646 | 647 | 648 |
649 | HTMLデータ 650 |
651 | 652 | 653 | 654 | 655 | 656 | 657 |
658 | 659 | 660 | 661 |
662 |

kanbun_to_kanbun(text, yomi, okuri, ten, kutou, unicode)

663 | 664 | 665 |
666 |
667 | 668 | 669 |
670 | 漢文をHTMLに変換する。 671 |
672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 |
Parameters:
680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 |
NameTypeDescription
text 708 | 709 | 710 | string 711 | 712 | 713 | 714 | 元データ
yomi 731 | 732 | 733 | boolean 734 | 735 | 736 | 737 | 読み表示
okuri 754 | 755 | 756 | boolean 757 | 758 | 759 | 760 | 送り仮名表示
ten 777 | 778 | 779 | boolean 780 | 781 | 782 | 783 | 漢文順序点表示
kutou 800 | 801 | 802 | boolean 803 | 804 | 805 | 806 | 句読点表示
unicode 823 | 824 | 825 | boolean 826 | 827 | 828 | 829 | 漢文順序にユニコードを使用
841 | 842 | 843 | 844 |
845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 |
Source:
865 |
868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 |
876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 |
Returns:
888 | 889 | 890 |
891 | HTMLデータ 892 |
893 | 894 | 895 | 896 | 897 | 898 | 899 |
900 | 901 |
902 | 903 | 904 | 905 | 906 | 907 |
908 | 909 |
910 | 911 | 912 | 913 | 914 |
915 | 916 | 919 | 920 |
921 | 922 | 925 | 926 | 927 | 928 | 929 | -------------------------------------------------------------------------------- /doc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Index 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Index

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |

29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
51 | 52 |
53 |

54 | kanbun-javascript/kanbun.js 55 |

56 | 57 |
58 | 59 |
60 |
61 | 62 | 63 | 64 | 65 |
漢文訓読 JavaScript -- 66 | 注記を施した漢文を、漢文または書き下し文のHTMLに変換する。
67 | 68 | 69 | 70 |
71 | 72 | 73 | 74 |
Version:
75 |
  • 0.1
76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |
Author:
86 |
87 |
    88 |
  • KAWABATA, Taichi
  • 89 |
90 |
91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 |
Source:
101 |
104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 |
112 | 113 | 114 | 115 | 116 |
117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 |
136 | 137 |
138 | 139 | 140 | 141 | 142 |
143 | 144 | 147 | 148 |
149 | 150 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /doc/kanbun.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: kanbun.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: kanbun.js

21 | 22 | 23 | 24 | 25 | 26 |
27 |
28 |
/** @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 |
454 |
455 | 456 | 457 | 458 | 459 |
460 | 461 | 464 | 465 |
466 | 467 | 470 | 471 | 472 | 473 | 474 | 475 | -------------------------------------------------------------------------------- /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/Apache-License-2.0.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /doc/scripts/prettify/prettify.js: -------------------------------------------------------------------------------- 1 | var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; 2 | (function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= 3 | [],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), 9 | l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, 10 | q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, 11 | q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, 12 | "");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), 13 | a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} 14 | for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], 18 | "catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], 19 | H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], 20 | J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ 21 | I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), 22 | ["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", 23 | /^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), 24 | ["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", 25 | hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= 26 | !k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p 2 | 3 | 4 | 漢文訓読 JavaScript 5 | 6 | 7 | 13 | 23 | 24 | 25 |

漢文訓読 JavaScript

26 |

サンプル

27 | 28 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 49 | 50 | 51 | 52 | 54 | 55 | 56 | 57 | 59 | 60 | 61 | 62 | 64 | 65 | 66 | 67 | 69 | 70 | 71 | 72 | 74 | 75 | 76 | 77 | 79 | 80 | 81 | 82 | 84 | 85 | 86 | 87 |
漢文解説
秦王、以テ[#二]十五城ヲ[#一]請フ[#レ]易《か》ヘンコトヲ[#二]寡人之璧ニ[#一]。可キヤ[#レ]予《あた》フ不《いな》ヤ。レ点や一・二点はかならず送りがなの後ろに付加します。
吾《われ》嘗《かつ》テ終《しゅう》日《じつ》不〈ズ〉[#レ]食《く》ラハ、終《しゅう》夜《や》不〈ズ〉[#レ]寝《い》ネ、以《もつ》テ思《おも》フ。書き下しの時に漢字ではなく読み仮名のみを表示させたい場合は、ルビに"《》"ではなく"〈〉"を用います。
使〈シ〉メヨ[#人]籍《せき》ヲシテ誠《まこと》ニ不〈〉〈ズ〉[#乙]以《もつ》テ[#下]蓄《やしな》ヒ[#二]妻子ヲ[#一]憂《うれ》フルヲ[#中]飢《き》寒《かん》ヲ[#上]乱サ[#甲レ]心ヲ、有リテ[#レ]銭《ぜに》以《もつ》テ済《な》サ[#地]医薬ヲ[#天]。対応する訓点には、上中下・甲乙丙丁・天地人があります。
未《いま》ダ〈ざ〉ル[#レ]足《た》ラ[#二]与《とも》ニ議スルニ[#一]也。再読文は、『【漢字】《【よみ】》【送り仮名】〈【再読よみ】〉【再読送り仮名】』で表現します。
盍《なん》ゾ〈ザ〉ル[#レ]反《かへ》ラ[#二]其ノ本ニ[#一]矣〈〉。置き字は、その漢字の後ろに空の〈〉を付します。
盍《なん》[#(ゾ)]〈ザ〉[#(ル)][#レ]反《かへ》[#(ラ)][#二]其[#(ノ)]本[#(ニ)][#一]矣〈〉。送り仮名は、[#(…)]の記法でも記述できます。再読文字の送り仮名も同様に書けます。
引キテ[#レ]酒ヲ且ニ〈ス〉[#レ]飲マント[#レ]之ヲ。再読文字で、最初の読みがない場合は省略できます。
孤之〈ノ〉有ルハ[#二]孔明[#一]、猶《な》ホ〈ゴト〉シ[#二]魚之〈ノ〉有ルガ[#一レ]水。再読文字で、再読文字に送り仮名がある場合は、〈…〉の後ろに送り仮名を入れます。
88 |
89 |
90 |
91 |
92 |
93 |
94 | 95 | 96 | -------------------------------------------------------------------------------- /kanbun.js: -------------------------------------------------------------------------------- 1 | /** @fileoverview 2 | * 漢文訓読 JavaScript -- 3 | * 注記を施した漢文を、漢文または書き下し文のHTMLに変換する。 4 | * 5 | * @author Teruyuki Kobayashi 6 | * @author KAWABATA, Taichi 7 | * @version 0.2 8 | */ 9 | 10 | /* 11 | 漢文注記記法: 12 | 漢文 := 漢文単位+ 13 | 漢文単位 := 漢字単位 読み仮名? 送り仮名* 再読仮名? 再読送り* 竪点? 訓点? 14 | 漢字単位 := 漢字 異体字選択? | 句読点 15 | 漢字 := "[㐀-\9fff]|[豈-\faff]|[\ud840-\ud87f][\udc00-\udfff]" 16 | 句読点 := "[。、]" 17 | 異体字選択 := "\udb40[\udd00-\uddef]" (異体字選択子:U+E0100...U+E01EF) 18 | 読み仮名 := 表示読み | 非表示読み 19 | 表示読み := "《" 仮名漢字* "》" 20 | ※ 表示読みは、漢文・書き下し文の両方で漢字の脇に読みを表示する。 21 | 仮名漢字 := 仮名 | 漢字 22 | 仮名 := [ぁ-ヿ] 23 | 非表示読み := "〈" 仮名漢字* "〉" 24 | ※ 非表示読みは、漢文では読みを表示せず、書き下し文では読みのみ表示する。 25 | ※ 置き字は非表示読みを空の〈〉として表現する。 26 | 送り仮名 := 仮名+ | "[#(" 仮名漢字+ ")]" 27 | ※ 万葉仮名がある場合は、後者を使用する。 28 | 再読仮名 := 表示読み | 非表示読み 29 | 再読送り := 仮名+ | "[#(" 仮名漢字+ ")]" 30 | ※ 万葉仮名がある場合は、後者を使用する。 31 | 竪点 := "‐" ※ (仮定)竪点は2つ連続しない。 32 | 訓点 := "[#" 訓点文字 "]" 33 | 訓点文字 := 順序点 | "[一上天甲]?レ" 34 | 順序点 := [一二三四上中下天地人甲乙丙丁] 35 | */ 36 | 37 | function kanbun_regex_setup() { 38 | const kanji = "[㐀-\u9fff]|[豈-\ufaff]|[\ud840-\ud87f][\udc00-\udfff]"; 39 | const vselector = "\udb40[\udd00-\uddef]"; 40 | const kutouten = "[。、]"; 41 | const kanji_unit = "(?:" + kanji+"(?:"+vselector+")?|"+kutouten+")"; 42 | const kana = "[ぁ-ヿ]"; 43 | const kana_kanji = kana+"|(?:"+kanji_unit+")"; 44 | const hyouji = "《(?:"+ kana_kanji + ")*》"; 45 | const hihyouji = "〈(?:"+ kana_kanji + ")*〉"; 46 | const yomi = "(?:" + hyouji +")|(?:" + hihyouji +")"; 47 | const okuri = kana + "+|[#((?:" + kana_kanji + ")+)]"; 48 | const saidoku = "(?:" + hyouji +")|(?:" + hihyouji +")"; 49 | const saiokuri = kana + "+|[#((?:" + kana_kanji + ")+)]"; 50 | const tateten = "‐"; 51 | const junjo = "[一二三四上中下天地人甲乙丙丁]"; 52 | const kunten = "[#(?:"+junjo+"|[一上天甲]?レ)]"; 53 | 54 | const kanbun = "(" +kanji_unit +")(" + yomi + ")?(" + okuri + ")?(" + saidoku + 55 | ")?(" + saiokuri + ")?(" + tateten +")?(" + kunten + ")?"; 56 | return new RegExp (kanbun); 57 | } 58 | 59 | // ******** 基本機能 ******** 60 | 61 | /** 62 | * 配列からの要素の削除 63 | * @private 64 | */ 65 | Array.prototype.remove = function() { 66 | let what, a = arguments, L = a.length, ax; 67 | while (L && this.length) { 68 | what = a[--L]; 69 | while ((ax = this.indexOf(what)) !== -1) { 70 | this.splice(ax, 1); 71 | } 72 | } 73 | return this; 74 | }; 75 | 76 | /** 77 | * 配列の複製(配列要素の複製はしない) 78 | * @private 79 | */ 80 | Array.prototype.clone = function(){ 81 | return Array.apply(null,this); 82 | }; 83 | 84 | 85 | // ******** 漢文の分割と関連ツール ******** 86 | 87 | /** 88 | * 漢文を漢字単位に分割する。 89 | * @private 90 | * @param {string} text 元データ 91 | * @returns matchの配列 92 | * @type {Array} 93 | */ 94 | function kanbun_split(text) { 95 | let result = []; 96 | const kanbun_regex = kanbun_regex_setup(); 97 | while (text.length > 0) { 98 | const match = text.match(kanbun_regex); 99 | if (match == null) { 100 | console.log(text); 101 | alert("Parse Error! see console log."); 102 | return -1; 103 | } 104 | if (match["index"]!=0) { 105 | console.log(match); 106 | alert("Parse Error! see console log."); 107 | return -1; 108 | } 109 | text = text.substring(match[0].length); 110 | result = result.concat([match]); 111 | } 112 | return result; 113 | } 114 | 115 | /** 116 | * match の漢字・読みの部分をHTMLにする。 117 | * @private 118 | * @param {Array} match 119 | * @param {boolean} yomi_p 漢字に読みを表示する。 120 | * @param {boolean} kanbun_p 漢文ならtrue, 書き下し文ならfalse。 121 | * trueなら、〈…〉は、漢字のみを表示し、falseなら仮名のみを表示する。 122 | * @param {boolean} saidoku_p 再読文字をHTML5 左ルビ仕様で表示する。 123 | * @returns {string} 読み付き漢字。rubyがfalseか読みがない場合は漢字のみ。 124 | * 〈…〉は kanbun がtrueなら漢字のみ。falseなら読みのみ。 125 | * 《…》ならタグで返す。 126 | */ 127 | // TODO 再読文字の左ルビは未対応。 128 | function kanbun_match_yomi(match,yomi_p,kanbun_p) { 129 | const kanji = match[1]; 130 | const yomi = match[2]; 131 | const saidoku = match[4]; 132 | // 特殊ケース 133 | if (yomi != undefined && yomi.match(/^〈/)) { 134 | if (kanbun_p) { 135 | return kanji; 136 | } else { 137 | return yomi.slice(1,-1); 138 | } 139 | } else if (!yomi_p) return kanji; 140 | // ruby 141 | if (yomi == undefined && saidoku == undefined) {return kanji;} 142 | const result=""+kanji+ 143 | ((yomi == undefined)? 144 | "":""+yomi.slice(1,-1)+"")+ 145 | // 書き下しでは再読文字にルビは入れない。 146 | ((kanbun_p == false || saidoku == undefined)? 147 | "":""+saidoku.slice(1,-1)+"")+ 148 | ""; 149 | return result; 150 | } 151 | 152 | const kanbun_unicode = {"‐":"㆐","レ":"㆑","一":"㆒","二":"㆓", 153 | "三":"㆔","四":"㆕","上":"㆖","中":"㆗", 154 | "下":"㆘","甲":"㆙","乙":"㆚","丙":"㆛", 155 | "丁":"㆜","天":"㆝","地":"㆞","人":"㆟"}; 156 | 157 | /** 158 | * match の送り仮名部分を返す。 159 | * (送り仮名がない場合は空文字を返す。) 160 | * @private 161 | * @param {Array} match 162 | * @returns {string} 送り仮名部分 163 | */ 164 | function kanbun_match_okuri (match) { 165 | const okuri = (match[3] != undefined)? match[3] : ""; 166 | return (okuri.match(/^[#(/)) ? okuri.slice(3,-2):okuri; 167 | } 168 | 169 | /** 170 | * match の送り・訓点部分をHTMLにする。(漢文訓読) 171 | * @private 172 | * @param {Array} match 173 | * @param {boolean} unicode_p 訓点をUniocodeで表示する 174 | * @param {boolean} okuri_p 送り仮名を表示する 175 | * @param {boolean} ten_p 訓点を表示する 176 | * @returns {string} 訓点HTML。 177 | */ 178 | function kanbun_match_okuri_ten(match,unicode_p,okuri_p,ten_p) { 179 | // 送り文字 180 | let okuri = (okuri_p == false) ? "" : kanbun_match_okuri(match); 181 | let tate = ((ten_p == false) || (match[6] == undefined))? "" : match[6]; 182 | let ten = ((ten_p == false) || (match[7] == undefined))? "" : match[7].slice(2,-1); 183 | 184 | if (okuri == "" && ten != "") okuri = " "; 185 | if (okuri != "" && ten == "") ten = " "; 186 | if (okuri != "" && ten != "") { 187 | return "
" 188 | + okuri + "
" + ten + "
"; 189 | // TODO tate shori. 190 | } else 191 | return ""; 192 | } 193 | 194 | // ******** 漢文 ******** 195 | 196 | /** 197 | * 文字列中のカタカナを平仮名にする。 198 | * @private 199 | * @param {string} text 元文字列 200 | * @returns 変換文字列 201 | * @type string 202 | */ 203 | function kanbun_katakana_to_hiragana (text) { 204 | const result = text.replace(/[ァ-ヶ]/g, whole=>{ 205 | const hiragana = whole.charCodeAt(0)-96; 206 | return String.fromCharCode(hiragana); 207 | }); 208 | return result; 209 | } 210 | 211 | /** 212 | * 句読点の前のを除去する。 213 | * @private 214 | * @param {string} html 元HTML 215 | * @returns 変換HTML 216 | * @type string 217 | */ 218 | function kanbun_remove_kutou_break(html) { 219 | const result = html.replace(/<\/nobr>([。、])/g,"$1"); 220 | return result; 221 | } 222 | 223 | /** 224 | * 漢文をHTMLに変換する。 225 | * @param {string} text 元データ 226 | * @param {boolean} yomi 読み表示 227 | * @param {boolean} okuri 送り仮名表示 228 | * @param {boolean} ten 漢文順序点表示 229 | * @param {boolean} kutou 句読点表示 230 | * @param {boolean} unicode 漢文順序にユニコードを使用 231 | * @returns HTMLデータ 232 | * @type string 233 | */ 234 | function kanbun_to_kanbun (text, yomi, okuri, ten, kutou, unicode) { 235 | const split = kanbun_split(text); 236 | let result = ""; 237 | split.forEach(match=>{ 238 | if (!(!kutou && match[1].match(/[。、]/))) { 239 | const kanji_part = kanbun_match_yomi(match,yomi,true); 240 | const okuri_ten_part = kanbun_match_okuri_ten(match,unicode,okuri,ten); 241 | result+=""+ kanji_part + okuri_ten_part +""; 242 | } 243 | }); 244 | return kanbun_remove_kutou_break(result); 245 | } 246 | 247 | // ******** 書き下し文 ******** 248 | 249 | /** 250 | * 漢文の順序を書き下し文の順序の分割した配列に変換する。 251 | * @private 252 | * @param {string} text 入力 253 | * @param {boolean} unicode 訓点文字 254 | * @returns {array} 順序を入れ替えた配列 255 | */ 256 | function kanbun_reorder(text){ 257 | let kunten_flag = "", reten_flag = false, tate_flag = false; 258 | let split_text = kanbun_split(text); 259 | let kanbun_two = null, kanbun_three = null, kanbun_four = null; 260 | let kanbun_middle = null, kanbun_down = null; 261 | let kanbun_otsu = null, kanbun_hei = null, kanbun_tei = null; 262 | let kanbun_chi = null, kanbun_jin = null; 263 | let stock = new Array(); 264 | let result = new Array(); 265 | 266 | split_text.forEach(match=>{ 267 | const tateten = (typeof match[6] != 'undefined')?match[6]:""; 268 | const kunten = (typeof match[7] != 'undefined')?match[7].slice(2,-1):""; 269 | const saidoku = match[4]; 270 | const saiyomi = match[5]; 271 | if (typeof saidoku != 'undefined') { 272 | // 再読処理。matchをそのままresultに入れ、 273 | // matchはclone()してそこの読み・送りを再読・再送りにする。 274 | result.push(match); 275 | match = match.clone(); 276 | match[2] = saidoku; 277 | match[3] = saiyomi; 278 | } 279 | // 前の漢字のレ点・竪点への対応 280 | if (reten_flag) { 281 | stock.unshift(match); 282 | reten_flag = false; 283 | } else if (tate_flag) { 284 | stock.push(match); 285 | tate_flag = false; 286 | } else { 287 | stock = new Array(match); 288 | } 289 | // 訓点処理 290 | if (kunten.match(/[一二三四上中下天地人甲乙丙丁]/)) { 291 | kunten_flag = RegExp.lastMatch; 292 | } 293 | if (kunten.match(/レ/)) { 294 | reten_flag = true; // 「一レ」の場合は reten_flag だけ true にして次に。 295 | } else if (tateten == "‐") { 296 | tate_flag = true; 297 | } else if (kunten_flag.length > 0) { 298 | // 現在漢字にレ点・竪点がない場合は訓点処理に入る 299 | if (kunten_flag.match(/一/)) { 300 | result = result.concat(stock).concat(kanbun_two); 301 | result = result.concat(kanbun_three).concat(kanbun_four); 302 | kanbun_two = null; 303 | kanbun_three = null; 304 | kanbun_four = null;} 305 | else if (kunten_flag.match(/二/)) kanbun_two = stock; 306 | else if (kunten_flag.match(/三/)) kanbun_three = stock; 307 | else if (kunten_flag.match(/四/)) kanbun_four = stock; 308 | else if (kunten_flag.match(/上/)) { 309 | result = result.concat(stock).concat(kanbun_middle); 310 | result = result.concat(kanbun_down); 311 | kanbun_middle=null; 312 | kanbun_down=null;} 313 | else if (kunten_flag.match(/中/)) kanbun_middle = stock; 314 | else if (kunten_flag.match(/下/)) kanbun_down = stock; 315 | else if (kunten_flag.match(/甲/)) { 316 | result = result.concat(stock).concat(kanbun_otsu); 317 | result = result.concat(kanbun_hei).concat(kanbun_tei); 318 | kanbun_otsu = null; 319 | kanbun_hei = null; 320 | kanbun_tei = null; 321 | } 322 | else if (kunten_flag.match(/乙/)) kanbun_otsu = stock; 323 | else if (kunten_flag.match(/丙/)) kanbun_hei = stock; 324 | else if (kunten_flag.match(/丁/)) kanbun_tei = stock; 325 | else if (kunten_flag.match(/天/)) { 326 | result = result.concat(stock).concat(kanbun_chi); 327 | result = result.concat(kanbun_jin); 328 | kanbun_chi = null; 329 | kanbun_jin = null;} 330 | else if (kunten_flag.match(/地/)) kanbun_chi = stock; 331 | else if (kunten_flag.match(/人/)) kanbun_jin = stock; 332 | else console.log ("error! match="+match); 333 | kunten_flag=""; 334 | } else { 335 | result = result.concat(stock); 336 | } 337 | }); 338 | return result.remove(null); 339 | } 340 | 341 | /** 342 | * 漢文を書き下し文に変換する。 343 | * @param {string} text 元データ 344 | * @param {boolean} yomi 読み表示 345 | * @param {boolean} hiragana カタカナを平仮名に変換 346 | * @returns HTMLデータ 347 | * @type string 348 | */ 349 | function kanbun_to_kakikudashi(text,yomi,hiragana){ 350 | const reordered = kanbun_reorder(text); 351 | let result=""; 352 | reordered.forEach(match=>{ 353 | const kanji_part = kanbun_match_yomi(match,yomi,false); 354 | const okuri_part = kanbun_match_okuri(match); 355 | result+=""+kanji_part+okuri_part +""; 356 | }); 357 | if (hiragana) result=kanbun_katakana_to_hiragana(result); 358 | return kanbun_remove_kutou_break(result); 359 | } 360 | 361 | 362 | // ******** HTML処理 ******** 363 | // 364 | // 元のデータを とコメントに入れて保存する。 365 | // 366 | 367 | /** 368 | * text中の の部分を返す。 369 | * @private 370 | */ 371 | function kanbun_orig_text (text) { 372 | let orig_text; 373 | if (text.match(//)) { 374 | orig_text = RegExp.$1; 375 | } else { 376 | orig_text = text; 377 | } 378 | return orig_text; 379 | }; 380 | 381 | /** 382 | * HTMLのIDノードの、 で保存されている原データをもとに戻す。 383 | * @private 384 | * @param {string} id HTML node 385 | * @returns {none} 386 | */ 387 | function kanbun_html_to_original (id) { 388 | document.querySelectorAll(id+"[class=kanbun]").forEach(elm=>{ 389 | const orig_text = kanbun_orig_text(elm.innerHTML); 390 | elm.innerHTML = orig_text; 391 | }); 392 | } 393 | 394 | /** 395 | * HTMLのIDノードを漢文に変換する。 396 | * @param {string} id HTML node 397 | * @param {boolean} yomi 読み仮名表示 398 | * @param {boolean} okuri 送り仮名表示 399 | * @param {boolean} ten 漢文順序点表示 400 | * @param {boolean} kutou 句読点表示 401 | * @param {boolean} unicode 漢文順序にユニコードを使用 402 | * @type {none} 403 | */ 404 | function kanbun_html_to_kanbun (id,yomi,okuri,ten,kutou,unicode) { 405 | document.querySelectorAll(id+"[class=kanbun]").forEach(elm=>{ 406 | const orig_text = kanbun_orig_text(elm.innerHTML); 407 | const new_text = kanbun_to_kanbun(orig_text,yomi,okuri,ten,kutou,unicode); 408 | elm.innerHTML = new_text+""; 409 | }); 410 | } 411 | 412 | /** 413 | * HTMLのIDノードを書き下し文に変換する。 414 | * @param {string} id HTML node 415 | * @param {boolean} yomi 読み表示 416 | * @param {boolean} hiragana カタカナを平仮名に変換 417 | * @type {none} 418 | */ 419 | function kanbun_html_to_kakikudashi (id,yomi,hiragana) { 420 | document.querySelectorAll(id+"[class=kanbun]").forEach(elm=>{ 421 | const orig_text = kanbun_orig_text(elm.innerHTML); 422 | const new_text = kanbun_to_kakikudashi(orig_text,yomi,hiragana); 423 | elm.innerHTML = new_text+""; 424 | }); 425 | } -------------------------------------------------------------------------------- /sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kawabata/kanbun-javascript/66481002d51b405b2a75de9ff451a44c21f6753a/sample.png --------------------------------------------------------------------------------