Class: Pastel::ColorParser Private

Inherits:
Object
  • Object
show all
Includes:
ANSI
Defined in:
lib/pastel/color_parser.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Responsible for parsing color symbols out of text with color escapes

Used internally by Color.

Constant Summary collapse

ESC =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

"\x1b"
CSI =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

"\["

Constants included from ANSI

ANSI::ATTRIBUTES

Class Method Summary collapse

Methods included from ANSI

background?, foreground?, style?

Class Method Details

.attribute_name(ansi) ⇒ Symbol

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Decide attribute name for ansi

Parameters:

  • ansi (Integer)

    the ansi escape code

Returns:

  • (Symbol)

104
105
106
107
108
109
110
111
112
# File 'lib/pastel/color_parser.rb', line 104

def self.attribute_name(ansi)
  if ANSI.foreground?(ansi)
    :foreground
  elsif ANSI.background?(ansi)
    :background
  elsif ANSI.style?(ansi)
    :style
  end
end

.color_name(ansi_code) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Convert ANSI code to color name

Returns:

  • (String)

119
120
121
# File 'lib/pastel/color_parser.rb', line 119

def self.color_name(ansi_code)
  ATTRIBUTES.key(ansi_code.to_i)
end

.parse(text) ⇒ Array[Hash[Symbol,String]]

Parse color escape sequences into a list of hashes corresponding to the color attributes being set by these sequences

Examples:

parse("\e[32mfoo\e[0m")
# => [{foreground: :green, text: "foo"}

Parameters:

  • text (String)

    the text to parse for presence of color ansi codes

Returns:

  • (Array[Hash[Symbol,String]])

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/pastel/color_parser.rb', line 33

def self.parse(text)
  scanner = StringScanner.new(text)
  state = {}
  result = []
  ansi_stack = []
  text_chunk = []

  until scanner.eos?
    char = scanner.getch
    # match control
    if char == ESC && (delim = scanner.getch) == CSI
      if scanner.scan(/^0?m/) # reset
        unpack_ansi(ansi_stack) { |attr, name| state[attr] = name }
        ansi_stack = []
      elsif scanner.scan(/^([1-9;:]+)m/)
        # ansi codes separated by text
        if !text_chunk.empty? && !ansi_stack.empty?
          unpack_ansi(ansi_stack) { |attr, name| state[attr] = name }
        end
        scanner[1].split(/:|;/).each do |code|
          ansi_stack << code
        end
      end

      if !text_chunk.empty?
        state[:text] = text_chunk.join
        result.push(state)
        state = {}
        text_chunk.clear
      end
    elsif char == ESC # broken escape
      text_chunk << char + delim.to_s
    else
      text_chunk << char
    end
  end

  if !text_chunk.empty?
    state[:text] = text_chunk.join
  end
  if !ansi_stack.empty?
    unpack_ansi(ansi_stack) { |attr, name| state[attr] = name}
  end
  if !state[:text].to_s.empty?
    result.push(state)
  end
  result
end

.unpack_ansi(ansi_stack) {|Symbol, Symbol| ... } ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Remove from current stack all ansi codes

Parameters:

  • ansi_stack (Array[Integer])

    the stack with all the ansi codes

Yields:

  • (Symbol, Symbol)

    attr, name


90
91
92
93
94
# File 'lib/pastel/color_parser.rb', line 90

def self.unpack_ansi(ansi_stack)
  ansi_stack.each do |code|
    yield(attribute_name(code), color_name(code))
  end
end