/* ***** BEGIN LICENSE BLOCK ***** Copyright (c) 2018-2020 Famibee (famibee.blog38.fc2.com) This software is released under the MIT License. http://opensource.org/licenses/mit-license.php ** ***** END LICENSE BLOCK ***** */ import {HArg, IPutCh} from './CmnInterface'; export interface IAutoPage { (idx: number, str: string): void; } export class RubySpliter { private static sesame = 'ヽ'; setting(hArg: HArg) {if (hArg.sesame) RubySpliter.sesame = hArg.sesame;} getSesame() {return RubySpliter.sesame;} private putCh : IPutCh = ()=> {}; init(putCh: IPutCh) {this.putCh = putCh;} /* ★Unicodeで「漢字」の正規表現 – ものかの http://tama-san.com/kanji-regex/ 2E80..2FDF CJK部首補助+康熙部首 3005 々(漢字の踊り字) 3007 〇(漢数字のゼロ) 303B 〻(漢字の踊り字) 3400..4DBF CJK統合漢字拡張A 4E00..9FFF CJK統合漢字 F900..FAFF CJK互換漢字 20000..2FFFF CJK統合漢字拡張B〜F+CJK互換漢字追加+念のためU+2FFFFまで [\x{2E80}-\x{2FDF}々〇〻\x{3400}-\x{4DBF}\x{4E00}-\x{9FFF}\x{F900}-\x{FAFF}\x{20000}-\x{2FFFF}] [\u2E80-\u2FDF々〇〻\u3400-\u4DBF\u4E00-\u9FFF\uF900-\uFAFF\u20000-\u2FFFF] [⺀-⿟々〇〻㐀-䶿一-鿿豈-﫿\u20000-\u2FFFF] // 含まれない文字がある [⺀-⿟々〇〻㐀-鿿豈-﫿\u20000-\u2FFFF] // ヽ--30FD が変に引っかかる。多分\u2000-\u2FFF解釈 \\u{20000}-\\u{2FFFF} // 五桁だとエラー */ private static REG_RUBY : RegExp; static setEscape(ce: string) { // 577 match 14303 step(~10ms) https://regex101.com/r/YmT3m1/2 RubySpliter.REG_RUBY = new RegExp( `${ce ?`(?\\${ce}\\S)|` :''}`+ `|(?[^《\\n]+)《(?[^》\\n]+)》`+ `|(?:(?[⺀-⿟々〇〻㐀-鿿豈-﫿]+[ぁ-ヿ]*|[^ |《》\\n])`+ `《(?[^》\\n]+)》)`+ `|(?`+ `[\uD800-\uDBFF][\uDC00-\uDFFF]`+ `|[^ |《》]+(?=|)`+ `|[^ |《》]*[ぁ-ヿ](?=[⺀-⿟々〇〻㐀-鿿豈-﫿]+《)`+ `|.)`, 'gs' ); } putTxt(text: string) { let e: any = null; // 全ループリセットかかるので不要 .lastIndex = 0; // /gなので必要 while (e = RubySpliter.REG_RUBY.exec(text)) { const g = e?.groups; if (! g) continue; const ruby: string = g.ruby; if (ruby) {this.putTxtRb(g.str, ruby); continue;} const kan_ruby: string = g.kan_ruby; if (kan_ruby) {this.putTxtRb(g.kan, kan_ruby); continue;} if (g.ce) {this.putCh(g.ce.slice(1), ''); continue} const txt = g.txt ?? ''; const a: string[] = Array.from(txt); // txt.split('')や [...txt] はサロゲートペアで問題 const len = a.length; for (let i=0; i len) ?lenR :len; for (let i=0; i