ExkPasswd.Transform.Romaji (ExkPasswd v0.2.0)

View Source

Converts Japanese Hiragana/Katakana to Romaji for keyboard compatibility.

This transform enables passwords with Japanese words to be typed on any keyboard layout while maintaining memorability for Japanese speakers.

Use Case

  • Dictionary: Japanese words (memorability in native language)
  • Transform: Romaji conversion (ASCII output for compatibility)
  • Result: Memorable for Japanese speakers, compatible with all systems

Examples

# Load Japanese dictionary
ExkPasswd.Dictionary.load_custom(:japanese, ["さくら", "やま", "うみ", "そら", "かぜ"])

config = ExkPasswd.Config.new!(
  dictionary: :japanese,
  word_length: 2..4,
  word_length_bounds: 1..10,
  separator: "-",
  meta: %{
    transforms: [%ExkPasswd.Transform.Romaji{}]
  }
)

ExkPasswd.generate(config)
#=> "45-sakura-yama-umi-89"
# Memorable: Japanese speaker remembers "さくら やま うみ"
# Compatible: Works on any keyboard, any system

# Katakana loanwords are also supported
ExkPasswd.Dictionary.load_custom(:katakana, ["ファイル", "コーヒー", "パーティー"])
# Converts to: fairu, koohii, paatii

Supported Scripts

  • Hiragana (あいうえお...) - All standard characters
  • Katakana (アイウエオ...) - All standard characters plus extended sounds
  • Extended Katakana - Foreign sound combinations (ファ, ウィ, ヴァ, ティ, etc.)

Romanization Style

This implementation follows Modified Hepburn with Wāpuro input conventions, which matches how Japanese speakers type on QWERTY keyboards using IME (Input Method Editor).

Standard Hepburn Features

  • Sokuon (っ/ッ): Doubles the next consonant
    • がっこう → gakkou
    • まっちゃ → matcha (special case: っち → tch)
  • Palatalized sounds (ゃ/ゅ/ょ): Combines with previous consonant
    • きょう → kyou, しゃ → sha, ちゃ → cha
  • ん before labials: Romanized as "m" before p, b, m
    • さんぽ → sampo, しんぶん → shimbun

Extended Features (Katakana Loanwords)

  • Long vowel marker (ー): Duplicates the previous vowel for ASCII compatibility
    • コーヒー → koohii (not kōhī with macrons)
    • ラーメン → raamen, ビール → biiru
  • ヴ (vu) sound: Used for "v" in foreign words
    • ヴァイオリン → vaiorin (violin)
    • ヴ → vu, ヴァ → va, ヴィ → vi, ヴェ → ve, ヴォ → vo
  • Small vowel combinations: Used for foreign sounds
    • フ + small vowels: ファ → fa, フィ → fi, フェ → fe, フォ → fo
    • ウ + small vowels: ウィ → wi, ウェ → we, ウォ → wo
    • テ/デ + small イ: ティ → ti, ディ → di
    • ト/ド + small ウ: トゥ → tu, ドゥ → du
    • シ/チ/ジ + small エ: シェ → she, チェ → che, ジェ → je

Real-World Examples

ExkPasswd.Transform.apply(%Romaji{}, "ファイル", nil)     #=> "fairu" (file)
ExkPasswd.Transform.apply(%Romaji{}, "パーティー", nil)   #=> "paatii" (party)
ExkPasswd.Transform.apply(%Romaji{}, "ウィンドウ", nil)   #=> "windou" (window)
ExkPasswd.Transform.apply(%Romaji{}, "チェック", nil)     #=> "chekku" (check)
ExkPasswd.Transform.apply(%Romaji{}, "コンピューター", nil) #=> "kompyuutaa" (computer)

Limitations

Kanji Not Supported

This transform cannot convert Kanji (漢字) to romaji without additional morphological analysis or dictionary lookup. Kanji characters will be passed through unchanged.

To use Japanese words with Kanji:

  1. Pre-convert to Hiragana/Katakana using your system IME or online tools
  2. Use kana-only dictionaries
  3. Use the contains_kanji?/1 function to detect Kanji in input

Particle Handling

The transform does not distinguish grammatical particles (は as "wa", を as "o") from their regular usage, as this requires sentence-level context. For password generation from word lists, this distinction is not necessary.

Kanji Detection

Use contains_kanji?/1 to check if text contains Kanji characters:

ExkPasswd.Transform.Romaji.contains_kanji?("桜")      #=> true
ExkPasswd.Transform.Romaji.contains_kanji?("さくら")  #=> false
ExkPasswd.Transform.Romaji.contains_kanji?("日本語")  #=> true

Summary

Functions

Check if a string contains Kanji characters.

Get the vowel value from a small vowel kana.

Check if a single character is a Kanji character.

Returns the Romaji romanization mapping.

Check if a character is a small vowel kana.

Types

t()

@type t() :: %ExkPasswd.Transform.Romaji{}

Functions

contains_kanji?(text)

@spec contains_kanji?(String.t()) :: boolean()

Check if a string contains Kanji characters.

Kanji are Chinese characters used in Japanese writing. This transform cannot convert Kanji to romaji without additional dictionary/morphological analysis.

Kanji Unicode Ranges

  • CJK Unified Ideographs: U+4E00 to U+9FFF (most common Kanji)
  • CJK Extension A: U+3400 to U+4DBF
  • CJK Extension B+: U+20000 to U+2EBEF (rare, requires surrogate pairs)

Examples

iex> ExkPasswd.Transform.Romaji.contains_kanji?("さくら")
false

iex> ExkPasswd.Transform.Romaji.contains_kanji?("桜")
true

iex> ExkPasswd.Transform.Romaji.contains_kanji?("日本語")
true

iex> ExkPasswd.Transform.Romaji.contains_kanji?("コーヒー")
false

get_small_vowel_value(arg1)

@spec get_small_vowel_value(String.t()) :: String.t()

Get the vowel value from a small vowel kana.

Examples

iex> ExkPasswd.Transform.Romaji.get_small_vowel_value("ァ")
"a"

iex> ExkPasswd.Transform.Romaji.get_small_vowel_value("ぃ")
"i"

kanji?(char)

@spec kanji?(String.t()) :: boolean()

Check if a single character is a Kanji character.

Examples

iex> ExkPasswd.Transform.Romaji.kanji?("桜")
true

iex> ExkPasswd.Transform.Romaji.kanji?("さ")
false

iex> ExkPasswd.Transform.Romaji.kanji?("日")
true

romaji_map()

@spec romaji_map() :: %{required(String.t()) => String.t()}

Returns the Romaji romanization mapping.

This function provides access to the internal mapping of Hiragana and Katakana characters to their Romaji romanization equivalents.

Returns

A map of Japanese kana characters to Romaji strings.

Examples

iex> map = ExkPasswd.Transform.Romaji.romaji_map()
...> map["あ"]
"a"

iex> map = ExkPasswd.Transform.Romaji.romaji_map()
...> map["さ"]
"sa"

iex> map = ExkPasswd.Transform.Romaji.romaji_map()
...> map["サ"]
"sa"

small_vowel?(char)

@spec small_vowel?(String.t()) :: boolean()

Check if a character is a small vowel kana.

Small vowels are used in Katakana to represent foreign sounds like ファ (fa), ウィ (wi), etc.