class Pastel::ColorParser
Responsible for parsing color symbols out of text with color escapes
Used internally by {Color}.
@api private
Constants
- CSI
- ESC
Public Class Methods
ansi_for(ansi)
click to toggle source
@api private
# File lib/pastel/color_parser.rb, line 115 def self.ansi_for(ansi) ATTRIBUTES.key(ansi.to_i) end
attribute_for(ansi)
click to toggle source
Decide attribute name for ansi
@param [Integer] ansi
the ansi escape code
@return [Symbol]
@api private
# File lib/pastel/color_parser.rb, line 104 def self.attribute_for(ansi) if ANSI.foreground?(ansi) :foreground elsif ANSI.background?(ansi) :background elsif ANSI.style?(ansi) :style end end
parse(text)
click to toggle source
Parse color escape sequences into a list of hashes corresponding to the color attributes being set by these sequences
@example
parse("\e[32mfoo\e[0m") # => [{colors: [:green], text: 'foo'}
@param [String] text
the text to parse for presence of color ansi codes
@return [Array[Hash]]
@api public
# File lib/pastel/color_parser.rb, line 30 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(/^0m/) 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 } ansi_stack = [] end scanner[1].split(/:|;/).each do |code| ansi_stack << code end end if !text_chunk.empty? state[:text] = text_chunk result.push(state) state = {} text_chunk = '' 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 end if !ansi_stack.empty? unpack_ansi(ansi_stack) { |attr, name| state[attr] = name} end if state.values.any? { |val| !val.empty? } result.push(state) end result end
unpack_ansi(ansi_stack) { |attr, name| ... }
click to toggle source
Remove from current stack all ansi codes
@param [Array] ansi_stack
the stack with all the ansi codes
@yield [Symbol, Symbol] attr, name
@api private
# File lib/pastel/color_parser.rb, line 88 def self.unpack_ansi(ansi_stack) ansi_stack.each do |ansi| name = ansi_for(ansi) attr = attribute_for(ansi) yield attr, name end end