Class: TwitterCldr::Shared::Bidi

Inherits:
Object
  • Object
show all
Defined in:
lib/twitter_cldr/shared/bidi.rb

Constant Summary collapse

MAX_DEPTH =
62

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Bidi

Returns a new instance of Bidi.



54
55
56
57
58
59
60
61
62
63
# File 'lib/twitter_cldr/shared/bidi.rb', line 54

def initialize(options = {})
  @string_arr = options[:string_arr] || options[:types]
  @types = options[:types] || []
  @levels = []
  @runs = []
  @direction = options[:direction]
  @default_direction = options[:default_direction] || :LTR
  @length = @types.size
  run_bidi
end

Instance Attribute Details

#levelsObject (readonly)

Returns the value of attribute levels.



31
32
33
# File 'lib/twitter_cldr/shared/bidi.rb', line 31

def levels
  @levels
end

#string_arrObject (readonly)

Returns the value of attribute string_arr.



31
32
33
# File 'lib/twitter_cldr/shared/bidi.rb', line 31

def string_arr
  @string_arr
end

#typesObject (readonly)

Returns the value of attribute types.



31
32
33
# File 'lib/twitter_cldr/shared/bidi.rb', line 31

def types
  @types
end

Class Method Details

.from_string(str, options = {}) ⇒ Object



36
37
38
39
# File 'lib/twitter_cldr/shared/bidi.rb', line 36

def from_string(str, options = {})
  string_arr = str.unpack("U*")
  Bidi.new(options.merge(types: compute_types(string_arr), string_arr: string_arr))
end

.from_type_array(types, options = {}) ⇒ Object



41
42
43
# File 'lib/twitter_cldr/shared/bidi.rb', line 41

def from_type_array(types, options = {})
  Bidi.new(options.merge(types: types))
end

Instance Method Details

#reorder_visually!Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/twitter_cldr/shared/bidi.rb', line 69

def reorder_visually!
  raise "No string given!" unless @string_arr

  # Do this explicitly so we can also find the maximum depth at the
  # same time.
  max = 0
  lowest_odd = MAX_DEPTH + 1

  @levels.each do |level|
    max = [level, max].max
    lowest_odd = [lowest_odd, level].min unless level.even?
  end

  # Reverse the runs starting with the deepest.
  max.downto(lowest_odd) do |depth|
    start = 0

    while start < @levels.size
      # Find the start of a run >= DEPTH.
      start += 1 while start < @levels.size && @levels[start] < depth

      break if start == @levels.size

      # Find the end of the run.
      finish = start + 1
      finish += 1 while finish < @levels.size && @levels[finish] >= depth

      # Reverse this run.
      ((finish - start) / 2).times do |i|
        tmpb = @levels[finish - i - 1]
        @levels[finish - i - 1] = @levels[start + i]
        @levels[start + i] = tmpb

        tmpo = @string_arr[finish - i - 1]
        @string_arr[finish - i - 1] = @string_arr[start + i]
        @string_arr[start + i] = tmpo
      end

      # Handle the next run.
      start = finish + 1
    end
  end

  self
end

#to_sObject



65
66
67
# File 'lib/twitter_cldr/shared/bidi.rb', line 65

def to_s
  @string_arr.pack("U*")
end