Module: Prawn::Rtl::Connector::Logic

Defined in:
lib/prawn/rtl/connector/logic.rb

Defined Under Namespace

Classes: CharacterInfo

Constant Summary collapse

@@charinfos =
nil

Class Method Summary collapse

Class Method Details

.determine_form(previous_previous_char, previous_char, next_char, next_next_char) ⇒ Object

Determine the form of the current character (:isolated, :initial, :medial, or :final), given the previous character and the next one. In Arabic, all characters can connect with a previous character, but not all letters can connect with the next character (this is determined by CharacterInfo#connects?).



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/prawn/rtl/connector/logic.rb', line 40

def self.determine_form(previous_previous_char, previous_char, next_char, next_next_char)
  charinfos = self.charinfos
  next_char = next_next_char if charinfos[next_char] && charinfos[next_char].diacritic?
  previous_char = previous_previous_char if charinfos[previous_char] && charinfos[previous_char].diacritic?
  if charinfos[previous_char] && charinfos[next_char]
    charinfos[previous_char].connects? ? :medial : :initial # If the current character does not connect,
                                                            # its medial form will map to its final form,
                                                            # and its initial form will map to its isolated form.
  elsif charinfos[previous_char] # The next character is not an arabic character.
    charinfos[previous_char].connects? ? :final : :isolated
  elsif charinfos[next_char] # The previous character is not an arabic character.
    :initial # If the current character does not connect, its initial form will map to its isolated form.
  else # Neither of the surrounding characters are arabic characters.
    :isolated
  end
end

.transform(str) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/prawn/rtl/connector/logic.rb', line 57

def self.transform(str)
  res = ''
  charinfos = self.charinfos
  previous_previous_char = nil
  previous_char = nil
  current_char = nil
  next_char = nil
  next_next_char = nil
  consume_character = lambda do |char|
    previous_previous_char = previous_char
    previous_char = current_char
    current_char = next_char
    next_char = next_next_char
    next_next_char = char
    return unless current_char
    if charinfos.keys.include?(current_char)
      form = determine_form(previous_previous_char, previous_char, next_char, next_next_char)
      res += charinfos[current_char].formatted[form]
    else
      res += current_char
    end
  end
  str.each_char { |char| consume_character.call(char) }
  2.times { consume_character.call(nil) }
  return res
end