UNPKG

rubyfy

Version:

Easily write ruby annotations and output it as HTML.

63 lines (59 loc) 2.55 kB
module.exports = class Parser { constructor(opts = {}) { Object.assign(this, opts, { openRt: '(', // fullwidth left parenthesis closeRt: ')', // fullwidth right parenthesis openRb: '((', closeRb: '))', // generated from tools/generate-regex.js autoRb: /[0-9\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u3005\u30F6\u3400-\u4DBF\u4E00-\u9FFF\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uF900-\uFAFF\uFF10-\uFF19\u{104A0}-\u{104A9}\u{11066}-\u{1106F}\u{110F0}-\u{110F9}\u{11136}-\u{1113F}\u{111D0}-\u{111D9}\u{112F0}-\u{112F9}\u{11450}-\u{11459}\u{114D0}-\u{114D9}\u{11650}-\u{11659}\u{116C0}-\u{116C9}\u{11730}-\u{11739}\u{118E0}-\u{118E9}\u{11C50}-\u{11C59}\u{16A60}-\u{16A69}\u{16B50}-\u{16B59}\u{1D7CE}-\u{1D7FF}\u{1E950}-\u{1E959}\u{20000}-\u{2A6DF}\u{2A700}-\u{2CEAF}\u{2F800}-\u{2FA1F}]/u.source }) } parse(text) { if (text == null) { return undefined } let { openRt, closeRt, openRb, closeRb, autoRb } = this let regex = new RegExp( `(?:${openRb}(.*?)${closeRb}|(${autoRb}+)(?!${openRb}(?:.*?)${closeRb}))(?:${openRt}(.*?)${closeRt})?`, 'ug' ) let parsed = [] let regexResult let startIndex = 0 let lastIsString = false let hasRuby const push = x => { if (x === '') { return } let curIsString = typeof x === 'string' if (lastIsString && curIsString) { parsed[parsed.length - 1] = `${parsed[parsed.length - 1]}${x}` } else { parsed.push(x) } lastIsString = curIsString } while ((regexResult = regex.exec(text)) != null) { let [, rb1, rb2, rt] = regexResult let rb = rb1 && rb1.length ? rb1 : rb2 let { index } = regexResult let leadingSubstring = text.substring(startIndex, index) push(leadingSubstring) startIndex = regex.lastIndex if (rt && rt.length) { push({ rb, rt }) hasRuby = true continue } if (rb) { push(rb) } } push(text.substring(startIndex)) parsed.hasRuby = hasRuby return parsed } }