Ruby: проверка ширины Восточной Азии (Юникод)

Используя Ruby, я должен выводить строки в столбчатом формате на терминал. Что-то вроде этого:

| row 1     | a string here     | etc
| row 2     | another string    | etc

Я могу сделать это хорошо с латинскими символами UTF8, используя String # ljust и% s.

Но проблема возникает, когда символы являются корейскими, китайскими и т. Д. Столбцы просто не будут выравниваться, если есть строки английского языка, в которые вкраплены строки, содержащие корейский язык и т. Д.

Как я могу получить выравнивание столбцов здесь? Есть ли способ вывести азиатские символы в эквиваленте шрифта фиксированной ширины? Как насчет документов, которые должны отображаться и редактироваться в Vim?

3 ответа

Решение

Позднее, но, надеюсь, все еще полезно: в Ruby вы можете использовать гем unicode-display_width, чтобы проверить восточно-азиатскую ширину строки:

require 'unicode/display_width'
"⚀".display_width #=> 1
'一'.display_width #=> 2

Ваша проблема возникает с полноразмерными и широкими символами CJK (китайский / японский / корейский) (также прокрутите вниз для просмотра диаграмм); эти символы занимают две ячейки фиксированной ширины. String#ljust и друзья не принимают это во внимание.

Есть unicodedata.east_asian_width в Python, который позволил бы вам написать свой собственный способ определения ширины, но в Ruby его, похоже, не существует. Лучшее, что мне удалось найти, - это сообщение в блоге: http://d.hatena.ne.jp/hush_puppy/20090227/1235740342 ( машинный перевод). Если вы посмотрите на вывод в нижней части оригинала, он, кажется, делает то, что вы хотите, поэтому, возможно, вы сможете повторно использовать часть кода Ruby.

Или, если вы печатаете только символы полной ширины (т.е. вы не смешиваете половину ширины и полную ширину), вы можете быть ленивыми и просто использовать формы полной ширины всего, включая интервалы и рисование блоков. Вот пара символов, которые вы можете скопировать и вставить:

  • | (вертикальная черта полной ширины)
  • (ширина во всю ширину)
  • - (полноразмерная черта; не очень красиво отображается в моем терминальном шрифте)
  • Another (еще один штрих во всю ширину)

Поздно на вечеринку, но вы можете попробовать .

      require 'east_asian_width_simple'
eaw = EastAsianWidthSimple.new(File.open('EastAsianWidth.txt'))
eaw.string_width('台灣 No.1') # => 9
eaw.string_width('No code, no ') # => 14

Он стремится быть быстрым и гибким.

Быстрый

работает быстрее, чем другие реализации на чистом Ruby. Ниже приведена сравнительная таблица стоимости времени:

Гибкий

east_asian_width_simpleeast_asian_width_simpleeast_asian_width_simple является гибким, поскольку он отделяет файл данных свойств ширины Восточной Азии .

В отличие от других гемов, вы обновляете, загружая последний файл свойств с unicode.org, а не обновляя гем.

Например, последняя черновая версия файла данных — v15.0.0d5 , но ни один другой гем не может применить ее, не выпустив новую версию гем.

Другие вопросы по тегам