From: shyouhei@... Date: 2019-07-16T03:55:05+00:00 Subject: [ruby-core:93804] [Ruby master Feature#16006] String count and alignment that consider multibyte characters Issue #16006 has been updated by shyouhei (Shyouhei Urabe). This particular proposal is NG. ASCII vs. non-ASCII is too Asian-centric. There are other non-wide non-ASCII encodings, such as those in Europe. ---------------------------------------- Feature #16006: String count and alignment that consider multibyte characters https://bugs.ruby-lang.org/issues/16006#change-79671 * Author: sawa (Tsuyoshi Sawada) * Status: Open * Priority: Normal * Assignee: * Target version: ---------------------------------------- In non-proportional font, multibyte characters have twice the width of ASCII characters. Since `String#length`, `String#ljust`, `String#rjust`, and `String#center` do not take this into consideration, applying these methods do not give the desired output. ```ruby array = ["aa���������", "b������������������������", "cc"] col_width = array.max(&:length) array.each{|w| puts w.ljust(col_width, "*")} # >> aa���������**** # >> b������������������������ # >> cc******* ``` In order to do justification of strings that have multi-byte characters, we have to do something much more complicated such as the following: ```ruby col_widths = array.to_h{|w| [ w, w .chars .partition(&:ascii_only?) .then{|ascii, non| ascii.length + (non.length * 2)} ]} col_width = col_widths.values.max array.each{|w| puts w + "*" * (col_width - col_widths[w])} # Note that the following gives the desired alignment in non-proportional font, but may not appear so in this issue tracker. # >> aa���������********* # >> b������������������������ # >> cc*************** ``` This issue seems to be common, as several webpages can be found that attempt to do something similar. I propose to give the relevant methods an option to take multibyte characters into consideration. Perhaps something like the `proportional` keyword in the following may work: ```ruby "aa���������".length(proportional: true) # => 8 "aa���������".ljust(17, "*", proportional: true) # => "aa���������*********" ``` Then, the desired output would be given by this code: ```ruby col_width = array.max{|w| w.length(proportional: true)} array.each{|w| puts w.ljust(col_width, "*", proportional: true)} # >> aa���������********* # >> b������������������������ # >> cc*************** ``` -- https://bugs.ruby-lang.org/ Unsubscribe: