src/utils/katakanaToHiragana.js
// inject toRomaji to avoid circular dependency between toRomaji <-> katakanaToHiragana
inject toRomaji to avoid circular dependency between toRomaji <-> katakanaToHiragana
inject toRomaji to avoid circular dependency between toRomaji < - > katakanaToHiragana
function katakanaToHiragana(input = '', toRomaji, isDestinationRomaji) {
  let previousKana = '';
  return input
    .split('')
    .reduce((hira, char, index) => {
      if (isCharSlashDot(char) || isCharInitialLongDash(char, index) || isKanaAsSymbol(char)) {
        return hira.concat(char);
      } else if (previousKana && isCharInnerLongDash(char, index)) {
        const romaji = toRomaji(previousKana).slice(-1);
        if (isCharKatakana(input[index - 1]) && romaji === 'o' && isDestinationRomaji) {
          return hira.concat('お');
        }
        return hira.concat(LONG_VOWELS[romaji]);
      } else if (!isCharLongDash(char) && isCharKatakana(char)) {
        const code = char.charCodeAt(0) + (HIRAGANA_START - KATAKANA_START);
        const hiraChar = String.fromCharCode(code);
        previousKana = hiraChar;
        return hira.concat(hiraChar);
      }
      previousKana = '';
      return hira.concat(char);
    }, [])
    .join('');
}
function katakanaToHiragana ( input = '' , toRomaji , isDestinationRomaji ) { let previousKana = '' ; return input . split ( '' ) . reduce ( ( hira , char , index ) => { if ( isCharSlashDot ( char ) || isCharInitialLongDash ( char , index ) || isKanaAsSymbol ( char ) ) { return hira . concat ( char ) ; } else if ( previousKana && isCharInnerLongDash ( char , index ) ) { const romaji = toRomaji ( previousKana ) . slice ( - 1 ) ; if ( isCharKatakana ( input [ index - 1 ] ) && romaji === 'o' && isDestinationRomaji ) { return hira . concat ( 'お'); } return hira . concat ( LONG_VOWELS [ romaji ] ) ; } else if ( ! isCharLongDash ( char ) && isCharKatakana ( char ) ) { const code = char . charCodeAt ( 0 ) + ( HIRAGANA_START - KATAKANA_START ) ; const hiraChar = String . fromCharCode ( code ) ; previousKana = hiraChar ; return hira . concat ( hiraChar ) ; } previousKana = '' ; return hira . concat ( char ) ; } , [ ] ) . join ( '' ) ; }
inject toRomaji to avoid circular dependency between toRomaji <-> katakanaToHiragana
inject toRomaji to avoid circular dependency between toRomaji < - > katakanaToHiragana
// Short circuit to avoid incorrect codeshift for 'ー' and '・' // Transform long vowels: 'オー' to 'おう' // Transform previousKana back to romaji, and slice off the vowel // However, ensure 'オー' => 'おお' => 'oo' if this is a transform on the way to romaji // Shift charcode. // Pass non katakana chars through