class Iuliia::Translit

Constants

ENDING_LENGTH

Attributes

schema[R]
string[R]

Public Class Methods

new(string, schema) click to toggle source

Initialize transliterator engine with string and schema @param string [String] @param schema [Iuliia::Schema] @return [Iuliia::Translit]

# File lib/iuliia/translit.rb, line 12
def initialize(string, schema)
  @string = string
  @schema = Iuliia::Schema[schema]
end

Public Instance Methods

translit() click to toggle source

Translit cyrillic string to latin representation @return [String]

# File lib/iuliia/translit.rb, line 19
def translit
  return unless schema

  string.split(/\b/).map { |chunk| translit_chunk(chunk) }.join
end

Private Instance Methods

camelcase(string) click to toggle source
# File lib/iuliia/translit.rb, line 90
def camelcase(string)
  return string unless upcase?(string[0])

  string = string.downcase
  string[0] = string[0].capitalize
  string
end
split_word(word) click to toggle source
# File lib/iuliia/translit.rb, line 75
def split_word(word)
  if word.length <= ENDING_LENGTH
    [word, '']
  else
    ending = word.length > ENDING_LENGTH ? word[-ENDING_LENGTH..-1] : ''
    stem = word[0..(word.length - ENDING_LENGTH - 1)] || word

    [stem, ending]
  end
end
translit_char(chars, char, index) click to toggle source
# File lib/iuliia/translit.rb, line 52
def translit_char(chars, char, index)
  translited_char = translit_prev(chars, index)
  translited_char = translit_next(chars, index) if translited_char.nil?
  translited_char = schema.mapping[char.downcase] if translited_char.nil?

  upcase?(char) ? translited_char.upcase : translited_char
end
translit_chunk(chunk) click to toggle source
# File lib/iuliia/translit.rb, line 29
def translit_chunk(chunk)
  return chunk unless /\p{l}+/.match?(chunk)

  stem, ending = split_word(chunk)

  return translit_stem(chunk) if ending.empty?

  translited_ending = schema.ending_mapping&.dig(ending)
  return translit_stem(chunk) if translited_ending.nil?

  translited_stem = translit_stem(stem)

  [translited_stem, translited_ending].join
end
translit_next(chars, index) click to toggle source
# File lib/iuliia/translit.rb, line 70
def translit_next(chars, index)
  next_char = chars[index..index + 1].join.downcase
  schema.next_mapping&.dig(next_char)
end
translit_prev(chars, index) click to toggle source
# File lib/iuliia/translit.rb, line 60
def translit_prev(chars, index)
  prev_char = if index.positive?
                chars[index - 1..index].join.downcase
              else
                chars[index].downcase
              end

  schema.prev_mapping&.dig(prev_char)
end
translit_stem(stem) click to toggle source
# File lib/iuliia/translit.rb, line 44
def translit_stem(stem)
  translited_stem = stem.chars.each_with_index.map do |char, index|
    translit_char(stem.chars, char, index)
  end

  camelcase(translited_stem.join)
end
upcase?(char) click to toggle source
# File lib/iuliia/translit.rb, line 86
def upcase?(char)
  /[[:upper:]]/.match(char)
end