diff options
author | Alex Yatskov <alex@foosoft.net> | 2017-08-26 12:36:56 -0700 |
---|---|---|
committer | Alex Yatskov <alex@foosoft.net> | 2017-08-26 12:36:56 -0700 |
commit | 65b679caeb7ae7261ea6f2ba76d1b14ff1d68c5c (patch) | |
tree | 16ff39b4730b5c84b0952a0cdd10b09e86d6a5b3 /ext/mixed/js/japanese.js | |
parent | 4325f325975614dc728a14fec0478654b1b43777 (diff) | |
parent | dbe6a16ca4db10b1c3ff51d0d79b563ff2bb7aeb (diff) |
Merge branch 'master' into firefox-amo
Diffstat (limited to 'ext/mixed/js/japanese.js')
-rw-r--r-- | ext/mixed/js/japanese.js | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/ext/mixed/js/japanese.js b/ext/mixed/js/japanese.js index c11e955b..9f401da7 100644 --- a/ext/mixed/js/japanese.js +++ b/ext/mixed/js/japanese.js @@ -38,3 +38,51 @@ function jpKatakanaToHiragana(text) { return result; } + +function jpDistributeFurigana(expression, reading) { + const fallback = [{furigana: reading, text: expression}]; + if (!reading) { + return fallback; + } + + const segmentize = (reading, groups) => { + if (groups.length === 0) { + return []; + } + + const group = groups[0]; + if (group.mode === 'kana') { + if (reading.startsWith(group.text)) { + const readingUsed = reading.substring(0, group.text.length); + const readingLeft = reading.substring(group.text.length); + const segs = segmentize(readingLeft, groups.splice(1)); + if (segs) { + return [{text: readingUsed}].concat(segs); + } + } + } else { + for (let i = reading.length; i >= group.text.length; --i) { + const readingUsed = reading.substring(0, i); + const readingLeft = reading.substring(i); + const segs = segmentize(readingLeft, groups.slice(1)); + if (segs) { + return [{text: group.text, furigana: readingUsed}].concat(segs); + } + } + } + }; + + const groups = []; + let modePrev = null; + for (const c of expression) { + const modeCurr = jpIsKanji(c) || c.charCodeAt(0) === 0x3005 /* noma */ ? 'kanji' : 'kana'; + if (modeCurr === modePrev) { + groups[groups.length - 1].text += c; + } else { + groups.push({mode: modeCurr, text: c}); + modePrev = modeCurr; + } + } + + return segmentize(reading, groups) || fallback; +} |