• Stars
    star
    117
  • Rank 292,301 (Top 6 %)
  • Language
    Ruby
  • License
    MIT License
  • Created over 13 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Monospace Unicode character width in Ruby

Unicode::DisplayWidth [version]

Determines the monospace display width of a string in Ruby. Useful for all kinds of terminal-based applications. Implementation based on EastAsianWidth.txt and other data, 100% in Ruby. It does not rely on the OS vendor (like wcwidth()) to provide an up-to-date method for measuring string width.

Unicode version: 15.0.0 (September 2022)

Supported Rubies: 3.1, 3.0, 2.7

Old Rubies which might still work: 2.6, 2.5, 2.4

For even older Rubies, use version 2.3.0 of this gem: 2.3, 2.2, 2.1, 2.0, 1.9

Version 2.4.2 β€” Performance Updates

If you use this gem, you should really upgrade to 2.4.2. It's often 100x faster, sometimes even 1000x and more!

This is possible because the gem now detects if you use very basic (and common) characters, like ASCII characters. Furthermore, the charachter width lookup code has been optimized, so even when full-width characters are involved, the gem is much faster now.

Version 2.0 β€” Breaking Changes

Some features of this library were marked deprecated for a long time and have been removed with Version 2.0:

  • Aliases of display_width (…_size, …_length) have been removed
  • Auto-loading of string core extension has been removed:

If you are relying on the String#display_width string extension to be automatically loaded (old behavior), please load it explicitly now:

require "unicode/display_width/string_ext"

You could also change your Gemfile line to achieve this:

gem "unicode-display_width", require: "unicode/display_width/string_ext"

Introduction to Character Widths

Guessing the correct space a character will consume on terminals is not easy. There is no single standard. Most implementations combine data from East Asian Width, some General Categories, and hand-picked adjustments.

How this Library Handles Widths

Further at the top means higher precedence. Please expect changes to this algorithm with every MINOR version update (the X in 1.X.0)!

Width Characters Comment
X (user defined) Overwrites any other values
-1 "\b" Backspace (total width never below 0)
0 "\0", "\x05", "\a", "\n", "\v", "\f", "\r", "\x0E", "\x0F" C0 control codes which do not change horizontal width
1 "\u{00AD}" SOFT HYPHEN
2 "\u{2E3A}" TWO-EM DASH
3 "\u{2E3B}" THREE-EM DASH
0 General Categories: Mn, Me, Cf (non-arabic) Excludes ARABIC format characters
0 "\u{1160}".."\u{11FF}", "\u{D7B0}".."\u{D7FF}" HANGUL JUNGSEONG
0 "\u{2060}".."\u{206F}", "\u{FFF0}".."\u{FFF8}", "\u{E0000}".."\u{E0FFF}" Ignorable ranges
2 East Asian Width: F, W Full-width characters
2 "\u{3400}".."\u{4DBF}", "\u{4E00}".."\u{9FFF}", "\u{F900}".."\u{FAFF}", "\u{20000}".."\u{2FFFD}", "\u{30000}".."\u{3FFFD}" Full-width ranges
1 or 2 East Asian Width: A Ambiguous characters, user defined, default: 1
1 All other codepoints -

Install

Install the gem with:

$ gem install unicode-display_width

Or add to your Gemfile:

gem 'unicode-display_width'

Usage

Classic API

require 'unicode/display_width'

Unicode::DisplayWidth.of("βš€") # => 1
Unicode::DisplayWidth.of("δΈ€") # => 2

Ambiguous Characters

The second parameter defines the value returned by characters defined as ambiguous:

Unicode::DisplayWidth.of("Β·", 1) # => 1
Unicode::DisplayWidth.of("Β·", 2) # => 2

Custom Overwrites

You can overwrite how to handle specific code points by passing a hash (or even a proc) as third parameter:

Unicode::DisplayWidth.of("a\tb", 1, "\t".ord => 10)) # => tab counted as 10, so result is 12

Please note that using overwrites disables some perfomance optimizations of this gem.

Emoji Support

Emoji width support is included, but in must be activated manually. It will adjust the string's size for modifier and zero-width joiner sequences. You also need to add the unicode-emoji gem to your Gemfile:

gem 'unicode-display_width'
gem 'unicode-emoji'

Enable the emoji string width adjustments by passing emoji: true as fourth parameter:

Unicode::DisplayWidth.of "πŸ€ΎπŸ½β€β™€οΈ" # => 5
Unicode::DisplayWidth.of "πŸ€ΎπŸ½β€β™€οΈ", 1, {}, emoji: true # => 2

Usage with String Extension

require 'unicode/display_width/string_ext'

"βš€".display_width # => 1
'δΈ€'.display_width # => 2

Modern API: Keyword-arguments Based Config Object

Version 2.0 introduces a keyword-argument based API, which allows you to save your configuration for later-reuse. This requires an extra line of code, but has the advantage that you'll need to define your string-width options only once:

require 'unicode/display_width'

