public static string HiraganaToKatakana(string input) { if (input is null) { throw new ArgumentNullException(nameof(input)); } var builder = new StringBuilder(); foreach (var character in input) { // Short circuit to avoid incorrect codeshift for 'ー' and '・' if (SpecialCharacterChecker.IsLongDash(character) || SpecialCharacterChecker.IsSlashDot(character)) { builder.Append(character); } else if (HiraganaChecker.IsHiragana(character)) { // Shift charcode. var katakanaCode = (character - CharacterRanges.HiraganaStart) + CharacterRanges.KatakanaStart; var katakanaCharacter = (char)katakanaCode; builder.Append(katakanaCharacter); } else { // Pass non-hiragana chars through builder.Append(character); } } return(builder.ToString()); }
public static string KatakanaToHiragana(string input, bool isDestinationRomaji = false) { if (input is null) { throw new ArgumentNullException(nameof(input)); } char?previousKana = null; var builder = new StringBuilder(); for (int index = 0; index < input.Length; index++) { var character = input[index]; // Short circuit to avoid incorrect codeshift for 'ー' and '・' if (SpecialCharacterChecker.IsSlashDot(character) || IsInitialLongDash(character, index) || IsKanaAsSymbol(character)) { builder.Append(character); // Transform long vowels: 'オー' to 'おう' } else if (previousKana != null && IsInnerLongDash(character, index)) { // Transform previousKana back to romaji, and slice off the vowel var romaji = RomajiConverter.ToRomaji(previousKana.ToString()).Last(); // However, ensure 'オー' => 'おお' => 'oo' if this is a transform on the way to romaji if (KatakanaChecker.IsKatakana(input[index - 1]) && romaji == 'o' && isDestinationRomaji) { builder.Append('お'); } else { builder.Append(_longVowels[romaji]); } } else if (!SpecialCharacterChecker.IsLongDash(character) && KatakanaChecker.IsKatakana(character)) { // Shift charcode. var hiraganaCode = (character - CharacterRanges.KatakanaStart) + CharacterRanges.HiraganaStart; var hiragana = (char)hiraganaCode; previousKana = hiragana; builder.Append(hiragana); } else { // Pass non katakana chars through previousKana = null; builder.Append(character); } } return(builder.ToString()); }