Lang::JA::Kana
Lang::JA::Kana - Japanese Kana Conversion Utilities
Languages: English âĸ æĨæŦčĒ
Documentation:
Romaji: README-Romaji.md
Cyrillic: English âĸ Đ ŅŅŅĐēиК
Overview
Lang::JA::Kana is a Raku module for converting between different Japanese kana scripts (Hiragana and Katakana) and their various forms. It provides support for modern kana, historical variants, half-width characters, and specialized Unicode symbols.
Features
Bidirectional Script Conversion: Seamless conversion between Hiragana and Katakana
Half-width Support: Handling of half-width katakana (īžīžīŊļīŊ¸) conversion
Historical Kana: Support for Hentaigana (å¤äŊäģŽå) and obsolete characters
Modern Extensions: Foreign sound adaptations (ããĄ, ããŖ, ãĻãŖ, etc.)
Specialized Symbols: Circled and squared katakana processing
Sound Mark Analysis: Diacritical mark separation and analysis
Cross-script Integration: Built-in integration with Romaji, Cyrillic, and Hangul converters
Installation
use Lang::JA::Kana;Basic Usage
Hiragana â Katakana Conversion
use Lang::JA::Kana;
# Basic conversions
say to-katakana("ãããĢãĄã¯"); # â ãŗãŗããã
say to-hiragana("ãŗãŗããã"); # â ãããĢãĄã¯
# With modern extensions
say to-katakana("ãĩããŋããŧ"); # â ããĄããĒãŧ
say to-hiragana("ããĄããĒãŧ"); # â ãĩããŋããŧ
# Combination sounds (æéŗ)
say to-katakana("ããããŧãąãŋã
ãąãŋã
"); # â ããŖãĒãŧãããĨãããĨ
say to-hiragana("ããŖãĒãŧãããĨãããĨ"); # â ããããŧãąãŋã
ãąãŋã
# Mixed text (non-kana characters pass through unchanged)
say to-katakana("Hello ãããĢãĄã¯ World"); # â Hello ãŗãŗããã World
say to-hiragana("Hello ãŗãŗããã World"); # â Hello ãããĢãĄã¯ WorldHalf-width Katakana Conversion
# Half-width to full-width conversion
say to-fullwidth-katakana("īŊąīŊ˛īŊŗīŊ´īŊĩ"); # â ãĸã¤ãĻã¨ãĒ
say to-fullwidth-katakana("īŊļīžīŊˇīžīŊ¸īž"); # â ãŦãŽã° (voiced combinations)
say to-fullwidth-katakana("īžīžīžīžīžīž"); # â ããã (semi-voiced combinations)
# Full-width to half-width conversion
say to-halfwidth-katakana("ãĸã¤ãĻã¨ãĒ"); # â īŊąīŊ˛īŊŗīŊ´īŊĩ
say to-halfwidth-katakana("ãŦãŽã°"); # â īŊļīžīŊˇīžīŊ¸īž
say to-halfwidth-katakana("ããã"); # â īžīžīžīžīžīž
# Integration with other conversions
say to-hiragana("īŊļīžīŊļīž
"); # â ããããĒ (auto-converts half-width)Character Support
Standard Kana
All 50-sound (äēåéŗ) characters:
# Basic vowels (æ¯éŗ)
to-katakana("ããããã"); # â ãĸã¤ãĻã¨ãĒ
# K-series (ãĢčĄ)
to-katakana("ããããã"); # â ãĢãã¯ãąãŗ
to-katakana("ããããã"); # â ãŦãŽã°ã˛ã´
# S-series (ãĩčĄ)
to-katakana("ããããã"); # â ãĩãˇãšãģãŊ
to-katakana("ããããã"); # â ãļã¸ãēãŧãž
# T-series (ãŋčĄ)
to-katakana("ããĄã¤ãĻã¨"); # â ãŋãããã
to-katakana("ã ãĸãĨã§ãŠ"); # â ããã
ãã
# N-series (ãčĄ)
to-katakana("ãĒãĢãŦããŽ"); # â ããããã
# H-series (ãčĄ)
to-katakana("ã¯ã˛ãĩã¸ãģ"); # â ããããã
to-katakana("ã°ãŗãļãšãŧ"); # â ããããã (voiced)
to-katakana("ãąã´ãˇãēãŊ"); # â ããããã (semi-voiced)
# M-series (ãčĄ)
to-katakana("ãžãŋããã"); # â ããã ãĄãĸ
# Y-series (ã¤čĄ)
to-katakana("ããã"); # â ã¤ãĻã¨
# R-series (ãŠčĄ)
to-katakana("ããããã"); # â ãŠãĒãĢãŦã
# W-series (ã¯čĄ) and N
to-katakana("ããããã"); # â ã¯ã°ãąã˛ãŗSmall Kana (å°æå)
# Small vowels
to-katakana("ããã
ãã"); # â ãĄãŖãĨã§ãŠ
# Small Y-sounds
to-katakana("ãã
ã"); # â ãŖãĨã§
# Small tsu (äŋéŗ)
to-katakana("ãŖ"); # â ã
# Small wa
to-katakana("ã"); # â ãŽCombination Sounds (æéŗ)
# Y-combinations
to-katakana("ãããã
ãã"); # â ããŖããĨãã§
to-katakana("ãããã
ãã"); # â ãˇãŖãˇãĨãˇã§
to-katakana("ãĄããĄã
ãĄã"); # â ããŖããĨãã§
to-katakana("ãĢããĢã
ãĢã"); # â ããŖããĨãã§
to-katakana("ã˛ãã˛ã
ã˛ã"); # â ããŖããĨãã§
to-katakana("ãŋããŋã
ãŋã"); # â ããŖããĨãã§
to-katakana("ãããã
ãã"); # â ãĒãŖãĒãĨãĒã§
# Voiced Y-combinations
to-katakana("ãããã
ãã"); # â ãŽãŖãŽãĨãŽã§
to-katakana("ãããã
ãã"); # â ã¸ãŖã¸ãĨã¸ã§
to-katakana("ãŗããŗã
ãŗã"); # â ããŖããĨãã§
to-katakana("ã´ãã´ã
ã´ã"); # â ããŖããĨãã§Modern Extensions for Foreign Sounds
# F-sounds
to-katakana("ãĩããĩããĩããĩã"); # â ããĄããŖãã§ããŠ
# T/D-sounds
to-katakana("ãĻãã§ã"); # â ããŖããŖ
to-katakana("ã¨ã
ãŠã
"); # â ããĨããĨ
# W-sounds
to-katakana("ãããããã"); # â ãĻãŖãĻã§ãĻãŠ
# V-sounds
to-katakana("ãããããããã"); # â ã´ãĄã´ãŖã´ã§ã´ãŠ
# Kw/Gw-sounds
to-katakana("ãããããããã"); # â ã¯ãĄã¯ãŖã¯ã§ã¯ãŠ
to-katakana("ãããããããã"); # â ã°ãĄã°ãŖã°ã§ã°ãŠ
# Ts-sounds
to-katakana("ã¤ãã¤ãã¤ãã¤ã"); # â ããĄããŖãã§ããŠ
# Other combinations
to-katakana("ãĄããããããã"); # â ãã§ã¸ã§ãˇã§ã¤ã§Historical and Obsolete Kana
# Historical Wi/We/Wo
to-katakana("ããã"); # â ã°ãąã˛
# VU sound
to-katakana("ã"); # â ã´
# Digraph Yori
to-katakana("ã"); # â ãŋHentaigana (å¤äŊäģŽå) Support
Hentaigana are historical variant forms of kana characters used before standardization. The module provides support for these Unicode characters.
Hentaigana to Hiragana Conversion
# Basic conversion
say hentaigana-to-hiragana("đđđ"); # â ããã
# Multiple readings (some Hentaigana have ambiguous readings)
say hentaigana-to-hiragana("đ"); # â ããģã (can be "shi" or "se")
say hentaigana-to-hiragana("đ"); # â ããģã (can be "wi" or "i")
# Complex examples
say hentaigana-to-hiragana("đđđ"); # â ãããHiragana to Hentaigana Conversion
# Single variant
say hiragana-to-hentaigana("ã"); # â đ
# Multiple variants (shows all possibilities)
say hiragana-to-hentaigana("ã"); # â đãģđãģđ
say hiragana-to-hentaigana("ã"); # â đãģđãģđĄ
# With voiced marks
say hiragana-to-hentaigana("ã"); # â (variants)ãHentaigana Character Origins
Many Hentaigana derive from specific Chinese characters (kanji):
đ (A): From åŽ (an)
đ (I): From äģĨ (i)
đ (U): From åŽ (u)
đ (KA): From å (ka)
đ (KI): From åšž (ki)
đ (SA): From åˇĻ (sa)
đ (SHI/SE): From äš (shi/se) - ambiguous reading
đ (TA): From å¤Ē (ta)
đ (CHI): From įĨ (chi)
Sound Mark Processing
The module provides utilities for analyzing and manipulating diacritical marks (æŋįšãģåæŋįš).
Sound Mark Splitting
# Split voiced characters into base + mark
my @parts = split-sound-marks("ã");
say @parts[0]; # â ã (base character)
say @parts[1]; # â ã (voiced mark)
# Split semi-voiced characters
@parts = split-sound-marks("ãą");
say @parts[0]; # â 㯠(base character)
say @parts[1]; # â ã (semi-voiced mark)
# Regular characters return as-is
@parts = split-sound-marks("ã");
say @parts[0]; # â ã (no splitting)Practical Applications
# Analyze character composition
sub analyze-kana($char) {
my @parts = split-sound-marks($char);
if @parts.elems == 2 {
say "$char = {@parts[0]} + {@parts[1]}";
} else {
say "$char = base character";
}
}
analyze-kana("ã"); # â ã = ã + ã
analyze-kana("ãą"); # â ãą = 㯠+ ã
analyze-kana("ã"); # â ã = base characterSpecialized Unicode Symbols
Circled Katakana
# Convert circled katakana to components
say decircle-katakana("ããã"); # â ãĸã¤ãĻ
say decircle-katakana("ããã"); # â ãĢãã¯
# Convert components to circled katakana
say encircle-katakana("ãĸã¤ãĻ"); # â ããã
say encircle-katakana("ãĢãã¯"); # â ãããSquared Katakana (Units and Abbreviations)
# Convert squared katakana to full forms
say desquare-katakana("ã"); # â ãã (kilo)
say desquare-katakana("ã§"); # â ããŗ (ton)
say desquare-katakana("ã"); # â ãĄãŧããĢ (meter)
say desquare-katakana("ã"); # â ãĒãããĢ (liter)
# Convert full forms to squared katakana
say ensquare-katakana("ãã"); # â ã
say ensquare-katakana("ãĄãŧããĢ"); # â ã
# Complex examples
say desquare-katakana("ãã"); # â ãããĄãŧããĢ
say desquare-katakana("ãã"); # â ããĒãĄãŧããĢCommon Squared Katakana Units:
ã (ãã) - kilo
ã§ (ããŗ) - ton
ã (ãĄãŧããĢ) - meter
ã (ãĒãããĢ) - liter
ã (ããĒ) - milli
ãĸ (ãģãŗã) - centi
ãĻ (ããĢ) - dollar
ãĢ (ããŧãģãŗã) - percent
ã (ã¯ãã) - watt
Cross-script Conversion Integration
The module seamlessly integrates with other script converters, automatically handling half-width conversion.
Romaji Conversion
# Automatic half-width handling
say kana-to-romaji("īŊēīžīžīžīž"); # â konnichiha
say kana-to-romaji("ãããĢãĄã¯"); # â konnichiha
# Multiple romanization systems
say kana-to-romaji("ãããļã", :system<hepburn>); # â shinbun
say kana-to-romaji("ãããļã", :system<kunrei>); # â sinbun
say kana-to-romaji("ãããļã", :system<nihon>); # â sinbun
# Sokuon (ãŖ) handling
say kana-to-romaji("ããŖãã"); # â gakkou
say kana-to-romaji("ãĄããŖã¨"); # â chottoCyrillic Conversion
# Polivanov system (default)
say kana-to-kuriru-moji("ãããĢãĄã¯"); # â ĐēĐžĐŊĐŊиŅиŅ
а
say kana-to-kuriru-moji("ã˛ãããĒ"); # â Ņ
иŅĐ°ĐŗĐ°ĐŊа
# Phonetic system
say kana-to-kuriru-moji("ãããļã", :system<phonetic>); # â ŅиĐŊĐąŅĐŊ
say kana-to-kuriru-moji("ãĄããĄã
ãĄã", :system<phonetic>); # â ŅаŅŅŅĐž
# Slavic language variants
say kana-to-kuriru-moji("ããã", :system<ukrainian>); # â ŅаĐēŅŅа
say kana-to-kuriru-moji("ããã", :system<serbian>); # â ŅаĐēŅŅаHangul Conversion
# Standard system (default)
say kana-to-hangul("ãããĢãĄã¯"); # â ęŗ¤ëėší
say kana-to-hangul("ã˛ãããĒ"); # â íëŧę°ë
# Academic system (with consonant doubling)
say kana-to-hangul("ããŖãã", :system<academic>); # â ęšėŊė°
say kana-to-hangul("ã°ãŖã°", :system<academic>); # â ëšąëš
# Phonetic system (preserves Japanese pronunciation)
say kana-to-hangul("ãĄããĄã
ãĄã", :system<phonetic>); # â ėšėŧėšė ėšė
# Popular system (K-pop/media usage)
say kana-to-hangul("ãĄã
ã", :system<popular>); # â ėļė°Advanced Features
Mixed Text Processing
All functions handle mixed text gracefully, processing only kana characters:
say to-katakana("Hello ãããĢãĄã¯ 123"); # â Hello ãŗãŗããã 123
say to-hiragana("Hello ãŗãŗããã 123"); # â Hello ãããĢãĄã¯ 123
say to-fullwidth-katakana("Hello īŊąīŊ˛īŊŗ 123"); # â Hello ãĸã¤ãĻ 123Chained Conversions
# Complex conversion chains
my $text = "īŊēīžīžīžīž"; # Half-width katakana
$text = to-fullwidth-katakana($text); # â ãŗãŗããã
$text = to-hiragana($text); # â ãããĢãĄã¯
say kana-to-romaji($text); # â konnichiha
# Historical processing
$text = "đđđ"; # Hentaigana
$text = hentaigana-to-hiragana($text); # â ããã
$text = to-katakana($text); # â ãĢãã¯
say encircle-katakana($text); # â ãããEmpty String and Edge Case Handling
say to-katakana(""); # â "" (empty string)
say to-hiragana(""); # â "" (empty string)
say to-fullwidth-katakana(""); # â "" (empty string)
say hentaigana-to-hiragana(""); # â "" (empty string)Character Coverage
Unicode Ranges Supported
Hiragana: U+3040-U+309F (ã˛ãããĒ)
Katakana: U+30A0-U+30FF (ãĢãŋãĢã)
Half-width Katakana: U+FF61-U+FF9F (īžīžīŊļīŊ¸)
Hentaigana: U+1B001-U+1B11E (đ-đ)
Circled Katakana: U+32D0-U+32FE (ã-ãž)
Squared Katakana: U+3300-U+3357 (ã-ã)
Character Count
Basic Hiragana/Katakana: 46 + 25 (voiced/semi-voiced) = 71 characters
Small Kana: 10 characters
Y-combinations: 33 combinations
Modern Extensions: 25+ foreign sound adaptations
Half-width Forms: 63 characters
Hentaigana: 300+ historical variants
Circled Katakana: 47 symbols
Squared Katakana: 88 unit abbreviations
Performance Considerations
Optimization Features
Longest-First Matching: Multi-character combinations processed before single characters
Efficient Hash Lookups: O(1) character mapping using Raku hashes
Minimal Regex Usage: Direct string substitution where possible
Lazy Evaluation: Conversion tables computed only when needed
Best Practices
# Efficient: Single conversion call
my $result = to-katakana($large-text);
# Less efficient: Multiple small conversions
for @small-texts -> $text {
$result ~= to-katakana($text); # Consider batching
}
# Efficient: Reuse conversion results
my $katakana = to-katakana($text);
my $romaji = kana-to-romaji($katakana); # Uses already-converted katakanaError Handling and Edge Cases
Robust Input Processing
# Invalid or unknown characters are preserved
say to-katakana("ãããĢãĄã¯đ"); # â ãŗãŗãããđ
say to-hiragana("ãĢãŋãĢãđž"); # â ããããĒđž
# Mixed scripts handled appropriately
say to-katakana("ã˛ãããĒãĢãŋãĢã"); # â ããŠãŦããĢãŋãĢã
say to-hiragana("ãĢãŋãĢãã˛ãããĒ"); # â ããããĒã˛ãããĒ
# Partial conversions work correctly
say to-fullwidth-katakana("Normal īŊąīŊ˛īŊŗ text"); # â Normal ãĸã¤ãĻ textAmbiguous Character Handling
# Hentaigana with multiple readings
say hentaigana-to-hiragana("đ"); # â ããģã (shows all possibilities)
# Historical characters preserved if no modern equivalent
say to-katakana("å¤ãđæå"); # â å¤ã¤đæå (đ processed separately)Integration Examples
Text Processing Pipeline
sub normalize-japanese-text($text) {
# Step 1: Convert half-width to full-width
my $normalized = to-fullwidth-katakana($text);
# Step 2: Standardize to hiragana for processing
$normalized = to-hiragana($normalized);
# Step 3: Convert historical kana
$normalized = hentaigana-to-hiragana($normalized);
# Step 4: Expand abbreviated forms
$normalized = desquare-katakana($normalized);
$normalized = decircle-katakana($normalized);
return $normalized;
}
# Example usage
my $text = "đīŊ˛īŊŗãã";
say normalize-japanese-text($text); # â ããããããMultilingual Conversion
sub convert-to-all-scripts($japanese-text) {
# Normalize input
my $normalized = to-fullwidth-katakana($japanese-text);
return {
hiragana => to-hiragana($normalized),
katakana => to-katakana($normalized),
romaji => kana-to-romaji($normalized),
cyrillic => kana-to-kuriru-moji($normalized),
hangul => kana-to-hangul($normalized)
};
}
# Example usage
my %scripts = convert-to-all-scripts("īŊēīžīžīžīž");
say %scripts<hiragana>; # â ãããĢãĄã¯
say %scripts<romaji>; # â konnichiha
say %scripts<cyrillic>; # â ĐēĐžĐŊĐŊиŅиŅ
а
say %scripts<hangul>; # â ęŗ¤ëėšíLimitations
Kanji Processing: Does not convert Kanji characters (æŧĸå)
Context Sensitivity: Pure character-level conversion without semantic analysis
Historical Accuracy: Hentaigana mappings based on Unicode standards, not historical manuscripts
Regional Variants: Based on standard Japanese, not dialectal pronunciations
Use Cases
Educational Applications
Japanese language learning materials
Script conversion exercises
Historical text modernization
Unicode character reference
Text Processing
Document normalization
Search and indexing systems
Legacy text conversion
Character encoding migration
Digital Humanities
Historical manuscript digitization
Classical Japanese text processing
Unicode compliance testing
Script evolution research
Entertainment Industry
Game localization
Anime subtitle processing
Manga text conversion
Social media content adaptation
Contributing
Contributions are welcome. Please visit the project repository at:https://github.com/slavenskoj/raku-lang-ja-kana
We apologize for any errors and welcome suggestions for improvements.
References
Unicode Standards
Unicode Standard Annex #15: Unicode Normalization Forms
Unicode block specifications for Japanese scripts
Unicode Consortium Hentaigana guidelines
Academic Sources
Japanese Ministry of Education kana standardization
Historical kana usage studies
Unicode Consortium technical reports
License
This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.
Author
Danslav Slavenskoj
For specific script conversions (Romaji, Cyrillic, Hangul), see the specialized README files:
README-Romaji.md - Romanization systems
README-Kuriru-moji.md - Cyrillic conversion
README-Hangul.md - Korean Hangul conversion