Move Japanese utility functions out of display-generator.js
This commit is contained in:
parent
cbc7e2646d
commit
0d80fcdf86
@ -305,7 +305,7 @@ class DisplayGenerator {
|
||||
|
||||
createPitch(details) {
|
||||
const {expressions, reading, position, tags} = details;
|
||||
const morae = DisplayGenerator._jpGetKanaMorae(reading);
|
||||
const morae = jp.getKanaMorae(reading);
|
||||
|
||||
const node = this._templateHandler.instantiate('term-pitch-accent');
|
||||
|
||||
@ -324,8 +324,8 @@ class DisplayGenerator {
|
||||
n = node.querySelector('.term-pitch-accent-characters');
|
||||
for (let i = 0, ii = morae.length; i < ii; ++i) {
|
||||
const mora = morae[i];
|
||||
const highPitch = DisplayGenerator._jpIsMoraPitchHigh(i, position);
|
||||
const highPitchNext = DisplayGenerator._jpIsMoraPitchHigh(i + 1, position);
|
||||
const highPitch = jp.isMoraPitchHigh(i, position);
|
||||
const highPitchNext = jp.isMoraPitchHigh(i + 1, position);
|
||||
|
||||
const n1 = this._templateHandler.instantiate('term-pitch-accent-character');
|
||||
const n2 = n1.querySelector('.term-pitch-accent-character-inner');
|
||||
@ -358,8 +358,8 @@ class DisplayGenerator {
|
||||
|
||||
const pathPoints = [];
|
||||
for (let i = 0; i < ii; ++i) {
|
||||
const highPitch = DisplayGenerator._jpIsMoraPitchHigh(i, position);
|
||||
const highPitchNext = DisplayGenerator._jpIsMoraPitchHigh(i + 1, position);
|
||||
const highPitch = jp.isMoraPitchHigh(i, position);
|
||||
const highPitchNext = jp.isMoraPitchHigh(i + 1, position);
|
||||
const graphic = (highPitch && !highPitchNext ? '#term-pitch-accent-graph-dot-downstep' : '#term-pitch-accent-graph-dot');
|
||||
const x = `${i * 50 + 25}`;
|
||||
const y = highPitch ? '25' : '75';
|
||||
@ -376,7 +376,7 @@ class DisplayGenerator {
|
||||
|
||||
pathPoints.splice(0, ii - 1);
|
||||
{
|
||||
const highPitch = DisplayGenerator._jpIsMoraPitchHigh(ii, position);
|
||||
const highPitch = jp.isMoraPitchHigh(ii, position);
|
||||
const x = `${ii * 50 + 25}`;
|
||||
const y = highPitch ? '25' : '75';
|
||||
const use = document.createElementNS(svgns, 'use');
|
||||
@ -532,30 +532,4 @@ class DisplayGenerator {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static _jpGetKanaMorae(text) {
|
||||
// This function splits Japanese kana reading into its individual mora
|
||||
// components. It is assumed that the text is well-formed.
|
||||
const smallKanaSet = DisplayGenerator._smallKanaSet;
|
||||
const morae = [];
|
||||
let i;
|
||||
for (const c of text) {
|
||||
if (smallKanaSet.has(c) && (i = morae.length) > 0) {
|
||||
morae[i - 1] += c;
|
||||
} else {
|
||||
morae.push(c);
|
||||
}
|
||||
}
|
||||
return morae;
|
||||
}
|
||||
|
||||
static _jpCreateSmallKanaSet() {
|
||||
return new Set(Array.from('ぁぃぅぇぉゃゅょゎァィゥェォャュョヮ'));
|
||||
}
|
||||
|
||||
static _jpIsMoraPitchHigh(moraIndex, pitchAccentPosition) {
|
||||
return pitchAccentPosition === 0 ? (moraIndex > 0) : (moraIndex < pitchAccentPosition);
|
||||
}
|
||||
}
|
||||
|
||||
DisplayGenerator._smallKanaSet = DisplayGenerator._jpCreateSmallKanaSet();
|
||||
|
@ -64,6 +64,8 @@ const jp = (() => {
|
||||
[0xffe0, 0xffee] // Currency markers
|
||||
];
|
||||
|
||||
const SMALL_KANA_SET = new Set(Array.from('ぁぃぅぇぉゃゅょゎァィゥェォャュョヮ'));
|
||||
|
||||
|
||||
// Character code testing functions
|
||||
|
||||
@ -112,6 +114,26 @@ const jp = (() => {
|
||||
}
|
||||
|
||||
|
||||
// Mora functions
|
||||
|
||||
function isMoraPitchHigh(moraIndex, pitchAccentPosition) {
|
||||
return pitchAccentPosition === 0 ? (moraIndex > 0) : (moraIndex < pitchAccentPosition);
|
||||
}
|
||||
|
||||
function getKanaMorae(text) {
|
||||
const morae = [];
|
||||
let i;
|
||||
for (const c of text) {
|
||||
if (SMALL_KANA_SET.has(c) && (i = morae.length) > 0) {
|
||||
morae[i - 1] += c;
|
||||
} else {
|
||||
morae.push(c);
|
||||
}
|
||||
}
|
||||
return morae;
|
||||
}
|
||||
|
||||
|
||||
// Exports
|
||||
|
||||
return {
|
||||
@ -119,6 +141,8 @@ const jp = (() => {
|
||||
isCodePointKana,
|
||||
isCodePointJapanese,
|
||||
isStringEntirelyKana,
|
||||
isStringPartiallyJapanese
|
||||
isStringPartiallyJapanese,
|
||||
isMoraPitchHigh,
|
||||
getKanaMorae
|
||||
};
|
||||
})();
|
||||
|
@ -392,6 +392,59 @@ function testDistributeFuriganaInflected() {
|
||||
}
|
||||
}
|
||||
|
||||
function testIsMoraPitchHigh() {
|
||||
const data = [
|
||||
[[0, 0], false],
|
||||
[[1, 0], true],
|
||||
[[2, 0], true],
|
||||
[[3, 0], true],
|
||||
|
||||
[[0, 1], true],
|
||||
[[1, 1], false],
|
||||
[[2, 1], false],
|
||||
[[3, 1], false],
|
||||
|
||||
[[0, 2], true],
|
||||
[[1, 2], true],
|
||||
[[2, 2], false],
|
||||
[[3, 2], false],
|
||||
|
||||
[[0, 3], true],
|
||||
[[1, 3], true],
|
||||
[[2, 3], true],
|
||||
[[3, 3], false],
|
||||
|
||||
[[0, 4], true],
|
||||
[[1, 4], true],
|
||||
[[2, 4], true],
|
||||
[[3, 4], true]
|
||||
];
|
||||
|
||||
for (const [[moraIndex, pitchAccentPosition], expected] of data) {
|
||||
const actual = jp.isMoraPitchHigh(moraIndex, pitchAccentPosition);
|
||||
assert.strictEqual(actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
function testGetKanaMorae() {
|
||||
const data = [
|
||||
['かこ', ['か', 'こ']],
|
||||
['かっこ', ['か', 'っ', 'こ']],
|
||||
['カコ', ['カ', 'コ']],
|
||||
['カッコ', ['カ', 'ッ', 'コ']],
|
||||
['コート', ['コ', 'ー', 'ト']],
|
||||
['ちゃんと', ['ちゃ', 'ん', 'と']],
|
||||
['とうきょう', ['と', 'う', 'きょ', 'う']],
|
||||
['ぎゅう', ['ぎゅ', 'う']],
|
||||
['ディスコ', ['ディ', 'ス', 'コ']]
|
||||
];
|
||||
|
||||
for (const [text, expected] of data) {
|
||||
const actual = jp.getKanaMorae(text);
|
||||
vm.assert.deepStrictEqual(actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function main() {
|
||||
testIsCodePointKanji();
|
||||
@ -408,6 +461,8 @@ function main() {
|
||||
testConvertAlphabeticToKana();
|
||||
testDistributeFurigana();
|
||||
testDistributeFuriganaInflected();
|
||||
testIsMoraPitchHigh();
|
||||
testGetKanaMorae();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user