display_width = Unicode::DisplayWidth.new(
  # ambiguous: 1,
  overwrite: { "A".ord => 100 },
  emoji: true,
)

display_width.of "βš€" # => 1
display_width.of "πŸ€ΎπŸ½β€β™€οΈ" # => 2
display_width.of "A" # => 100

Usage From the CLI

Use this one-liner to print out display widths for strings from the command-line:

$ gem install unicode-display_width
$ ruby -r unicode/display_width -e 'puts Unicode::DisplayWidth.of $*[0]' -- "δΈ€"

Replace "δΈ€" with the actual string to measure

Other Implementations & Discussion

See unicode-x for more Unicode related micro libraries.

Copyright & Info

More Repositories

1

irbtools

Improvements for Ruby's IRB console πŸ’ŽοΈŽ
Ruby
912
star
2

paint

Ruby gem for ANSI terminal colors 🎨︎ VERY FAST
Ruby
364
star
3

clipboard

Ruby access to the clipboard on Windows, Linux, macOS, Java, Cygwin, and WSL πŸ“‹οΈŽ
Ruby
350
star
4

whirly

Colorful Terminal Spinner for Ruby πŸ˜€οΈŽ
Ruby
323
star
5

idiosyncratic-ruby.com

Documenting All Ruby Specialities πŸ’ŽοΈŽ
JavaScript
310
star
6

uniscribe

Know your Unicode βœ€
Ruby
280
star
7

pws

Command-Line Password Safe πŸ”οΈŽ
Ruby
210
star
8

unicode-emoji

Up-to-date Emoji Regex in Ruby
Ruby
142
star
9

unibits

Visualize different Unicode encodings in the terminal
Ruby
127
star
10

sugar_refinery

Tiny refinements for Ruby
Ruby
110
star
11

productive-sublime-snippets-ruby

Ruby Snippets for Sublime Text
Ruby
107
star
12

stdgems

Ruby's default & bundled gems: The new standard library
Ruby
105
star
13

relaxed.ruby.style

A Relaxed Style Guide for Ruby & Configuration for RuboCop
Ruby
72
star
14

fresh

Fresh Ruby Enhanced SHell
Ruby
71
star
15

wirb

Ruby Object Inspection for IRB
Ruby
70
star
16

unicode-confusable

Unicode::Confusable.confusable? "β„œΥ½α–―Κ", "Ruby"
Ruby
68
star
17

sig

Validate Method Arguments & Results in Ruby
Ruby
58
star
18

fancy_irb

Colors & Hash Rockets in IRB
Ruby
48
star
19

rg

A way to integrate AngularJS into a Rails project using CoffeeScript and Bower.
Ruby
46
star
20

debugging

Improve your Print Debugging
Ruby
42
star
21

unicode-x

Unicode Micro Libraries for Ruby
Ruby
38
star
22

characteristics

Character info under different encodings
Ruby
27
star
23

object_shadow

The Shadow of a Ruby Object lets you See and Manipulate its Instance Variables and Methods
Ruby
27
star
24

value_struct

Read-only structs in Ruby
Ruby
25
star
25

redux.rb

A tiny Ruby redux
Ruby
25
star
26

code

Displays a Ruby method's source code
Ruby
24
star
27

has_many_booleans

This Rails plugin/gem allows you to generate virtual boolean attributes, which get saved in the database as a single bitset integer.
Ruby
23
star
28

microevent.rb

Events for Ruby objects (a.k.a objects with Publish-Subscribe capabilities a.k.a. Observer pattern)
Ruby
23
star
29

ruby.style

Collects Ruby Style Guides
CSS
20
star
30

unicopy

Unicode command-line codepoint dumper
Ruby
20
star
31

unicode-blocks

Unicode Blocks of a Ruby String
Ruby
18
star
32

irbtools-more

irbtools-more adds gems to IRB that may not build out-of-the-box
18
star
33

character.construction

Notable characters, codepoints, and resources
HTML
16
star
34

ruby_version

RubyVersion | Better than RUBY_VERSION
Ruby
15
star
35

better-array

Unobtrusive JavaScript Array Extras
JavaScript
15
star
36

render_react

Pre-render and mount React components from Ruby
Ruby
15
star
37

yyid.ex

Almost a random UUID in Elixir
Elixir
14
star
38

rubybuntu-gedit

Ruby/Rails/Web related gedit language definitions, mime types, styles and snippets.
Ruby
14
star
39

slim_migrations

Let's you write slightly slimmer Rails migrations.
Ruby
14
star
40

unicode-name

Unicode character names in Ruby
Ruby
13
star
41

uke

𝄝 Ukulele CLI Support
Ruby
13
star
42

gedit-external-tools

A repository for useful and handy snippets for gedit's external tools plugin
Shell
13
star
43

boolean2

Boolean2 is a Ruby constant that is an ancestor of true and false.
Ruby
11
star
44

derb

Dockerfile.erb
Ruby
11
star
45

unicode-scripts

