import { UnicodeRange } from "./string.ts"; declare global { interface String { /** * @summary check if string is hiragana only * * @argument strict don't allow ascii whitespace and punctuation (default: false) * * return `true` if at least one hiragana character is in string, and no other * unicode ranges are found. ascii whitespace and punctuation is still allowed, * but not counted as hiragana. this behavior can be turned off by setting * `strict` to true */ hiraganaOnly(strict?: boolean): boolean /** * @summary check if string is katakana only * * @argument strict don't allow ascii whitespace and punctuation (default: false) * * return `true` if at least one katakana character is in string, and no other * unicode ranges are found. ascii whitespace and punctuation is still allowed, * but not counted as katakana. this behavior can be turned off by setting * `strict` to true */ katakanaOnly(strict?: boolean): boolean /** * @summary check if string is kanji only * * @argument strict don't allow ascii whitespace and punctuation (default: false) * * return `true` if at least one kanji character is in string, and no other * unicode ranges are found. ascii whitespace and punctuation is still allowed, * but not counted as kanji. this behavior can be turned off by setting * `strict` to true */ kanjiOnly(strict?: boolean): boolean /** * @summary check if string is kana only * * @argument strict don't allow ascii whitespace and punctuation (default: false) * * return `true` if at least one kana character is in string, and no other * unicode ranges are found. ascii whitespace and punctuation is still allowed, * but not counted as kana. this behavior can be turned off by setting `strict` * to true */ kanaOnly(strict?: boolean): boolean /** * @summary check if string is japanese only * * @argument strict don't allow ascii whitespace and punctuation (default: false) * * return `true` if at least one japanese character is in string, and no other * unicode ranges are found. ascii whitespace and punctuation is still allowed, * but not counted as japanese. this behavior can be turned off by setting * `strict` to true */ japaneseOnly(strict?: boolean): boolean } } enum StringOnlyReturnValue { TallyAdd, TallyIgnore, TallyStop, } /** @summary check tally for allowed scripts (internal use only) */ function stringOnly(input: string, check: (key: string, val: number) => StringOnlyReturnValue): boolean { var tally = input.rangeTally(); var ok = false; for (var [key, val] of Object.entries(tally)) { switch(check(key, val)) { case StringOnlyReturnValue.TallyAdd: { ok = true; break; } case StringOnlyReturnValue.TallyIgnore: { break; } case StringOnlyReturnValue.TallyStop: { return false; } } } return ok; } String.prototype.hiraganaOnly = function(strict = false) { return stringOnly(this as string, (key, val) => { if (key == UnicodeRange.JapaneseHiragana) return StringOnlyReturnValue.TallyAdd; // count hiragana characters else if (!strict && key.startsWith("any-")) return StringOnlyReturnValue.TallyIgnore; // allow any- (ascii whitespace and punctuation) else if (val > 0) return StringOnlyReturnValue.TallyStop; // don't allow any other ranges return StringOnlyReturnValue.TallyIgnore; }); } String.prototype.katakanaOnly = function(strict = false) { return stringOnly(this as string, (key, val) => { if (key == UnicodeRange.JapaneseKatakana) return StringOnlyReturnValue.TallyAdd; // count katakana characters else if (!strict && key.startsWith("any-")) return StringOnlyReturnValue.TallyIgnore; // allow any- (ascii whitespace and punctuation) else if (val > 0) return StringOnlyReturnValue.TallyStop; // don't allow any other ranges return StringOnlyReturnValue.TallyIgnore; }); } String.prototype.kanjiOnly = function(strict = false) { return stringOnly(this as string, (key, val) => { if (key == UnicodeRange.JapaneseKanji) return StringOnlyReturnValue.TallyAdd; // count kanji characters else if (!strict && key.startsWith("any-")) return StringOnlyReturnValue.TallyIgnore; // allow any- (ascii whitespace and punctuation) else if (val > 0) return StringOnlyReturnValue.TallyStop; // don't allow any other ranges return StringOnlyReturnValue.TallyIgnore; }); } String.prototype.kanaOnly = function(strict = false) { return stringOnly(this as string, (key, val) => { if (key == UnicodeRange.JapaneseHiragana || key == UnicodeRange.JapaneseKatakana) return StringOnlyReturnValue.TallyAdd; // count kana characters else if (!strict && key.startsWith("any-")) return StringOnlyReturnValue.TallyIgnore; // allow any- (ascii whitespace and punctuation) else if (val > 0) return StringOnlyReturnValue.TallyStop; // don't allow any other ranges return StringOnlyReturnValue.TallyIgnore; }); } String.prototype.japaneseOnly = function(strict = false) { return stringOnly(this as string, (key, val) => { if (key.startsWith("jp-")) return StringOnlyReturnValue.TallyAdd; // count japanese characters else if (!strict && key.startsWith("any-")) return StringOnlyReturnValue.TallyIgnore; // allow any- (ascii whitespace and punctuation) else if (val > 0) return StringOnlyReturnValue.TallyStop; // don't allow any other ranges return StringOnlyReturnValue.TallyIgnore; }); }