Class: Roka::Converter

Inherits:
Object
  • Object
show all
Defined in:
lib/roka/converter.rb

Constant Summary collapse

VOWELS_INDEX =
%w[a  i  u  e  o ]
VOWELS_KANA =
%w[    ]
SOUND_CHANGES =
{
  'ts' => %w[ツァ ツィ    ツェ ツォ],

  'xy' => %w[              ],
  'x'  => %w[              ],

  'k'  => %w[              ],
  's'  => %w[              ],
  't'  => %w[              ],
  'n'  => %w[              ],
  'h'  => %w[              ],
  'm'  => %w[              ],
  'y'  => %w[         イェ   ],
  'r'  => %w[              ],
  'l'  => %w[              ],
  'w'  => %w[   ウィ    ウェ   ],

  'g'  => %w[              ],
  'z'  => %w[              ],
  'j'  => %w[ジャ    ジュ ジェ ジョ],
  'd'  => %w[              ],
  'b'  => %w[              ],
  'v'  => %w[ヴァ ヴィ    ヴェ ヴォ],

  'f'  => %w[ファ フィ    フェ フォ],
  'p'  => %w[              ],

  'c'  => %w[              ],
}
PREFIX_CHANGES =
{
  /^([kg])w([aeiou])/              => '\1ux\2',
  /^([td])w([aeiou])/              => '\1ox\2',
  /^sh([aeiou])/                   => 'sixy\1',
  /^ch([aeiou])/                   => 'tixy\1',
  /^([kgszjtcdnhbpmrl])y([aeiou])/ => '\1ixy\2',
  /^([td])h([aeiou])/              => '\1exy\2',
  /^([^aeioun])\1/                 => 'xtu\1',
  /^nn\b/                          => 'n',
  /^([^aeiou]o)([^h]?)\b/          => '\1h\2',
}
EXCEPTIONS =
{
  '-'    => '',
  'xka'  => '',
  'xke'  => '',
  'xtu'  => '',
  'xtsu' => '',
  'xwa'  => '',
  'shi'  => '',
  'chi'  => '',
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(str) ⇒ Converter

Returns a new instance of Converter.



63
64
65
66
# File 'lib/roka/converter.rb', line 63

def initialize(str)
  @buffer     = regulate(str)
  @determined = []
end

Instance Attribute Details

#determinedObject (readonly)

Returns the value of attribute determined.



61
62
63
# File 'lib/roka/converter.rb', line 61

def determined
  @determined
end

Instance Method Details

#consume(len, replacement = nil) ⇒ Object



145
146
147
148
149
150
# File 'lib/roka/converter.rb', line 145

def consume(len, replacement = nil)
  replacement = @buffer[0...len] if replacement.nil?
  @determined << replacement if replacement
  @buffer = @buffer[len..-1].to_s
  true
end

#convertObject



68
69
70
71
# File 'lib/roka/converter.rb', line 68

def convert
  return if eos?
  parse && convert
end

#eos?Boolean

Returns:

  • (Boolean)


172
173
174
# File 'lib/roka/converter.rb', line 172

def eos?
  @buffer.empty?
end

#expand_long_sound(prefix, vowel) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/roka/converter.rb', line 152

def expand_long_sound(prefix, vowel)
  c = @buffer[0]

  case vowel
  when 'o'
    if 'h' == c && !@buffer[1]
      consume(1, ['', ''])
    elsif 'h' == c
      d, _ = peak
      if d[0] == 'h'
        consume(1, ['', ''])
      end
    elsif !(VOWELS_INDEX + %w[y]).include?(c) && ('n' == c && 'o' == @buffer[1])
      @determined << ['', '', '']
    end
  when 'u'
    @determined << ['', ''] if 'y' == prefix
  end
end

#parseObject



73
74
75
76
77
78
79
# File 'lib/roka/converter.rb', line 73

def parse
  parse_exception \
    || parse_prefix \
    || parse_sound \
    || parse_vowel \
    || parse_last
end

#parse_exceptionObject



81
82
83
84
85
86
87
88
89
90
# File 'lib/roka/converter.rb', line 81

def parse_exception
  EXCEPTIONS.each do |seq, replacement|
    if @buffer.start_with?(seq)
      consume(seq.size, replacement)
      return true
    end
  end

  false
end

#parse_lastObject



137
138
139
140
141
142
143
# File 'lib/roka/converter.rb', line 137

def parse_last
  if 'n' == @buffer[0]
    consume(1, '')
  else
    consume(1, @buffer[0])
  end
end

#parse_prefixObject



92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/roka/converter.rb', line 92

def parse_prefix
  PREFIX_CHANGES.each do |pattern, replacement|
    buffer = @buffer.sub(pattern, replacement)

    unless buffer == @buffer
      @buffer = buffer
      return true
    end
  end

  false
end

#parse_soundObject



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/roka/converter.rb', line 105

def parse_sound
  SOUND_CHANGES.each do |prefix, changes|
    if @buffer.start_with?(prefix)
      l = prefix.size
      vowel = @buffer[l]

      if (i = VOWELS_INDEX.index(vowel))
        if 'n' == @buffer[0] && 'x' != @buffer[l + 1] && '' != @determined[@determined.size - 1]
          consume(l + 1, ['' + VOWELS_KANA[i], changes[i]])
        else
          consume(l + 1, changes[i])
        end
        expand_long_sound(prefix, vowel)
        return true
      end
    end
  end

  false
end

#parse_vowel(consonant = nil) ⇒ Object



126
127
128
129
130
131
132
133
134
135
# File 'lib/roka/converter.rb', line 126

def parse_vowel(consonant = nil)
  vowel = @buffer[0]
  if (i = VOWELS_INDEX.index(vowel))
    consume(1, VOWELS_KANA[i])
    expand_long_sound(nil, vowel)
    true
  else
    false
  end
end

#peak(_buffer = nil) ⇒ Object



194
195
196
197
198
199
200
201
202
203
204
# File 'lib/roka/converter.rb', line 194

def peak(_buffer = nil)
  determined  = @determined
  buffer      = @buffer
  @determined = []
  @buffer = _buffer unless _buffer.nil?
  parse while @determined.empty? || !eos?
  [@determined, @buffer]
ensure
  @determined = determined
  @buffer     = buffer
end

#regulate(str) ⇒ Object



190
191
192
# File 'lib/roka/converter.rb', line 190

def regulate(str)
  NKF.nkf('-m0 -Z1 -w', str.to_s.downcase)
end

#resultsObject



176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/roka/converter.rb', line 176

def results
  tree = ['']

  @determined.each do |det|
    if det.is_a?(Array)
      tree = tree.product(det).map(&:join)
    else
      tree.each { |t| t << det }
    end
  end

  tree
end