Unicode Scripts / Script Extensions of a Ruby String
Ruby
11
star
46

az

From A to Z
Ruby
10
star
47

symbolify

␀ ␁ ␂ ␃ ␄ ␅ ␆ ␇ ␈ ␉ ␊ ␋ ␌ ␍ ␎ ␏ ␐ ␑ ␒ ␓ ␔ ␕ ␖ ␗ ␘ ␙ ␚ ␛ ␜ ␝ ␞ ␟ ␠ ␑
Ruby
9
star
48

micrologger

A minimal logger based on MicroEvent.rb
Ruby
9
star
49

watchbuffy

Which Buffy episode to put on next?
Ruby
8
star
50

ruby_info

RubyInfo | Better than SCRIPT_LINES__
Ruby
8
star
51

productive-sublime-snippets-erb

Productive Sublime Snippets for ERB
Ruby
8
star
52

unicoder

(wip)
Ruby
7
star
53

clipboard_formatter

A clipboard formatter for RSpec
Ruby
7
star
54

unicode-categories

Unicode General Categories of a Ruby String
Ruby
7
star
55

microgem

more gems
Ruby
6
star
56

unicode-types

Basic Unicode Types of a Ruby String
Ruby
6
star
57

rubynetz

Example Usage of Harvester
6
star
58

unicode-sequence_name

Unicode sequence names in Ruby
Ruby
6
star
59

Deutsch.rb

Like English.rb
Ruby
6
star
60

unicode-numeric_value

Convert a Unicode character into its numeric value
Ruby
6
star
61

rubybuntu-language-specs

gtksourceview language specifications for Ruby/Web devoloper's gedit
Ruby
6
star
62

ripl-multi_line

This ripl plugin allows you to evaluate multiple lines of code.
Ruby
6
star
63

ruby_engine

RubyEngine | Better than RUBY_ENGINE
Ruby
6
star
64

rubybuntu-mime

gnome mime types for Ruby/Web developer's gedit
5
star
65

promiseUserMedia.js

Promisified access to getUserMedia & vendor prefixes.
JavaScript
5
star
66

added

Module#added
Ruby
5
star
67

procstar

Provides to_proc implementations for other Ruby classes than just Symbol
Ruby
4
star
68

every_day_irb

Ruby
4
star
69

rusty_clipboard

Ruby πŸ‘ͺ Rust πŸ‘ͺ System Clipboard
Ruby
4
star
70

unicode-age

Determine Unicode version required to display a string
Ruby
4
star
71

yyid.rb

Almost a random UUID in Ruby
Ruby
4
star
72

multi_block

Pass multiple blocks to a Ruby method
Ruby
4
star
73

ripl-color_result

This ripl plugin colorizes your results.
Ruby
4
star
74

nem

npm + gem = nem
Ruby
4
star
75

rubybuntu-editor-styles

gtksourceview styles for Ruby/Web devoloper's gedit
4
star
76

ripltools

This meta gem installs a bunch of ripl plugins for a nice-to-use general purpose ripl.
Ruby
4
star
77

named_proc

Named procs and lambdas
Ruby
3
star
78

local_port

Returns the next free local port number to use for your shiny new service
Ruby
3
star
79

nomore

Blocks your computer from accessing domains on the internet
Ruby
3
star
80

cd

Enhanced cd command for the Ruby console.
Ruby
3
star
81

ripl-auto_indent

This ripl plugin indents your multi-line Ruby input.
Ruby
3
star
82

unicode-version

Which level of Unicode and Emoji support is included with Ruby?
Ruby
3
star
83

egonil

Egocentric Nil
Ruby
2
star
84

talk-ruby-unconf-surprises

Ruby is Full of Surprises (Ruby Unconf 2018)
JavaScript
2
star
85

iterate

Kernel#iterate
Ruby
2
star
86

ripl-rocket

Lets you display the ripl result as a comment on the same line.
Ruby
2
star
87

instance_variables_from

Turn bindings, hashes or arrays into instance variables
Ruby
2
star
88

yyid.js

yyid() generates a random uuid* in the browser, uses the crypto api when available
JavaScript
2
star
89

wcswidth-ruby

FFI bindings to libc's wcswidth() to determine the actual display width of strings
Ruby
2
star
90

pws-otp

Experimental OTP support for PWS
Ruby
2
star
91

website

Ruby
2
star
92

null_plus

+nil
Ruby
2
star
93

ripl-color_streams

This ripl plugin colorizes your stdout and stderr streams.
Ruby
2
star
94

yyid-node.js

Almost a random UUID in node.js
JavaScript
1
star
95

yyid.go

Almost a random UUID in Go
Go
1
star
96

communication-map

WebRTC based Location Sharing
CSS
1
star
97

null_question

Adds the null? predicate to Ruby's nil
Ruby
1
star
98

ripl-profiles

This ripl plugin adds a --profile option to ripl that loads profile files in ~/.ripl/profiles before starting ripl
Ruby
1
star
99

exists

Turns null objects into nil
Ruby
1
star