Class: Yay::Colourizer

Inherits:
Object
  • Object
show all
Defined in:
lib/yay/colourizer.rb

Overview

this class adds colour to a stream based on rules that have been generated by a parser

Instance Method Summary collapse

Constructor Details

#initialize(rules, input, output) ⇒ Colourizer

create a colourizer using specified parser rules and input and output streams (usually stdin/stdout)



9
10
11
12
13
14
15
16
17
18
19
# File 'lib/yay/colourizer.rb', line 9

def initialize rules, input, output
  colourize_rules rules
  @input   = input
  @output  = output
  
  # this is the colour we'll use when we haven't already applied a colour
  # we remember the previous choice as we can colourize words within a line
  # that's already been coloured
  @default_end_colour = ColourWheel::end_colour
  @end_colour = @default_end_colour
end

Instance Method Details

#apply_line_rules(line) ⇒ Object

apply all rules that span the entire line



57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/yay/colourizer.rb', line 57

def apply_line_rules line
  # track the line_rules end colour so we can return to this after each
  # match
  @line_rules.each { |rule| 
    if line.match(rule[0])
      line = "#{rule[1]}#{line.rstrip}#{@default_end_colour}"
      @end_colour = rule[1]
      # leave loop; only allow one line match per line
      break
    end
  }
  return line
end

#apply_word_rules(line) ⇒ Object

apply all partial rules



72
73
74
75
76
77
# File 'lib/yay/colourizer.rb', line 72

def apply_word_rules line
  @part_rules.each { |rule|
    line = line.gsub(rule[0], "#{rule[1]}\\0#{@end_colour}")
  }
  return line
end

#colourize_pipeObject

create a pipe between the input and output streams, applying colour rules to every line that appears. only an interrupt, end of file or exception will end this process



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/yay/colourizer.rb', line 82

def colourize_pipe
  @end_colour = @default_end_colour
  begin
    @input.each_line { |line|
      line = apply_line_rules(line)
      line = apply_word_rules(line)
      @output.puts line
    }
  rescue Errno::EPIPE
    # ignore the Broken Pipe error that is caused by tools like head
  end
end

#colourize_rules(rules) ⇒ Object

process the rules created by a parser and determine the actual strings we need to emit when we use this colour. this breaks parser rules up in to two categories - line rules and part rules



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/yay/colourizer.rb', line 36

def colourize_rules rules
  @line_rules = []
  @part_rules = []

  rules.each { |rule|

    regex   = rule[0]
    colours = rule[1]
    is_line = rule[2]

    colour_string = ColourWheel::begin_colours(colours)

    if is_line
      @line_rules.unshift [regex, colour_string]
    else
      @part_rules.unshift [regex, colour_string]
    end
  }
end

#line_rulesObject

get the rules that are applied to a whole line if it contains matching text of the form [[regex, colour_string],..]



23
24
25
# File 'lib/yay/colourizer.rb', line 23

def line_rules
  @line_rules
end

#part_rulesObject

get the rules that are applied to matching text of the form [[regex, colour_string],..]



29
30
31
# File 'lib/yay/colourizer.rb', line 29

def part_rules
  @part_rules
end