Sha256: ffb566adaa2c65c39c04425b1fb31d0a362ccc49c2e895afc8881472a1de54f8

Contents?: true

Size: 1.9 KB

Versions: 19

Compression:

Stored size: 1.9 KB

Contents

# frozen_string_literal: true

require_relative "display_width/constants"
require_relative "display_width/index"

module Unicode
  class DisplayWidth
    DEPTHS = [0x10000, 0x1000, 0x100, 0x10].freeze

    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

    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

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

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

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

Version data entries

19 entries across 15 versions & 7 rubygems

Version Path
cm-admin-1.5.22 vendor/bundle/ruby/3.3.0/gems/unicode-display_width-2.3.0/lib/unicode/display_width.rb
cm-admin-1.5.21 vendor/bundle/ruby/3.3.0/gems/unicode-display_width-2.3.0/lib/unicode/display_width.rb
cm-admin-1.5.20 vendor/bundle/ruby/3.3.0/gems/unicode-display_width-2.3.0/lib/unicode/display_width.rb
scrapbook-0.3.2 vendor/ruby/2.7.0/gems/unicode-display_width-2.1.0/lib/unicode/display_width.rb
scrapbook-0.3.2 vendor/ruby/2.7.0/gems/unicode-display_width-2.2.0/lib/unicode/display_width.rb
scrapbook-0.3.2 vendor/ruby/2.7.0/gems/unicode-display_width-2.3.0/lib/unicode/display_width.rb
scrapbook-0.3.1 vendor/ruby/2.7.0/gems/unicode-display_width-2.1.0/lib/unicode/display_width.rb
scrapbook-0.3.1 vendor/ruby/2.7.0/gems/unicode-display_width-2.2.0/lib/unicode/display_width.rb
scrapbook-0.3.1 vendor/ruby/2.7.0/gems/unicode-display_width-2.3.0/lib/unicode/display_width.rb
unicode-display_width-2.3.0 lib/unicode/display_width.rb
unicode-display_width-2.2.0 lib/unicode/display_width.rb
op_connect-0.1.2 vendor/bundle/ruby/3.1.0/gems/unicode-display_width-2.1.0/lib/unicode/display_width.rb
phillipug-foodie-0.1.0 .vendor/ruby/3.0.0/gems/unicode-display_width-2.1.0/lib/unicode/display_width.rb
unicode-display_width-2.1.0 lib/unicode/display_width.rb
rails_mini_profiler-0.2.0 vendor/bundle/ruby/3.0.0/gems/unicode-display_width-2.0.0/lib/unicode/display_width.rb
cocRb-0.1.0 .bundle/ruby/3.0.0/gems/unicode-display_width-2.0.0/lib/unicode/display_width.rb
unicode-display_width-2.0.0 lib/unicode/display_width.rb
unicode-display_width-2.0.0.pre2 lib/unicode/display_width.rb
unicode-display_width-2.0.0.pre1 lib/unicode/display_width.rb