aboutsummaryrefslogtreecommitdiff
path: root/util/japanese.ts
diff options
context:
space:
mode:
Diffstat (limited to 'util/japanese.ts')
-rw-r--r--util/japanese.ts133
1 files changed, 130 insertions, 3 deletions
diff --git a/util/japanese.ts b/util/japanese.ts
index 2017280..d398b60 100644
--- a/util/japanese.ts
+++ b/util/japanese.ts
@@ -1,4 +1,5 @@
import { UnicodeRange } from "./string.ts";
+import "./number.ts";
declare global {
interface String {
@@ -57,6 +58,15 @@ declare global {
* `strict` to true
*/
japaneseOnly(strict?: boolean): boolean
+
+ /** @summary convert any half-width katakana to full-width */
+ widenKatakana(): string;
+
+ /** @summary convert any full-width katakana to hiragana */
+ katakanaToHiragana(): string;
+
+ /** @summary convert any kana (full and half-width) to full-width hiragana */
+ normalizeKana(): string;
}
}
@@ -85,7 +95,7 @@ function stringOnly(input: string, check: (key: string, val: number) => StringOn
String.prototype.hiraganaOnly = function(strict = false) {
return stringOnly(this as string, (key, val) => {
- if (key == UnicodeRange.JapaneseHiragana)
+ if (key == UnicodeRange.JapaneseFWHiragana)
return StringOnlyReturnValue.TallyAdd; // count hiragana characters
else if (!strict && key.startsWith("any-"))
return StringOnlyReturnValue.TallyIgnore; // allow any- (ascii whitespace and punctuation)
@@ -97,7 +107,7 @@ String.prototype.hiraganaOnly = function(strict = false) {
String.prototype.katakanaOnly = function(strict = false) {
return stringOnly(this as string, (key, val) => {
- if (key == UnicodeRange.JapaneseKatakana)
+ if ([UnicodeRange.JapaneseHWKatakana, UnicodeRange.JapaneseFWKatakana].includes(key as UnicodeRange))
return StringOnlyReturnValue.TallyAdd; // count katakana characters
else if (!strict && key.startsWith("any-"))
return StringOnlyReturnValue.TallyIgnore; // allow any- (ascii whitespace and punctuation)
@@ -121,7 +131,7 @@ String.prototype.kanjiOnly = function(strict = false) {
String.prototype.kanaOnly = function(strict = false) {
return stringOnly(this as string, (key, val) => {
- if (key == UnicodeRange.JapaneseHiragana || key == UnicodeRange.JapaneseKatakana)
+ if ([UnicodeRange.JapaneseHWKatakana, UnicodeRange.JapaneseFWKatakana, UnicodeRange.JapaneseFWHiragana].includes(key as UnicodeRange))
return StringOnlyReturnValue.TallyAdd; // count kana characters
else if (!strict && key.startsWith("any-"))
return StringOnlyReturnValue.TallyIgnore; // allow any- (ascii whitespace and punctuation)
@@ -143,3 +153,120 @@ String.prototype.japaneseOnly = function(strict = false) {
});
}
+String.prototype.widenKatakana = function() {
+ const map: { [key: string]: string } = {
+ "ァ": "ァ",
+ "ア": "ア",
+ "ィ": "ィ",
+ "イ": "イ",
+ "ゥ": "ゥ",
+ "ウ": "ウ",
+ "ェ": "ェ",
+ "エ": "エ",
+ "ォ": "ォ",
+ "オ": "オ",
+ "ガ": "ガ",
+ "カ": "カ",
+ "ギ": "ギ",
+ "キ": "キ",
+ "グ": "グ",
+ "ク": "ク",
+ "ゲ": "ゲ",
+ "ケ": "ケ",
+ "ゴ": "ゴ",
+ "コ": "コ",
+ "ザ": "ザ",
+ "サ": "サ",
+ "ジ": "ジ",
+ "シ": "シ",
+ "ズ": "ズ",
+ "ス": "ス",
+ "ゼ": "ゼ",
+ "セ": "セ",
+ "ゾ": "ゾ",
+ "ソ": "ソ",
+ "ダ": "ダ",
+ "タ": "タ",
+ "ヂ": "ヂ",
+ "チ": "チ",
+ "ヅ": "ヅ",
+ "ッ": "ッ",
+ "ツ": "ツ",
+ "デ": "デ",
+ "テ": "テ",
+ "ド": "ド",
+ "ト": "ト",
+ "ナ": "ナ",
+ "ニ": "ニ",
+ "ヌ": "ヌ",
+ "ネ": "ネ",
+ "ノ": "ノ",
+ "バ": "バ",
+ "パ": "パ",
+ "ハ": "ハ",
+ "ビ": "ビ",
+ "ピ": "ピ",
+ "ヒ": "ヒ",
+ "ブ": "ブ",
+ "プ": "プ",
+ "フ": "フ",
+ "ベ": "ベ",
+ "ペ": "ペ",
+ "ヘ": "ヘ",
+ "ボ": "ボ",
+ "ポ": "ポ",
+ "ホ": "ホ",
+ "マ": "マ",
+ "ミ": "ミ",
+ "ム": "ム",
+ "メ": "メ",
+ "モ": "モ",
+ "ャ": "ャ",
+ "ヤ": "ヤ",
+ "ュ": "ュ",
+ "ユ": "ユ",
+ "ョ": "ョ",
+ "ヨ": "ヨ",
+ "ラ": "ラ",
+ "リ": "リ",
+ "ル": "ル",
+ "レ": "レ",
+ "ロ": "ロ",
+ "ワ": "ワ",
+ "ヲ": "ヲ",
+ "ン": "ン",
+ "ヴ": "ヴ",
+ "ヷ": "ヷ",
+ "イ゙": "イ゙",
+ "エ゙": "エ゙",
+ "ヺ": "ヺ",
+ "ー": "ー",
+ };
+
+ var out = "";
+ outer:
+ for (let i = 0; i < this.length; i++) {
+ for (var key in map) {
+ if (!this.substring(i).startsWith(key)) continue;
+ out += map[key];
+ i += key.length - 1;
+ continue outer;
+ }
+
+ out += this[i];
+ }
+ return out;
+}
+
+String.prototype.katakanaToHiragana = function() {
+ return this.map(char => {
+ var code = char.codePointAt(0)!;
+ if (0x30a1 <= code && code <= 0x30f6) return (code + (0x3041 - 0x30a1)).toChar();
+ return char;
+ })
+}
+
+String.prototype.normalizeKana = function() {
+ return this.widenKatakana().katakanaToHiragana();
+}
+