Module: IS::Term::StringHelpers
- Defined in:
- lib/is-term/string_helpers.rb
Overview
Terminal string rendering utilities with proper width calculation for Unicode characters, emoji, East Asian characters, and ANSI escape sequences.
This module provides essential string manipulation methods for terminal UIs, handling complex Unicode display widths correctly while ignoring ANSI color/style codes. It extends String via Refinements to provide a clean, chainable API.
Features
-
Correct width calculation (emoji=2, CJK=2, ASCII=1, ANSI=0)
-
Safe truncation preserving ANSI codes
-
Flexible alignment (left, right, center)
-
Ellipsis with configurable marker
Usage
require 'is-term/string_helpers'
Standalone (no refinements, no includes):
IS::Term::StringHelpers.str_width("中👨⚕️")
# => 4
Include private methods:
include IS::Term::StringHelpers
str_width("中👨⚕️")
# => 4
With refinements (recommended):
using IS::Term::StringHelpers
"中👨⚕️".width # => 4
"中👨⚕️".ellipsis(3) # => "中…"
Constant Summary collapse
- ALIGN_LEFT =
:left- ALIGN_RIGHT =
:right- ALIGN_CENTER =
:center- ALIGN_MODES =
[ ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER ].freeze
- DEFAULT_ELLIPSIS_MARKER =
'…'- DEFAULT_ALIGN_MODE =
ALIGN_LEFT
Class Method Summary collapse
-
.str_align(str, width, mode = DEFAULT_ALIGN_MODE) ⇒ String
Aligns string within specified display width using spaces.
-
.str_ellipsis(str, width, marker = DEFAULT_ELLIPSIS_MARKER) ⇒ String
Truncates string to fit within width, appending ellipsis marker if truncated.
-
.str_truncate(str, width) ⇒ String
Truncates string to specified display width, preserving ANSI escape sequences.
-
.str_width(str) ⇒ Integer
Calculates the display width of a string in terminal context.
Instance Method Summary collapse
-
#str_align(str, width, mode = DEFAULT_ALIGN_MODE) ⇒ String
private
Aligns string within specified display width using spaces.
-
#str_ellipsis(str, width, marker = DEFAULT_ELLIPSIS_MARKER) ⇒ String
private
Truncates string to fit within width, appending ellipsis marker if truncated.
-
#str_truncate(str, width) ⇒ String
private
Truncates string to specified display width, preserving ANSI escape sequences.
-
#str_width(str) ⇒ Integer
private
Calculates the display width of a string in terminal context.
Class Method Details
.str_align(str, width, mode = DEFAULT_ALIGN_MODE) ⇒ String
Aligns string within specified display width using spaces.
Returns original string if source width is greater than or equal to target. Supports left, right, and center alignment.
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/is-term/string_helpers.rb', line 159 def str_align str, width, mode = DEFAULT_ALIGN_MODE src_width = str_width str return str if src_width >= width case mode when ALIGN_LEFT str + ' ' * (width - src_width) when ALIGN_RIGHT ' ' * (width - src_width) + str when ALIGN_CENTER left = (width - src_width) / 2 right = width - src_width - left ' ' * left + str + ' ' * right else raise ArgumentError, "Invalid align value: #{ mode.inspect }", caller_locations end end |
.str_ellipsis(str, width, marker = DEFAULT_ELLIPSIS_MARKER) ⇒ String
Truncates string to fit within width, appending ellipsis marker if truncated.
Raises ArgumentError if marker display width exceeds target width. Preserves ANSI codes and handles Unicode widths correctly.
135 136 137 138 139 140 141 142 143 |
# File 'lib/is-term/string_helpers.rb', line 135 def str_ellipsis str, width, marker = DEFAULT_ELLIPSIS_MARKER marker_width = str_width marker raise ArgumentError, "Marker too long: #{ marker.inspect }", caller_locations if marker_width > width if str_width(str) > width str_truncate(str, width - marker_width) + marker else str end end |
.str_truncate(str, width) ⇒ String
Truncates string to specified display width, preserving ANSI escape sequences.
ANSI codes are fully skipped (width 0), truncation occurs only on visible characters. Returns original string if already within width or empty string for non-positive widths.
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/is-term/string_helpers.rb', line 101 def str_truncate str, width return str if str.length <= width return '' if width <= 0 current = 0 position = 0 str.scan(TOKEN) do |match| w = case match when ESC_CODES 0 when EMOJI, EAST_ASIA 2 else 1 end current += w return str[0, position] if current > width position += match.length end str end |
.str_width(str) ⇒ Integer
Calculates the display width of a string in terminal context.
Handles Unicode display rules:
-
ANSI escape sequences: width 0
-
Emoji: width 2
-
East Asian characters (Han, Hiragana, Katakana, Hangul): width 2
-
Other characters: width 1
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/is-term/string_helpers.rb', line 72 def str_width str current = 0 str.scan(TOKEN) do |match| w = case match when ESC_CODES 0 when EMOJI, EAST_ASIA 2 else 1 end current += w end current end |
Instance Method Details
#str_align(str, width, mode = DEFAULT_ALIGN_MODE) ⇒ String (private)
Aligns string within specified display width using spaces.
Returns original string if source width is greater than or equal to target. Supports left, right, and center alignment.
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/is-term/string_helpers.rb', line 159 def str_align str, width, mode = DEFAULT_ALIGN_MODE src_width = str_width str return str if src_width >= width case mode when ALIGN_LEFT str + ' ' * (width - src_width) when ALIGN_RIGHT ' ' * (width - src_width) + str when ALIGN_CENTER left = (width - src_width) / 2 right = width - src_width - left ' ' * left + str + ' ' * right else raise ArgumentError, "Invalid align value: #{ mode.inspect }", caller_locations end end |
#str_ellipsis(str, width, marker = DEFAULT_ELLIPSIS_MARKER) ⇒ String (private)
Truncates string to fit within width, appending ellipsis marker if truncated.
Raises ArgumentError if marker display width exceeds target width. Preserves ANSI codes and handles Unicode widths correctly.
135 136 137 138 139 140 141 142 143 |
# File 'lib/is-term/string_helpers.rb', line 135 def str_ellipsis str, width, marker = DEFAULT_ELLIPSIS_MARKER marker_width = str_width marker raise ArgumentError, "Marker too long: #{ marker.inspect }", caller_locations if marker_width > width if str_width(str) > width str_truncate(str, width - marker_width) + marker else str end end |
#str_truncate(str, width) ⇒ String (private)
Truncates string to specified display width, preserving ANSI escape sequences.
ANSI codes are fully skipped (width 0), truncation occurs only on visible characters. Returns original string if already within width or empty string for non-positive widths.
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/is-term/string_helpers.rb', line 101 def str_truncate str, width return str if str.length <= width return '' if width <= 0 current = 0 position = 0 str.scan(TOKEN) do |match| w = case match when ESC_CODES 0 when EMOJI, EAST_ASIA 2 else 1 end current += w return str[0, position] if current > width position += match.length end str end |
#str_width(str) ⇒ Integer (private)
Calculates the display width of a string in terminal context.
Handles Unicode display rules:
-
ANSI escape sequences: width 0
-
Emoji: width 2
-
East Asian characters (Han, Hiragana, Katakana, Hangul): width 2
-
Other characters: width 1
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/is-term/string_helpers.rb', line 72 def str_width str current = 0 str.scan(TOKEN) do |match| w = case match when ESC_CODES 0 when EMOJI, EAST_ASIA 2 else 1 end current += w end current end |