Skip to content

Commit 2614266

Browse files
oieioictran
authored andcommitted
Fix alignment of multi-byte fullwidth character comments (#575)
This fixes alignment of Japanese, Korean and Chinese fullwidth character comments. The displayed widths of multi-byte fullwidth characters are generally twice as large as the ASCII characters, but String#size returns only the number of characters. So if the column comment contains fullwidth multibyte characters, the alignment is broken.
1 parent ca4090d commit 2614266

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

lib/annotate/annotate_models.rb

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ def get_schema_info(klass, header, options = {})
301301
type_remainder = (md_type_allowance - 2) - col_type.length
302302
info << (sprintf("# **`%s`**%#{name_remainder}s | `%s`%#{type_remainder}s | `%s`", col_name, " ", col_type, " ", attrs.join(", ").rstrip)).gsub('``', ' ').rstrip + "\n"
303303
else
304-
info << sprintf("# %-#{max_size}.#{max_size}s:%-#{bare_type_allowance}.#{bare_type_allowance}s %s", col_name, col_type, attrs.join(", ")).rstrip + "\n"
304+
info << format_default(col_name, max_size, col_type, bare_type_allowance, attrs)
305305
end
306306
end
307307

@@ -884,7 +884,7 @@ def with_comments?(klass, options)
884884
def max_schema_info_width(klass, options)
885885
if with_comments?(klass, options)
886886
max_size = klass.columns.map do |column|
887-
column.name.size + (column.comment ? column.comment.size : 0)
887+
column.name.size + (column.comment ? width(column.comment) : 0)
888888
end.max || 0
889889
max_size += 2
890890
else
@@ -894,6 +894,20 @@ def max_schema_info_width(klass, options)
894894

895895
max_size
896896
end
897+
898+
def format_default(col_name, max_size, col_type, bare_type_allowance, attrs)
899+
sprintf("# %s:%s %s", mb_chars_ljust(col_name, max_size), mb_chars_ljust(col_type, bare_type_allowance), attrs.join(", ")).rstrip + "\n"
900+
end
901+
902+
def width(string)
903+
string.chars.inject(0) { |acc, elem| acc + (elem.bytesize == 1 ? 1 : 2) }
904+
end
905+
906+
def mb_chars_ljust(string, length)
907+
string = string.to_s
908+
padding = length - width(string)
909+
string + (' ' * padding)
910+
end
897911
end
898912

899913
class BadModelFileError < LoadError

spec/annotate/annotate_models_spec.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,29 @@ def self.when_called_with(options = {})
936936
# notes(Notes) :text(55) not null
937937
# no_comment :text(20) not null
938938
#
939+
EOS
940+
941+
mocked_columns_with_multibyte_comment = [
942+
[:id, :integer, { limit: 8, comment: 'ID' }],
943+
[:active, :boolean, { limit: 1, comment: 'ACTIVE' }],
944+
[:name, :string, { limit: 50, comment: 'NAME' }],
945+
[:notes, :text, { limit: 55, comment: 'NOTES' }],
946+
[:no_comment, :text, { limit: 20, comment: nil }]
947+
]
948+
949+
when_called_with with_comment: 'yes',
950+
with_columns: mocked_columns_with_multibyte_comment, returns:
951+
<<-EOS.strip_heredoc
952+
# Schema Info
953+
#
954+
# Table name: users
955+
#
956+
# id(ID) :integer not null, primary key
957+
# active(ACTIVE) :boolean not null
958+
# name(NAME) :string(50) not null
959+
# notes(NOTES) :text(55) not null
960+
# no_comment :text(20) not null
961+
#
939962
EOS
940963

941964
it 'should get schema info as RDoc' do

0 commit comments

Comments
 (0)