docdiff 0.6.5 → 0.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +7 -7
- data/Guardfile +4 -4
- data/Makefile +1 -1
- data/Rakefile +6 -6
- data/bin/docdiff +1 -1
- data/devutil/Rakefile +12 -5
- data/devutil/char_by_charclass.rb +43 -20
- data/devutil/charclass_by_char.rb +40 -19
- data/devutil/jis0208.rb +263 -231
- data/devutil/jis0208_test.rb +196 -0
- data/doc/news.md +8 -0
- data/docdiff.gemspec +12 -10
- data/lib/doc_diff.rb +59 -60
- data/lib/docdiff/charstring.rb +225 -241
- data/lib/docdiff/cli.rb +285 -250
- data/lib/docdiff/diff/contours.rb +1 -1
- data/lib/docdiff/diff/editscript.rb +1 -1
- data/lib/docdiff/diff/rcsdiff.rb +1 -1
- data/lib/docdiff/diff/shortestpath.rb +1 -1
- data/lib/docdiff/diff/speculative.rb +1 -1
- data/lib/docdiff/diff/subsequence.rb +1 -1
- data/lib/docdiff/diff/unidiff.rb +1 -1
- data/lib/docdiff/diff.rb +1 -1
- data/lib/docdiff/difference.rb +71 -70
- data/lib/docdiff/document.rb +129 -109
- data/lib/docdiff/encoding/en_ascii.rb +64 -58
- data/lib/docdiff/encoding/ja_eucjp.rb +250 -235
- data/lib/docdiff/encoding/ja_sjis.rb +240 -226
- data/lib/docdiff/encoding/ja_utf8.rb +6952 -6939
- data/lib/docdiff/version.rb +1 -1
- data/lib/docdiff/view.rb +522 -438
- data/lib/docdiff.rb +2 -2
- data/test/charstring_test.rb +475 -351
- data/test/cli_test.rb +103 -101
- data/test/diff_test.rb +15 -16
- data/test/difference_test.rb +40 -31
- data/test/docdiff_test.rb +162 -136
- data/test/document_test.rb +280 -175
- data/test/test_helper.rb +2 -1
- data/test/view_test.rb +636 -497
- metadata +8 -8
- data/devutil/testjis0208.rb +0 -38
data/lib/docdiff/cli.rb
CHANGED
|
@@ -1,281 +1,316 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "optparse"
|
|
2
2
|
|
|
3
3
|
class DocDiff
|
|
4
4
|
module CLI
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
parser
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
54
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
5
|
+
class << self
|
|
6
|
+
def parse_options!(args, base_options: {})
|
|
7
|
+
o = base_options.dup
|
|
8
|
+
|
|
9
|
+
option_parser = OptionParser.new do |parser|
|
|
10
|
+
parser.on(
|
|
11
|
+
"--resolution=RESOLUTION",
|
|
12
|
+
resolutions = ["line", "word", "char"],
|
|
13
|
+
"specify resolution (granularity)",
|
|
14
|
+
"#{resolutions.join("|")} (default: word)",
|
|
15
|
+
) { |s| o[:resolution] = (s || "word") }
|
|
16
|
+
parser.on("--line", "same as --resolution=line") { o[:resolution] = "line" }
|
|
17
|
+
parser.on("--word", "same as --resolution=word") { o[:resolution] = "word" }
|
|
18
|
+
parser.on("--char", "same as --resolution=char") { o[:resolution] = "char" }
|
|
19
|
+
|
|
20
|
+
parser.on(
|
|
21
|
+
'--encoding=ENCODING',
|
|
22
|
+
encodings = ['ASCII', 'EUC-JP', 'Shift_JIS', 'CP932', 'UTF-8', 'auto'],
|
|
23
|
+
encoding_aliases = {
|
|
24
|
+
"ascii" => "ASCII",
|
|
25
|
+
"euc-jp" => "EUC-JP",
|
|
26
|
+
"shift_jis" => "Shift_JIS",
|
|
27
|
+
"cp932" => "CP932",
|
|
28
|
+
"utf-8" => "UTF-8",
|
|
29
|
+
},
|
|
30
|
+
"specify character encoding",
|
|
31
|
+
"#{encodings.join("|")} (default: auto)",
|
|
32
|
+
"(try ASCII for single byte encodings such as ISO-8859)",
|
|
33
|
+
) { |s| o[:encoding] = (s || "auto") }
|
|
34
|
+
parser.on("--ascii", "same as --encoding=ASCII") { o[:encoding] = "ASCII" }
|
|
35
|
+
parser.on("--iso8859", "same as --encoding=ASCII") { o[:encoding] = "ASCII" }
|
|
36
|
+
parser.on("--iso8859x", "same as --encoding=ASCII (deprecated)") { o[:encoding] = "ASCII" }
|
|
37
|
+
parser.on("--eucjp", "same as --encoding=EUC-JP") { o[:encoding] = "EUC-JP" }
|
|
38
|
+
parser.on("--sjis", "same as --encoding=Shift_JIS") { o[:encoding] = "Shift_JIS" }
|
|
39
|
+
parser.on("--cp932", "same as --encoding=CP932") { o[:encoding] = "CP932" }
|
|
40
|
+
parser.on("--utf8", "same as --encoding=UTF-8") { o[:encoding] = "UTF-8" }
|
|
41
|
+
|
|
42
|
+
parser.on(
|
|
43
|
+
"--eol=EOL",
|
|
44
|
+
eols = ["CR", "LF", "CRLF", "auto"],
|
|
45
|
+
eol_aliases = { "cr" => "CR", "lf" => "LF", "crlf" => "CRLF" },
|
|
46
|
+
"specify end-of-line character",
|
|
47
|
+
"#{eols.join("|")} (default: auto)",
|
|
48
|
+
) { |s| o[:eol] = (s || "auto") }
|
|
49
|
+
parser.on("--cr", "same as --eol=CR") { o[:eol] = "CR" }
|
|
50
|
+
parser.on("--lf", "same as --eol=LF") { o[:eol] = "LF" }
|
|
51
|
+
parser.on("--crlf", "same as --eol=CRLF") { o[:eol] = "CRLF" }
|
|
52
|
+
|
|
53
|
+
parser.on(
|
|
54
|
+
"--format=FORMAT",
|
|
55
|
+
formats = ["tty", "manued", "html", "wdiff", "stat", "user"],
|
|
56
|
+
"specify output format",
|
|
57
|
+
"#{formats.join("|")} (default: html) (stat is deprecated)",
|
|
58
|
+
"(user tags can be defined in config file)",
|
|
59
|
+
) { |s| o[:format] = (s || "manued") }
|
|
60
|
+
parser.on("--tty", "same as --format=tty") { o[:format] = "tty" }
|
|
61
|
+
parser.on("--manued", "same as --format=manued") { o[:format] = "manued" }
|
|
62
|
+
parser.on("--html", "same as --format=html") { o[:format] = "html" }
|
|
63
|
+
parser.on("--wdiff", "same as --format=wdiff") { o[:format] = "wdiff" }
|
|
64
|
+
parser.on("--stat", "same as --format=stat (not implemented) (deprecated)") { o[:format] = "stat" }
|
|
65
|
+
|
|
66
|
+
parser.on(
|
|
67
|
+
"--label LABEL",
|
|
68
|
+
"-L LABEL",
|
|
69
|
+
"use label instead of file name (not implemented; exists for compatibility with diff)",
|
|
70
|
+
) do |s|
|
|
71
|
+
o[:label] ||= []
|
|
72
|
+
o[:label] << s
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
parser.on("--digest", "digest output, do not show all") { o[:digest] = true }
|
|
76
|
+
parser.on("--summary", "same as --digest") { o[:digest] = true }
|
|
77
|
+
|
|
78
|
+
parser.on(
|
|
79
|
+
"--display=DISPLAY",
|
|
80
|
+
display_types = ["inline", "block", "multi"],
|
|
81
|
+
"specify presentation type (effective only with digest; experimental feature)",
|
|
82
|
+
"#{display_types.join("|")} (default: inline) (multi is deprecated)",
|
|
83
|
+
) { |s| o[:display] ||= s.downcase }
|
|
84
|
+
|
|
85
|
+
parser.on("--cache", "use file cache (not implemented) (deprecated)") { o[:cache] = true }
|
|
86
|
+
parser.on(
|
|
87
|
+
"--pager=PAGER",
|
|
88
|
+
String,
|
|
89
|
+
"specify pager (if available, $DOCDIFF_PAGER is used by default)",
|
|
90
|
+
) { |s| o[:pager] = s }
|
|
91
|
+
parser.on("--no-pager", "do not use pager") { o[:pager] = false }
|
|
92
|
+
parser.on("--config-file=FILE", String, "specify config file to read") { |s| o[:config_file] = s }
|
|
93
|
+
parser.on("--no-config-file", "do not read config files") { o[:no_config_file] = true }
|
|
94
|
+
parser.on("--verbose", "run verbosely (not well-supported) (deprecated)") { o[:verbose] = true }
|
|
95
|
+
|
|
96
|
+
parser.on("--help", "show this message") do
|
|
97
|
+
puts parser
|
|
98
|
+
exit(0)
|
|
99
|
+
end
|
|
100
|
+
parser.on("--version", "show version") do
|
|
101
|
+
puts Docdiff::VERSION
|
|
102
|
+
exit(0)
|
|
103
|
+
end
|
|
104
|
+
parser.on("--license", "show license (deprecated)") do
|
|
105
|
+
puts DocDiff::License
|
|
106
|
+
exit(0)
|
|
107
|
+
end
|
|
108
|
+
parser.on("--author", "show author(s) (deprecated)") do
|
|
109
|
+
puts DocDiff::Author
|
|
110
|
+
exit(0)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
parser.on_tail(
|
|
114
|
+
"When invoked as worddiff or chardiff, resolution will be set accordingly.",
|
|
115
|
+
"Config files: /etc/docdiff/docdiff.conf, ~/.config/docdiff/docdiff.conf (or ~/etc/docdiff/docdiff.conf (deprecated))",
|
|
116
|
+
)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
option_parser.parse!(args)
|
|
120
|
+
o
|
|
91
121
|
end
|
|
92
122
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
123
|
+
def parse_config_file_content(content)
|
|
124
|
+
result = {}
|
|
125
|
+
return result if content.size <= 0
|
|
96
126
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
end
|
|
127
|
+
lines = content.dup.split(/\r\n|\r|\n/).compact
|
|
128
|
+
lines.collect! { |line| line.sub(/#.*$/, "") }
|
|
129
|
+
lines.collect!(&:strip)
|
|
130
|
+
lines.delete_if { |line| line == "" }
|
|
131
|
+
lines.each do |line|
|
|
132
|
+
raise 'line does not include " = ".' unless /[\s]+=[\s]+/.match(line)
|
|
133
|
+
|
|
134
|
+
name_src, value_src = line.split(/[\s]+=[\s]+/)
|
|
135
|
+
raise "Invalid name: #{name_src.inspect}" if /\s/.match(name_src)
|
|
136
|
+
raise "Invalid value: #{value_src.inspect}" unless value_src.is_a?(String)
|
|
137
|
+
|
|
138
|
+
name = name_src.intern
|
|
139
|
+
value = value_src
|
|
140
|
+
value = true if ["on", "yes", "true"].include?(value_src.downcase)
|
|
141
|
+
value = false if ["off", "no", "false"].include?(value_src.downcase)
|
|
142
|
+
value = value_src.to_i if /^[0-9]+$/.match(value_src)
|
|
143
|
+
result[name] = value
|
|
144
|
+
end
|
|
145
|
+
result
|
|
146
|
+
end
|
|
118
147
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
148
|
+
def read_config_from_file(filename)
|
|
149
|
+
content = nil
|
|
150
|
+
begin
|
|
151
|
+
File.open(filename, "r") { |f| content = f.read }
|
|
152
|
+
rescue => exception
|
|
153
|
+
raise exception
|
|
154
|
+
ensure
|
|
155
|
+
message =
|
|
156
|
+
case exception
|
|
157
|
+
in Errno::ENOENT
|
|
158
|
+
"config file not found: #{filename.inspect}"
|
|
159
|
+
in Errno::EACCES
|
|
160
|
+
"permission denied for reading: #{filename.inspect}"
|
|
161
|
+
else
|
|
162
|
+
"something unexpected happened: #{filename.inspect}"
|
|
163
|
+
end
|
|
164
|
+
if content
|
|
165
|
+
config = parse_config_file_content(content)
|
|
132
166
|
else
|
|
133
|
-
"
|
|
167
|
+
message = "config file empty: #{filename.inspect}"
|
|
134
168
|
end
|
|
135
|
-
if content
|
|
136
|
-
config = parse_config_file_content(content)
|
|
137
|
-
else
|
|
138
|
-
message = "config file empty: #{filename.inspect}"
|
|
139
169
|
end
|
|
170
|
+
[config, message]
|
|
140
171
|
end
|
|
141
|
-
[config, message]
|
|
142
|
-
end
|
|
143
172
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
173
|
+
def print_or_write_to_pager(content, pager)
|
|
174
|
+
if $stdout.tty? && pager.is_a?(String) && !pager.empty?
|
|
175
|
+
IO.popen(pager, "w") { |f| f.print(content) }
|
|
176
|
+
else
|
|
177
|
+
print(content)
|
|
178
|
+
end
|
|
149
179
|
end
|
|
150
|
-
end
|
|
151
180
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
181
|
+
def run
|
|
182
|
+
command_line_config = parse_options!(ARGV)
|
|
183
|
+
|
|
184
|
+
system_config =
|
|
185
|
+
unless command_line_config[:no_config_file]
|
|
186
|
+
possible_system_config_file_names = [
|
|
187
|
+
DocDiff::SystemConfigFileName,
|
|
188
|
+
]
|
|
189
|
+
existing_system_config_file_names =
|
|
190
|
+
possible_system_config_file_names.select { |fn| File.exist?(fn) }
|
|
191
|
+
if existing_system_config_file_names.size >= 2
|
|
192
|
+
raise <<~EOS
|
|
193
|
+
More than one system config file found, using the first one: \
|
|
194
|
+
#{existing_system_config_file_names.inspect}
|
|
195
|
+
EOS
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
filename = existing_system_config_file_names.first
|
|
199
|
+
config, message = read_config_from_file(filename)
|
|
200
|
+
$stderr.print(message) if command_line_config[:verbose]
|
|
201
|
+
config
|
|
167
202
|
end
|
|
168
|
-
filename = existing_system_config_file_names.first
|
|
169
|
-
config, message = read_config_from_file(filename)
|
|
170
|
-
STDERR.print message if command_line_config[:verbose]
|
|
171
|
-
config
|
|
172
|
-
end
|
|
173
203
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
204
|
+
user_config =
|
|
205
|
+
unless command_line_config[:no_config_file]
|
|
206
|
+
possible_user_config_file_names = [
|
|
207
|
+
DocDiff::UserConfigFileName,
|
|
208
|
+
DocDiff::AltUserConfigFileName,
|
|
209
|
+
DocDiff::XDGUserConfigFileName,
|
|
210
|
+
]
|
|
211
|
+
existing_user_config_file_names =
|
|
212
|
+
possible_user_config_file_names.select { |fn| File.exist?(fn) }
|
|
213
|
+
if existing_user_config_file_names.size >= 2
|
|
214
|
+
raise <<~EOS
|
|
215
|
+
Only one user config file can be used at the same time. \
|
|
216
|
+
Keep one and remove or rename the others: \
|
|
217
|
+
#{existing_user_config_file_names.inspect}
|
|
218
|
+
EOS
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
filename = existing_user_config_file_names.first
|
|
222
|
+
config, message = read_config_from_file(filename)
|
|
223
|
+
$stderr.print(message) if command_line_config[:verbose]
|
|
224
|
+
config
|
|
189
225
|
end
|
|
190
|
-
filename = existing_user_config_file_names.first
|
|
191
|
-
config, message = read_config_from_file(filename)
|
|
192
|
-
STDERR.print message if command_line_config[:verbose]
|
|
193
|
-
config
|
|
194
|
-
end
|
|
195
226
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
227
|
+
config_from_specified_file =
|
|
228
|
+
if (filename = command_line_config[:config_file])
|
|
229
|
+
config, message = read_config_from_file(filename)
|
|
230
|
+
$stderr.print(message) if command_line_config[:verbose] == true
|
|
231
|
+
config
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
config_from_program_name =
|
|
235
|
+
case File.basename($PROGRAM_NAME, ".*")
|
|
236
|
+
when "worddiff" then { resolution: "word" }
|
|
237
|
+
when "chardiff" then { resolution: "char" }
|
|
238
|
+
end
|
|
202
239
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
when "chardiff" then {:resolution => "char"}
|
|
240
|
+
config_from_env_vars = {}
|
|
241
|
+
if (pager = ENV["DOCDIFF_PAGER"]) && !pager.empty?
|
|
242
|
+
config_from_env_vars[:pager] = pager
|
|
207
243
|
end
|
|
208
244
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
245
|
+
config_in_effect = DocDiff::DEFAULT_CONFIG.dup
|
|
246
|
+
config_in_effect.merge!(config_from_program_name) if config_from_program_name
|
|
247
|
+
config_in_effect.merge!(system_config) if system_config
|
|
248
|
+
config_in_effect.merge!(user_config) if user_config
|
|
249
|
+
config_in_effect.merge!(config_from_env_vars) if config_from_env_vars
|
|
250
|
+
config_in_effect.merge!(config_from_specified_file) if config_from_specified_file
|
|
251
|
+
config_in_effect.merge!(command_line_config) if command_line_config
|
|
252
|
+
|
|
253
|
+
docdiff = DocDiff.new(config: config_in_effect)
|
|
254
|
+
|
|
255
|
+
file1_content = nil
|
|
256
|
+
file2_content = nil
|
|
257
|
+
raise "Try `#{File.basename($PROGRAM_NAME)} --help' for more information." if ARGV[0].nil?
|
|
258
|
+
raise "Specify at least 2 target files." unless ARGV[0] && ARGV[1]
|
|
259
|
+
|
|
260
|
+
ARGV[0] = "/dev/stdin" if ARGV[0] == "-"
|
|
261
|
+
ARGV[1] = "/dev/stdin" if ARGV[1] == "-"
|
|
262
|
+
raise "No such file: #{ARGV[0]}." unless FileTest.exist?(ARGV[0])
|
|
263
|
+
raise "No such file: #{ARGV[1]}." unless FileTest.exist?(ARGV[1])
|
|
264
|
+
raise "#{ARGV[0]} is not readable." unless FileTest.readable?(ARGV[0])
|
|
265
|
+
raise "#{ARGV[1]} is not readable." unless FileTest.readable?(ARGV[1])
|
|
266
|
+
|
|
267
|
+
File.open(ARGV[0], "r") { |f| file1_content = f.read }
|
|
268
|
+
File.open(ARGV[1], "r") { |f| file2_content = f.read }
|
|
213
269
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
raise "Specify at least 2 target files." unless ARGV[0] && ARGV[1]
|
|
228
|
-
ARGV[0] = "/dev/stdin" if ARGV[0] == "-"
|
|
229
|
-
ARGV[1] = "/dev/stdin" if ARGV[1] == "-"
|
|
230
|
-
raise "No such file: #{ARGV[0]}." unless FileTest.exist?(ARGV[0])
|
|
231
|
-
raise "No such file: #{ARGV[1]}." unless FileTest.exist?(ARGV[1])
|
|
232
|
-
raise "#{ARGV[0]} is not readable." unless FileTest.readable?(ARGV[0])
|
|
233
|
-
raise "#{ARGV[1]} is not readable." unless FileTest.readable?(ARGV[1])
|
|
234
|
-
File.open(ARGV[0], "r"){|f| file1_content = f.read}
|
|
235
|
-
File.open(ARGV[1], "r"){|f| file2_content = f.read}
|
|
236
|
-
|
|
237
|
-
doc1 = nil
|
|
238
|
-
doc2 = nil
|
|
239
|
-
|
|
240
|
-
encoding1 = docdiff.config[:encoding]
|
|
241
|
-
encoding2 = docdiff.config[:encoding]
|
|
242
|
-
eol1 = docdiff.config[:eol]
|
|
243
|
-
eol2 = docdiff.config[:eol]
|
|
244
|
-
|
|
245
|
-
if docdiff.config[:encoding] == "auto"
|
|
246
|
-
encoding1 = DocDiff::CharString.guess_encoding(file1_content)
|
|
247
|
-
encoding2 = DocDiff::CharString.guess_encoding(file2_content)
|
|
248
|
-
case
|
|
249
|
-
when (encoding1 == "UNKNOWN" or encoding2 == "UNKNOWN")
|
|
250
|
-
raise "Document encoding unknown (#{encoding1}, #{encoding2})."
|
|
251
|
-
when encoding1 != encoding2
|
|
252
|
-
raise "Document encoding mismatch (#{encoding1}, #{encoding2})."
|
|
270
|
+
encoding1 = docdiff.config[:encoding]
|
|
271
|
+
encoding2 = docdiff.config[:encoding]
|
|
272
|
+
eol1 = docdiff.config[:eol]
|
|
273
|
+
eol2 = docdiff.config[:eol]
|
|
274
|
+
|
|
275
|
+
if docdiff.config[:encoding] == "auto"
|
|
276
|
+
encoding1 = DocDiff::CharString.guess_encoding(file1_content)
|
|
277
|
+
encoding2 = DocDiff::CharString.guess_encoding(file2_content)
|
|
278
|
+
if (encoding1 == "UNKNOWN") || (encoding2 == "UNKNOWN")
|
|
279
|
+
raise "Document encoding unknown (#{encoding1}, #{encoding2})."
|
|
280
|
+
elsif encoding1 != encoding2
|
|
281
|
+
raise "Document encoding mismatch (#{encoding1}, #{encoding2})."
|
|
282
|
+
end
|
|
253
283
|
end
|
|
254
|
-
end
|
|
255
284
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
285
|
+
if docdiff.config[:eol] == "auto"
|
|
286
|
+
eol1 = DocDiff::CharString.guess_eol(file1_content)
|
|
287
|
+
eol2 = DocDiff::CharString.guess_eol(file2_content)
|
|
288
|
+
if eol1.nil? || eol2.nil?
|
|
289
|
+
raise "Document eol is nil (#{eol1.inspect}, #{eol2.inspect}). The document might be empty."
|
|
290
|
+
elsif (eol1 == "UNKNOWN") || (eol2 == "UNKNOWN")
|
|
291
|
+
raise "Document eol unknown (#{eol1.inspect}, #{eol2.inspect})."
|
|
292
|
+
elsif eol1 != eol2
|
|
293
|
+
raise "Document eol mismatch (#{eol1}, #{eol2})."
|
|
294
|
+
end
|
|
266
295
|
end
|
|
267
|
-
end
|
|
268
296
|
|
|
269
|
-
|
|
270
|
-
|
|
297
|
+
doc1 = DocDiff::Document.new(file1_content, encoding1, eol1)
|
|
298
|
+
doc2 = DocDiff::Document.new(file2_content, encoding2, eol2)
|
|
271
299
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
300
|
+
output =
|
|
301
|
+
docdiff.run(
|
|
302
|
+
doc1,
|
|
303
|
+
doc2,
|
|
304
|
+
{
|
|
305
|
+
resolution: docdiff.config[:resolution],
|
|
306
|
+
format: docdiff.config[:format],
|
|
307
|
+
digest: docdiff.config[:digest],
|
|
308
|
+
display: docdiff.config[:display],
|
|
309
|
+
},
|
|
310
|
+
)
|
|
277
311
|
|
|
278
|
-
|
|
312
|
+
print_or_write_to_pager(output, docdiff.config[:pager])
|
|
313
|
+
end
|
|
279
314
|
end
|
|
280
315
|
end
|
|
281
316
|
end
|
data/lib/docdiff/diff/rcsdiff.rb
CHANGED
data/lib/docdiff/diff/unidiff.rb
CHANGED
data/lib/docdiff/diff.rb
CHANGED