Class: DiffToHtml

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

Direct Known Subclasses

GitDiffToHtml, SvnDiffToHtml

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#file_prefixObject

Returns the value of attribute file_prefix.



5
6
7
# File 'lib/diff_to_html.rb', line 5

def file_prefix
  @file_prefix
end

Instance Method Details

#begin_file(file) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
# File 'lib/diff_to_html.rb', line 66

def begin_file(file)
  result = "<li><h2><a name=\"F\#{@filenum}\" href=\"#F\#{@filenum}\">\#{file}</a></h2><table class='diff'>\n<colgroup>\n<col class=\"lineno\"/>\n<col class=\"lineno\"/>\n<col class=\"content\"/>\n</colgroup>\n" 
result
end

#composite_to_html(composite_diff) ⇒ Object



182
183
184
# File 'lib/diff_to_html.rb', line 182

def composite_to_html(composite_diff)
  diffs_to_html get_diffs(composite_diff)
end

#diffs_to_html(diffs) ⇒ Object



171
172
173
174
175
176
177
178
179
180
# File 'lib/diff_to_html.rb', line 171

def diffs_to_html(diffs)
  result = '<ul class="diff">'
  @filenum = 0
  diffs.each do |file_map|
    result << get_single_file_diff(file_map[:filename], file_map[:file])
    @filenum += 1
  end
  result << '</ul>'
  result    
end

#file_header_patternObject



153
154
155
# File 'lib/diff_to_html.rb', line 153

def file_header_pattern
  raise "Method to be implemented in VCS-specific class"
end

#flush_changes(result, left_ln, right_ln) ⇒ Object



78
79
80
81
82
83
84
# File 'lib/diff_to_html.rb', line 78

def flush_changes(result, left_ln, right_ln)
  x, left_ln, right_ln = get_diff_row(left_ln, right_ln)
  result << x
  @left.clear
  @right.clear    
  return left_ln, right_ln
end

#get_diff_row(left_ln, right_ln) ⇒ Object

helper for building the next row in the diff



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/diff_to_html.rb', line 20

def get_diff_row(left_ln, right_ln)
  result = []
  if @left.length > 0 or @right.length > 0
    modified = (@last_op != ' ')
    if modified
      left_class = " class='r'"
      right_class = " class='a'"
      result << "<tbody class='mod'>"
    else
      left_class = right_class = ''
    end
    result << @left.map do |line| 
      x = "<tr#{left_class}>#{ln_cell(left_ln, 'l')}"
      if modified
        x += ln_cell(nil)
      else
        x += ln_cell(right_ln, 'r')
        right_ln += 1
      end
      x += "<td>#{line}</td></tr>"
      left_ln += 1
      x
    end
    if modified
      result << @right.map do |line| 
        x = "<tr#{right_class}>#{ln_cell(nil)}#{ln_cell(right_ln, 'r')}<td>#{line}</td></tr>"
        right_ln += 1
        x
      end
      result << "</tbody>"
    end
  end
  return result.join("\n"), left_ln, right_ln
end

#get_diffs(composite_diff) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/diff_to_html.rb', line 157

def get_diffs(composite_diff)
  pattern = file_header_pattern
  files = composite_diff.split(pattern)
  headers = composite_diff.scan(pattern) #huh can't find a way to get both at once
  files.shift if files[0] == '' #first one is junk usually
  result = []
  i = 0
  files.each do |file|
    result << {:filename => "#{file_prefix}#{get_filename(headers[i])}", :file => file}
    i += 1
  end
  result
end

#get_single_file_diff(file_name, diff_file) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/diff_to_html.rb', line 86

def get_single_file_diff(file_name, diff_file)
  @last_op = ' '
  @left = []
  @right = []

  result = ""

  diff = diff_file.split("\n")
  
  diff.shift #index
  line = nil
  while line !~ /^---/ && !diff.empty?
    line = diff.shift
  end
  header_old = line
  if line =~ /^---/
    diff.shift #+++
    
    result << begin_file(file_name)
    range = diff.shift
    left_ln, right_ln = range_info(range)
    result << range_row(range)
    
    diff.each do |line|
      op = line[0,1]
      line = line[1..-1] || ''
      if op == '\\'
        line = op + line
        op = ' '
      end
      
      if ((@last_op != ' ' and op == ' ') or (@last_op == ' ' and op != ' '))
        left_ln, right_ln = flush_changes(result, left_ln, right_ln)
      end
      
      # truncate and escape
      line = CGI.escapeHTML(line)

      case op
      when ' '
        @left.push(line)
        @right.push(line)
      when '-' then @left.push(line)
      when '+' then @right.push(line)
      when '@' 
        range = '@' + line
        flush_changes(result, left_ln, right_ln)
        left_ln, right_ln = range_info(range)
        result << range_row(range)
      else
        flush_changes(result, left_ln, right_ln)
        result << "</table></li>"
        break
      end
      @last_op = op
    end

    flush_changes(result, left_ln, right_ln)
    result << "</table></li>"      
  else
    #"<div class='error'>#{header_old}</div>"
    result =%Q{<li><h2><a name="F#{@filenum}" href="#F#{@filenum}">#{file_name}</a></h2>#{header_old}</li>}
  end

  result
end

#ln_cell(ln, side = nil) ⇒ Object



7
8
9
10
11
12
13
14
15
# File 'lib/diff_to_html.rb', line 7

def ln_cell(ln, side = nil)
  anchor = "f#{@filenum}#{side}#{ln}"
  result = "<td class = 'ln'>"
  result += "<a name='#{anchor}' href='##{anchor}'>" if ln
  result += "#{ln}"
  result += "</a>" if ln
  result += "</td>"
  result
end

#range_info(range) ⇒ Object



59
60
61
62
63
64
# File 'lib/diff_to_html.rb', line 59

def range_info(range)
  range.match(/^@@ \-(\d+),\d+ \+(\d+),\d+ @@/)
  left_ln = Integer($1)
  right_ln = Integer($2)
  return left_ln, right_ln
end

#range_row(range) ⇒ Object



55
56
57
# File 'lib/diff_to_html.rb', line 55

def range_row(range)
  "<tr class='range'><td>...</td<td>...</td><td>#{range}</td></tr>"
end