Class: Diff::Display::Unified::Generator

Inherits:
Object
  • Object
show all
Defined in:
lib/diff/display/unified/generator.rb

Overview

Processes the diff and generates a Data object which contains the resulting data structure.

The run class method is fed a diff and returns a Data object. It will accept as its argument a String, an Array or a File object (or anything that responds to #each):

Diff::Display::Unified::Generator.run(diff)

Constant Summary collapse

LINE_NUM_RE =

Extracts the line number info for a given diff section

/^@@ [+-]([0-9]+)(?:,([0-9]+))? [+-]([0-9]+)(?:,([0-9]+))? @@/
LINE_TYPES =
{'+' => :add, '-' => :rem, ' ' => :unmod, '\\' => :nonewline}

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeGenerator

Returns a new instance of Generator.



32
33
34
35
36
37
38
39
# File 'lib/diff/display/unified/generator.rb', line 32

def initialize
  @buffer         = []
  @line_type      = nil
  @prev_line_type = nil
  @offset         = [0, 0]
  @data = Data.new
  self
end

Class Method Details

.run(udiff) ⇒ Object

Runs the generator on a diff and returns a Data object

Raises:

  • (ArgumentError)


18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/diff/display/unified/generator.rb', line 18

def self.run(udiff)
  raise ArgumentError, "Object must be enumerable" unless udiff.respond_to?(:each_line)
  generator = new
  udiff.each_line do |line|
    begin
      generator.process(line.chomp)
    rescue ArgumentError => e
      e.message =~ /^invalid byte sequence/ ? next : raise(e)
    end
  end
  generator.finish
  generator.data
end

Instance Method Details

#dataObject

Finishes up with the generation and returns the Data object (could probably use a better name…maybe just #data?)



43
44
45
# File 'lib/diff/display/unified/generator.rb', line 43

def data
  @data
end

#finishObject

This method is called once the generator is done with the unified diff. It is a finalizer of sorts. By the time it is called all data has been collected and processed.



50
51
52
53
# File 'lib/diff/display/unified/generator.rb', line 50

def finish
  # certain things could be set now that processing is done
  #identify_block
end

#process(line) ⇒ Object



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
81
82
83
84
85
86
# File 'lib/diff/display/unified/generator.rb', line 55

def process(line)      
  if is_header_line?(line)
    push Block.header
    current_block << Line.header(line)
    return
  end
  
  if line =~ LINE_NUM_RE
    push Block.header
    current_block << Line.header(line)
    add_separator unless @offset[0].zero?
    @line_type = nil
    @offset    = Array.new(2) { $3.to_i - 1 }
    return
  end
  
  @line_type, line = LINE_TYPES[car(line)], cdr(line)
  
  if @line_type == :add && @prev_line_type == :rem
    @offset[0] -= 1
    @buffer.push current_block.pop
    @buffer.push line
    process_block(:mod, false)
    return
  end
  
  if LINE_TYPES.values.include?(@line_type)
    @buffer.push(line.to_s)
    process_block(@line_type, true)
  end
  
end