Class: CLI::UI::Formatter

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/cli/ui/formatter.rb

Defined Under Namespace

Classes: FormatError

Constant Summary collapse

SGR_MAP =

Available mappings of formattings To use any of them, you can use {<key>:<string>} There are presentational (colours and formatters) and semantic (error, info, command) formatters available

{
  # presentational
  'red' => '31',
  'green' => '32',
  'yellow' => '33',
  # default blue is low-contrast against black in some default terminal color scheme
  'blue' => '94', # 9x = high-intensity fg color x
  'magenta' => '35',
  'cyan' => '36',
  'gray' => '38;5;244',
  'white' => '97',
  'bold' => '1',
  'italic' => '3',
  'underline' => '4',
  'reset' => '0',

  # semantic
  'error' => '31', # red
  'success' => '32', # success
  'warning' => '33', # yellow
  'info' => '94', # bright blue
  'command' => '36', # cyan
}.freeze
BEGIN_EXPR =
'{{'
END_EXPR =
'}}'
SCAN_WIDGET =
%r[@widget/(?<handle>\w+):(?<args>.*?)}}]
SCAN_FUNCNAME =
/\w+:/
SCAN_GLYPH =
/.}}/
SCAN_BODY =
%r{
  .*?
  (
    #{BEGIN_EXPR} |
    #{END_EXPR}   |
    \z
  )
}mx
DISCARD_BRACES =
0..-3
LITERAL_BRACES =
Class.new
Stack =
T.type_alias { T::Array[T.any(String, LITERAL_BRACES)] }

Instance Method Summary collapse

Methods included from T::Sig

sig

Constructor Details

#initialize(text) ⇒ Formatter

Returns a new instance of Formatter.



86
87
88
89
# File 'lib/cli/ui/formatter.rb', line 86

def initialize(text)
  @text = text
  @nodes = T.let([], T::Array[[String, Stack]])
end

Instance Method Details

#format(sgr_map = SGR_MAP, enable_color: CLI::UI.enable_color?) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/cli/ui/formatter.rb', line 102

def format(sgr_map = SGR_MAP, enable_color: CLI::UI.enable_color?)
  @nodes.replace([])
  stack = parse_body(StringScanner.new(@text))
  prev_fmt = T.let(nil, T.nilable(Stack))
  content = @nodes.each_with_object(+'') do |(text, fmt), str|
    if prev_fmt != fmt && enable_color
      text = apply_format(text, fmt, sgr_map)
    end
    str << text
    prev_fmt = fmt
  end

  stack.reject! { |e| e.is_a?(LITERAL_BRACES) }

  return content unless enable_color
  return content if stack == prev_fmt

  unless stack.empty? && (@nodes.empty? || T.must(@nodes.last)[1].empty?)
    content << apply_format('', stack, sgr_map)
  end
  content
end