Katakana to hiragana conversion options (#1965)

* Refactor convertKatakanaToHiragana

* Add keepProlongedSoundMarks option

* Test keepProlongedSoundMarks option

* Refactor

* Add keepProlongedSoundMarks option to hiragana handlebars helper

* Update documentation
This commit is contained in:
toasted-nutbread 2021-09-27 18:19:53 -04:00 committed by GitHub
parent 729abbf561
commit b784e5b11a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 18 deletions

View File

@ -786,11 +786,14 @@ Converts katakana text to hiragana.
<details>
<summary>Syntax:</summary>
<code>{{#hiragana <i>value</i>}}{{/hiragana}}</code><br>
<code>{{#hiragana}}<i>value</i>{{/hiragana}}</code><br>
<code>{{#hiragana <i>value</i> <i>[keepProlongedSoundMarks=true|false]</i>}}{{/hiragana}}</code><br>
<code>{{#hiragana <i>[keepProlongedSoundMarks=true|false]</i>}}<i>value</i>{{/hiragana}}</code><br>
* _`value`_ <br>
The text to convert.
* _`keepProlongedSoundMarks`_ _(optional)_ <br>
Whether or not the `ー` character should be kept or converted to a vowel character.
Defaults to `false` if not specified.
</details>
<details>
<summary>Example:</summary>
@ -798,12 +801,16 @@ Converts katakana text to hiragana.
```handlebars
{{#hiragana "よみちゃん ヨミちゃん ヨミチャン"}}{{/hiragana}}
{{#hiragana}}よみちゃん ヨミちゃん ヨミチャン{{/hiragana}}
{{#hiragana}}ローマ字{{/hiragana}}
{{#hiragana keepProlongedSoundMarks=true}}ローマ字{{/hiragana}}
```
Output:
```html
よみちゃん よみちゃん よみちゃん
よみちゃん よみちゃん よみちゃん
ろうま字
ろーま字
```
</details>

View File

@ -297,20 +297,27 @@ const JapaneseUtil = (() => {
return this._wanakana !== null;
}
convertKatakanaToHiragana(text) {
convertKatakanaToHiragana(text, keepProlongedSoundMarks=false) {
let result = '';
const offset = (HIRAGANA_CONVERSION_RANGE[0] - KATAKANA_CONVERSION_RANGE[0]);
for (let char of text) {
const codePoint = char.codePointAt(0);
if (codePoint === KATAKANA_SMALL_KA_CODE_POINT || codePoint === KATAKANA_SMALL_KE_CODE_POINT) {
// No change
} else if (codePoint === KANA_PROLONGED_SOUND_MARK_CODE_POINT) {
if (result.length > 0) {
const char2 = getProlongedHiragana(result[result.length - 1]);
if (char2 !== null) { char = char2; }
}
} else if (isCodePointInRange(codePoint, KATAKANA_CONVERSION_RANGE)) {
char = String.fromCodePoint(codePoint + offset);
switch (codePoint) {
case KATAKANA_SMALL_KA_CODE_POINT:
case KATAKANA_SMALL_KE_CODE_POINT:
// No change
break;
case KANA_PROLONGED_SOUND_MARK_CODE_POINT:
if (!keepProlongedSoundMarks && result.length > 0) {
const char2 = getProlongedHiragana(result[result.length - 1]);
if (char2 !== null) { char = char2; }
}
break;
default:
if (isCodePointInRange(codePoint, KATAKANA_CONVERSION_RANGE)) {
char = String.fromCodePoint(codePoint + offset);
}
break;
}
result += char;
}

View File

@ -607,13 +607,16 @@ class AnkiTemplateRenderer {
_hiragana(context, ...args) {
const ii = args.length - 1;
const value = (ii > 0 ? args[0] : args[ii].fn(context));
return this._japaneseUtil.convertKatakanaToHiragana(value);
const options = args[ii];
const {keepProlongedSoundMarks} = options.hash;
const value = (ii > 0 ? args[0] : options.fn(context));
return this._japaneseUtil.convertKatakanaToHiragana(value, keepProlongedSoundMarks === true);
}
_katakana(context, ...args) {
const ii = args.length - 1;
const value = (ii > 0 ? args[0] : args[ii].fn(context));
const options = args[ii];
const value = (ii > 0 ? args[0] : options.fn(context));
return this._japaneseUtil.convertHiraganaToKatakana(value);
}
}

View File

@ -130,11 +130,13 @@ function testConvertKatakanaToHiragana() {
['ヒラガナひらがな', 'ひらがなひらがな'],
['chikaraちからチカラ力', 'chikaraちからちから力'],
['katakana', 'katakana'],
['hiragana', 'hiragana']
['hiragana', 'hiragana'],
['カーナー', 'かあなあ'],
['カーナー', 'かーなー', true]
];
for (const [string, expected] of data) {
assert.strictEqual(jp.convertKatakanaToHiragana(string), expected);
for (const [string, expected, keepProlongedSoundMarks=false] of data) {
assert.strictEqual(jp.convertKatakanaToHiragana(string, keepProlongedSoundMarks), expected);
}
}