Project

General

Profile

Actions

Feature #16006

closed

String count and alignment that consider multibyte characters

Feature #16006: String count and alignment that consider multibyte characters

Added by sawa (Tsuyoshi Sawada) over 6 years ago. Updated over 6 years ago.

Status:
Rejected
Assignee:
-
Target version:
-
[ruby-core:<unknown>]

Description

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.

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:

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:

"aaあああ".length(proportional: true) # => 8 "aaあああ".ljust(17, "*", proportional: true) # => "aaあああ*********" 

Then, the desired output would be given by this code:

col_width = array.max{|w| w.length(proportional: true)} array.each{|w| puts w.ljust(col_width, "*", proportional: true)} # >> aaあああ********* # >> bいいいいいいいい # >> cc*************** 

Related issues 1 (1 open0 closed)

Actions

Also available in: PDF Atom