Class: Unicode::DisplayWidth

Inherits:
Object
  • Object
show all
Defined in:
lib/unicode/display_width.rb,
lib/unicode/display_width/index.rb,
lib/unicode/display_width/constants.rb

Constant Summary collapse

DEPTHS =
[0x10000, 0x1000, 0x100, 0x10].freeze
VERSION =
"2.0.0"
UNICODE_VERSION =
"13.0.0"
DATA_DIRECTORY =
File.expand_path(File.dirname(__FILE__) + "/../../../data/")
INDEX_FILENAME =
DATA_DIRECTORY + "/display_width.marshal.gz"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ambiguous: 1, overwrite: {}, emoji: false) ⇒ DisplayWidth

Returns a new instance of DisplayWidth.


46
47
48
49
50
# File 'lib/unicode/display_width.rb', line 46

def initialize(ambiguous: 1, overwrite: {}, emoji: false)
  @ambiguous = ambiguous
  @overwrite = overwrite
  @emoji     = emoji
end

Class Method Details

.emoji_extra_width_of(string, ambiguous = 1, overwrite = {}, _ = {}) ⇒ Object


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/unicode/display_width.rb', line 28

def self.emoji_extra_width_of(string, ambiguous = 1, overwrite = {}, _ = {})
  require "unicode/emoji"

  extra_width = 0
  modifier_regex = /[#{ Unicode::Emoji::EMOJI_MODIFIERS.pack("U*") }]/
  zwj_regex = /(?<=#{ [Unicode::Emoji::ZWJ].pack("U") })./

  string.scan(Unicode::Emoji::REGEX){ |emoji|
    extra_width += 2 * emoji.scan(modifier_regex).size

    emoji.scan(zwj_regex){ |zwj_succ|
      extra_width += self.of(zwj_succ, ambiguous, overwrite)
    }
  }

  extra_width
end

.of(string, ambiguous = 1, overwrite = {}, options = {}) ⇒ Object


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/unicode/display_width.rb', line 10

def self.of(string, ambiguous = 1, overwrite = {}, options = {})
  res = string.codepoints.inject(0){ |total_width, codepoint|
    index_or_value = INDEX
    codepoint_depth_offset = codepoint
    DEPTHS.each{ |depth|
      index_or_value         = index_or_value[codepoint_depth_offset / depth]
      codepoint_depth_offset = codepoint_depth_offset % depth
      break unless index_or_value.is_a? Array
    }
    width = index_or_value.is_a?(Array) ? index_or_value[codepoint_depth_offset] : index_or_value
    width = ambiguous if width == :A
    total_width + (overwrite[codepoint] || width || 1)
  }

  res -= emoji_extra_width_of(string, ambiguous, overwrite) if options[:emoji]
  res < 0 ? 0 : res
end

Instance Method Details

#get_config(**kwargs) ⇒ Object


52
53
54
55
56
57
58
# File 'lib/unicode/display_width.rb', line 52

def get_config(**kwargs)
  [
    kwargs[:ambiguous] || @ambiguous,
    kwargs[:overwrite] || @overwrite,
    { emoji: kwargs[:emoji] || @emoji },
  ]
end

#of(string, **kwargs) ⇒ Object


60
61
62
# File 'lib/unicode/display_width.rb', line 60

def of(string, **kwargs)
  self.class.of(string, *get_config(**kwargs))
end