diff options
Diffstat (limited to 'vendor/bundle/ruby/3.4.0/gems/unicode-display_width-2.6.0/lib/unicode')
5 files changed, 184 insertions, 0 deletions
diff --git a/vendor/bundle/ruby/3.4.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width.rb b/vendor/bundle/ruby/3.4.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width.rb new file mode 100644 index 0000000..bbd7026 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width.rb @@ -0,0 +1,123 @@ +# frozen_string_literal: true + +require_relative "display_width/constants" +require_relative "display_width/index" + +module Unicode + class DisplayWidth + INITIAL_DEPTH = 0x10000 + ASCII_NON_ZERO_REGEX = /[\0\x05\a\b\n\v\f\r\x0E\x0F]/ + FIRST_4096 = decompress_index(INDEX[0][0], 1) + + def self.of(string, ambiguous = 1, overwrite = {}, options = {}) + if overwrite.empty? + # Optimization for ASCII-only strings without certain control symbols + if string.ascii_only? + if string.match?(ASCII_NON_ZERO_REGEX) + res = string.gsub(ASCII_NON_ZERO_REGEX, "").size - string.count("\b") + res < 0 ? 0 : res + else + string.size + end + else + width_no_overwrite(string, ambiguous, options) + end + else + width_all_features(string, ambiguous, overwrite, options) + end + end + + def self.width_no_overwrite(string, ambiguous, options = {}) + # Sum of all chars widths + res = string.codepoints.sum{ |codepoint| + if codepoint > 15 && codepoint < 161 # very common + next 1 + elsif codepoint < 0x1001 + width = FIRST_4096[codepoint] + else + width = INDEX + depth = INITIAL_DEPTH + while (width = width[codepoint / depth]).instance_of? Array + codepoint %= depth + depth /= 16 + end + end + + width == :A ? ambiguous : (width || 1) + } + + # Substract emoji error + res -= emoji_extra_width_of(string, ambiguous) if options[:emoji] + + # Return result + prevent negative lengths + res < 0 ? 0 : res + end + + # Same as .width_no_overwrite - but with applying overwrites for each char + def self.width_all_features(string, ambiguous, overwrite, options) + # Sum of all chars widths + res = string.codepoints.sum{ |codepoint| + next overwrite[codepoint] if overwrite[codepoint] + + if codepoint > 15 && codepoint < 161 # very common + next 1 + elsif codepoint < 0x1001 + width = FIRST_4096[codepoint] + else + width = INDEX + depth = INITIAL_DEPTH + while (width = width[codepoint / depth]).instance_of? Array + codepoint %= depth + depth /= 16 + end + end + + width == :A ? ambiguous : (width || 1) + } + + # Substract emoji error + res -= emoji_extra_width_of(string, ambiguous, overwrite) if options[:emoji] + + # Return result + prevent negative lengths + 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 + diff --git a/vendor/bundle/ruby/3.4.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/constants.rb b/vendor/bundle/ruby/3.4.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/constants.rb new file mode 100644 index 0000000..14af2b1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/constants.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Unicode + class DisplayWidth + VERSION = "2.6.0" + UNICODE_VERSION = "16.0.0" + DATA_DIRECTORY = File.expand_path(File.dirname(__FILE__) + "/../../../data/") + INDEX_FILENAME = DATA_DIRECTORY + "/display_width.marshal.gz" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/index.rb b/vendor/bundle/ruby/3.4.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/index.rb new file mode 100644 index 0000000..f81df7f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/index.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require "zlib" +require_relative "constants" + +module Unicode + class DisplayWidth + File.open(INDEX_FILENAME, "rb") do |file| + serialized_data = Zlib::GzipReader.new(file).read + serialized_data.force_encoding Encoding::BINARY + INDEX = Marshal.load(serialized_data) + end + + def self.decompress_index(index, level) + index.flat_map{ |value| + if level > 0 + if value.instance_of?(Array) + value[15] ||= nil + decompress_index(value, level - 1) + else + decompress_index([value] * 16, level - 1) + end + else + if value.instance_of?(Array) + value[15] ||= nil + value + else + [value] * 16 + end + end + } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/no_string_ext.rb b/vendor/bundle/ruby/3.4.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/no_string_ext.rb new file mode 100644 index 0000000..2601497 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/no_string_ext.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +warn "You are loading 'unicode-display_width/no_string_ext'\n" \ + "Beginning with version 2.0, this is not necessary anymore\n"\ + "You can just require 'unicode-display_width' now and no\n"\ + "string extension will be loaded" + +require_relative "../display_width" diff --git a/vendor/bundle/ruby/3.4.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/string_ext.rb b/vendor/bundle/ruby/3.4.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/string_ext.rb new file mode 100644 index 0000000..88df9ea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/string_ext.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require_relative "../display_width" unless defined? Unicode::DisplayWidth + +class String + def display_width(ambiguous = 1, overwrite = {}, options = {}) + Unicode::DisplayWidth.of(self, ambiguous, overwrite, options) + end +end |
