##// END OF EJS Templates
Switch order of current and previous revisions in side-by-side diff (#1903)....
Jean-Philippe Lang -
r1893:8cb75be0dbd7
parent child
Show More
@@ -1,178 +1,178
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2008 Jean-Philippe Lang
2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 module Redmine
18 module Redmine
19 # Class used to parse unified diffs
19 # Class used to parse unified diffs
20 class UnifiedDiff < Array
20 class UnifiedDiff < Array
21 def initialize(diff, type="inline")
21 def initialize(diff, type="inline")
22 diff_table = DiffTable.new type
22 diff_table = DiffTable.new type
23 diff.each do |line|
23 diff.each do |line|
24 if line =~ /^(---|\+\+\+) (.*)$/
24 if line =~ /^(---|\+\+\+) (.*)$/
25 self << diff_table if diff_table.length > 1
25 self << diff_table if diff_table.length > 1
26 diff_table = DiffTable.new type
26 diff_table = DiffTable.new type
27 end
27 end
28 a = diff_table.add_line line
28 a = diff_table.add_line line
29 end
29 end
30 self << diff_table unless diff_table.empty?
30 self << diff_table unless diff_table.empty?
31 self
31 self
32 end
32 end
33 end
33 end
34
34
35 # Class that represents a file diff
35 # Class that represents a file diff
36 class DiffTable < Hash
36 class DiffTable < Hash
37 attr_reader :file_name, :line_num_l, :line_num_r
37 attr_reader :file_name, :line_num_l, :line_num_r
38
38
39 # Initialize with a Diff file and the type of Diff View
39 # Initialize with a Diff file and the type of Diff View
40 # The type view must be inline or sbs (side_by_side)
40 # The type view must be inline or sbs (side_by_side)
41 def initialize(type="inline")
41 def initialize(type="inline")
42 @parsing = false
42 @parsing = false
43 @nb_line = 1
43 @nb_line = 1
44 @start = false
44 @start = false
45 @before = 'same'
45 @before = 'same'
46 @second = true
46 @second = true
47 @type = type
47 @type = type
48 end
48 end
49
49
50 # Function for add a line of this Diff
50 # Function for add a line of this Diff
51 def add_line(line)
51 def add_line(line)
52 unless @parsing
52 unless @parsing
53 if line =~ /^(---|\+\+\+) (.*)$/
53 if line =~ /^(---|\+\+\+) (.*)$/
54 @file_name = $2
54 @file_name = $2
55 return false
55 return false
56 elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
56 elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
57 @line_num_l = $5.to_i
57 @line_num_l = $2.to_i
58 @line_num_r = $2.to_i
58 @line_num_r = $5.to_i
59 @parsing = true
59 @parsing = true
60 end
60 end
61 else
61 else
62 if line =~ /^[^\+\-\s@\\]/
62 if line =~ /^[^\+\-\s@\\]/
63 @parsing = false
63 @parsing = false
64 return false
64 return false
65 elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
65 elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
66 @line_num_l = $5.to_i
66 @line_num_l = $2.to_i
67 @line_num_r = $2.to_i
67 @line_num_r = $5.to_i
68 else
68 else
69 @nb_line += 1 if parse_line(line, @type)
69 @nb_line += 1 if parse_line(line, @type)
70 end
70 end
71 end
71 end
72 return true
72 return true
73 end
73 end
74
74
75 def inspect
75 def inspect
76 puts '### DIFF TABLE ###'
76 puts '### DIFF TABLE ###'
77 puts "file : #{file_name}"
77 puts "file : #{file_name}"
78 self.each do |d|
78 self.each do |d|
79 d.inspect
79 d.inspect
80 end
80 end
81 end
81 end
82
82
83 private
83 private
84 # Test if is a Side By Side type
84 # Test if is a Side By Side type
85 def sbs?(type, func)
85 def sbs?(type, func)
86 if @start and type == "sbs"
86 if @start and type == "sbs"
87 if @before == func and @second
87 if @before == func and @second
88 tmp_nb_line = @nb_line
88 tmp_nb_line = @nb_line
89 self[tmp_nb_line] = Diff.new
89 self[tmp_nb_line] = Diff.new
90 else
90 else
91 @second = false
91 @second = false
92 tmp_nb_line = @start
92 tmp_nb_line = @start
93 @start += 1
93 @start += 1
94 @nb_line -= 1
94 @nb_line -= 1
95 end
95 end
96 else
96 else
97 tmp_nb_line = @nb_line
97 tmp_nb_line = @nb_line
98 @start = @nb_line
98 @start = @nb_line
99 self[tmp_nb_line] = Diff.new
99 self[tmp_nb_line] = Diff.new
100 @second = true
100 @second = true
101 end
101 end
102 unless self[tmp_nb_line]
102 unless self[tmp_nb_line]
103 @nb_line += 1
103 @nb_line += 1
104 self[tmp_nb_line] = Diff.new
104 self[tmp_nb_line] = Diff.new
105 else
105 else
106 self[tmp_nb_line]
106 self[tmp_nb_line]
107 end
107 end
108 end
108 end
109
109
110 # Escape the HTML for the diff
110 # Escape the HTML for the diff
111 def escapeHTML(line)
111 def escapeHTML(line)
112 CGI.escapeHTML(line)
112 CGI.escapeHTML(line)
113 end
113 end
114
114
115 def parse_line(line, type="inline")
115 def parse_line(line, type="inline")
116 if line[0, 1] == "+"
116 if line[0, 1] == "+"
117 diff = sbs? type, 'add'
117 diff = sbs? type, 'add'
118 @before = 'add'
118 @before = 'add'
119 diff.line_left = escapeHTML line[1..-1]
119 diff.line_right = escapeHTML line[1..-1]
120 diff.nb_line_left = @line_num_l
120 diff.nb_line_right = @line_num_r
121 diff.type_diff_left = 'diff_in'
121 diff.type_diff_right = 'diff_in'
122 @line_num_l += 1
122 @line_num_r += 1
123 true
123 true
124 elsif line[0, 1] == "-"
124 elsif line[0, 1] == "-"
125 diff = sbs? type, 'remove'
125 diff = sbs? type, 'remove'
126 @before = 'remove'
126 @before = 'remove'
127 diff.line_right = escapeHTML line[1..-1]
127 diff.line_left = escapeHTML line[1..-1]
128 diff.nb_line_right = @line_num_r
128 diff.nb_line_left = @line_num_l
129 diff.type_diff_right = 'diff_out'
129 diff.type_diff_left = 'diff_out'
130 @line_num_r += 1
130 @line_num_l += 1
131 true
131 true
132 elsif line[0, 1] =~ /\s/
132 elsif line[0, 1] =~ /\s/
133 @before = 'same'
133 @before = 'same'
134 @start = false
134 @start = false
135 diff = Diff.new
135 diff = Diff.new
136 diff.line_right = escapeHTML line[1..-1]
136 diff.line_right = escapeHTML line[1..-1]
137 diff.nb_line_right = @line_num_r
137 diff.nb_line_right = @line_num_r
138 diff.line_left = escapeHTML line[1..-1]
138 diff.line_left = escapeHTML line[1..-1]
139 diff.nb_line_left = @line_num_l
139 diff.nb_line_left = @line_num_l
140 self[@nb_line] = diff
140 self[@nb_line] = diff
141 @line_num_l += 1
141 @line_num_l += 1
142 @line_num_r += 1
142 @line_num_r += 1
143 true
143 true
144 elsif line[0, 1] = "\\"
144 elsif line[0, 1] = "\\"
145 true
145 true
146 else
146 else
147 false
147 false
148 end
148 end
149 end
149 end
150 end
150 end
151
151
152 # A line of diff
152 # A line of diff
153 class Diff
153 class Diff
154 attr_accessor :nb_line_left
154 attr_accessor :nb_line_left
155 attr_accessor :line_left
155 attr_accessor :line_left
156 attr_accessor :nb_line_right
156 attr_accessor :nb_line_right
157 attr_accessor :line_right
157 attr_accessor :line_right
158 attr_accessor :type_diff_right
158 attr_accessor :type_diff_right
159 attr_accessor :type_diff_left
159 attr_accessor :type_diff_left
160
160
161 def initialize()
161 def initialize()
162 self.nb_line_left = ''
162 self.nb_line_left = ''
163 self.nb_line_right = ''
163 self.nb_line_right = ''
164 self.line_left = ''
164 self.line_left = ''
165 self.line_right = ''
165 self.line_right = ''
166 self.type_diff_right = ''
166 self.type_diff_right = ''
167 self.type_diff_left = ''
167 self.type_diff_left = ''
168 end
168 end
169
169
170 def inspect
170 def inspect
171 puts '### Start Line Diff ###'
171 puts '### Start Line Diff ###'
172 puts self.nb_line_left
172 puts self.nb_line_left
173 puts self.line_left
173 puts self.line_left
174 puts self.nb_line_right
174 puts self.nb_line_right
175 puts self.line_right
175 puts self.line_right
176 end
176 end
177 end
177 end
178 end
178 end
General Comments 0
You need to be logged in to leave comments. Login now