daff 1.2.3 → 1.2.4
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.
- data/README.md +4 -1
- data/lib/daff.rb +20 -7
- data/lib/lib/coopy/alignment.rb +6 -0
- data/lib/lib/coopy/cell_info.rb +1 -0
- data/lib/lib/coopy/compare_flags.rb +2 -0
- data/lib/lib/coopy/compare_table.rb +1 -1
- data/lib/lib/coopy/coopy.rb +80 -18
- data/lib/lib/coopy/csv.rb +1 -1
- data/lib/lib/coopy/diff_render.rb +61 -22
- data/lib/lib/coopy/flat_cell_builder.rb +1 -1
- data/lib/lib/coopy/highlight_patch.rb +8 -6
- data/lib/lib/coopy/mover.rb +1 -1
- data/lib/lib/coopy/ndjson.rb +134 -0
- data/lib/lib/coopy/nested_cell_builder.rb +74 -0
- data/lib/lib/coopy/simple_view.rb +29 -0
- data/lib/lib/coopy/sql_column.rb +35 -0
- data/lib/lib/coopy/sql_compare.rb +245 -0
- data/lib/lib/coopy/sql_database.rb +19 -0
- data/lib/lib/coopy/sql_helper.rb +12 -0
- data/lib/lib/coopy/sql_table.rb +216 -0
- data/lib/lib/coopy/sql_table_name.rb +23 -0
- data/lib/lib/coopy/sqlite_helper.rb +47 -0
- data/lib/lib/coopy/table_diff.rb +18 -6
- data/lib/lib/coopy/table_io.rb +5 -0
- data/lib/lib/coopy/terminal_diff_render.rb +8 -9
- data/lib/lib/coopy/view.rb +5 -0
- data/lib/lib/haxe/ds/int_map.rb +4 -0
- data/lib/lib/haxe/ds/string_map.rb +4 -0
- data/lib/lib/haxe/format/json_parser.rb +8 -8
- data/lib/lib/haxe/imap.rb +1 -0
- data/lib/lib/haxe/io/bytes.rb +1 -1
- data/lib/lib/haxe/io/bytes_output.rb +1 -1
- data/lib/lib/haxe/io/error.rb +1 -0
- data/lib/lib/haxe/io/output.rb +2 -2
- data/lib/lib/hx_overrides.rb +12 -0
- data/lib/lib/hx_sys.rb +1 -1
- data/lib/lib/rb/boot.rb +5 -1
- data/lib/lib/reflect.rb +1 -0
- data/lib/lib/sys/io/file_handle.rb +1 -0
- data/lib/lib/sys/io/file_output.rb +1 -1
- data/lib/lib/value_type.rb +1 -0
- metadata +36 -25
data/README.md
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
[](http://badge.fury.io/rb/daff)
|
4
4
|
[](http://badge.fury.io/py/daff)
|
5
5
|
[](http://badge.fury.io/ph/paulfitz%2Fdaff-php)
|
6
|
+
[](https://gratipay.com/paulfitz/)
|
6
7
|
|
7
8
|
daff: data diff
|
8
9
|
===============
|
@@ -47,7 +48,7 @@ daff can produce and apply tabular diffs.
|
|
47
48
|
Call as:
|
48
49
|
daff [--output OUTPUT.csv] a.csv b.csv
|
49
50
|
daff [--output OUTPUT.csv] parent.csv a.csv b.csv
|
50
|
-
daff [--output OUTPUT.
|
51
|
+
daff [--output OUTPUT.ndjson] a.ndjson b.ndjson
|
51
52
|
daff patch [--inplace] [--output OUTPUT.csv] a.csv patch.csv
|
52
53
|
daff merge [--inplace] [--output OUTPUT.csv] parent.csv a.csv b.csv
|
53
54
|
daff trim [--output OUTPUT.csv] source.csv
|
@@ -72,6 +73,8 @@ If you need more control, here is the full list of flags:
|
|
72
73
|
--plain: do not use fancy utf8 characters to make arrows prettier
|
73
74
|
````
|
74
75
|
|
76
|
+
Formats supported are CSV, TSV, and [ndjson](http://dataprotocols.org/ndjson/).
|
77
|
+
|
75
78
|
Using with git
|
76
79
|
--------------
|
77
80
|
|
data/lib/daff.rb
CHANGED
@@ -55,17 +55,25 @@ require_relative 'lib/coopy/index_item'
|
|
55
55
|
require_relative 'lib/coopy/index_pair'
|
56
56
|
require_relative 'lib/coopy/merger'
|
57
57
|
require_relative 'lib/coopy/mover'
|
58
|
+
require_relative 'lib/coopy/ndjson'
|
59
|
+
require_relative 'lib/coopy/nested_cell_builder'
|
58
60
|
require_relative 'lib/coopy/ordering'
|
59
61
|
require_relative 'lib/coopy/table'
|
60
62
|
require_relative 'lib/coopy/simple_table'
|
61
63
|
require_relative 'lib/coopy/view'
|
62
64
|
require_relative 'lib/coopy/simple_view'
|
63
65
|
require_relative 'lib/coopy/sparse_sheet'
|
66
|
+
require_relative 'lib/coopy/sql_column'
|
67
|
+
require_relative 'lib/coopy/sql_compare'
|
68
|
+
require_relative 'lib/coopy/sql_database'
|
69
|
+
require_relative 'lib/coopy/sql_helper'
|
70
|
+
require_relative 'lib/coopy/sql_table'
|
71
|
+
require_relative 'lib/coopy/sql_table_name'
|
72
|
+
require_relative 'lib/coopy/sqlite_helper'
|
64
73
|
require_relative 'lib/coopy/table_comparison_state'
|
65
74
|
require_relative 'lib/coopy/table_diff'
|
66
75
|
require_relative 'lib/coopy/table_io'
|
67
76
|
require_relative 'lib/coopy/table_modifier'
|
68
|
-
require_relative 'lib/coopy/table_text'
|
69
77
|
require_relative 'lib/coopy/terminal_diff_render'
|
70
78
|
require_relative 'lib/coopy/unit'
|
71
79
|
require_relative 'lib/coopy/viterbi'
|
@@ -96,16 +104,21 @@ def _hx_ord(s) return 0 if s.nil?; s.ord end
|
|
96
104
|
$hx_exception_classes = {}
|
97
105
|
def hx_exception_class(c)
|
98
106
|
$hx_exception_classes[c.name] ||= Class.new(RuntimeError) do
|
99
|
-
Object.const_set((c.name.split(/::/)
|
100
|
-
|
101
|
-
def
|
102
|
-
@target.send(name, *args, &block)
|
103
|
-
end
|
107
|
+
Object.const_set((c.name.split(/::/)[-1]||'') + 'HaxeException',self)
|
108
|
+
attr_accessor :hx_exception_target
|
109
|
+
def initialize(target) @hx_exception_target = target; end
|
104
110
|
end
|
105
111
|
end
|
106
|
-
def
|
112
|
+
def hx_raise(x)
|
107
113
|
hx_exception_class(x.class).new(x)
|
108
114
|
end
|
115
|
+
def hx_rescue(x)
|
116
|
+
hx_exception_class(x.class)
|
117
|
+
end
|
118
|
+
def hx_rescued(x)
|
119
|
+
return x.hx_exception_target if x.respond_to? :hx_exception_target
|
120
|
+
x
|
121
|
+
end
|
109
122
|
|
110
123
|
|
111
124
|
Daff = Coopy
|
data/lib/lib/coopy/alignment.rb
CHANGED
@@ -96,6 +96,12 @@ module Coopy
|
|
96
96
|
return @order_cache
|
97
97
|
end
|
98
98
|
|
99
|
+
def add_to_order(l,r,p = -2)
|
100
|
+
@order_cache = ::Coopy::Ordering.new if @order_cache == nil
|
101
|
+
@order_cache.add(l,r,p)
|
102
|
+
@order_cache_has_reference = p != -2
|
103
|
+
end
|
104
|
+
|
99
105
|
def get_source
|
100
106
|
return @ta
|
101
107
|
end
|
data/lib/lib/coopy/cell_info.rb
CHANGED
@@ -16,6 +16,7 @@ module Coopy
|
|
16
16
|
@acts = nil
|
17
17
|
@ids = nil
|
18
18
|
@columns_to_ignore = nil
|
19
|
+
@allow_nested_cells = false
|
19
20
|
end
|
20
21
|
|
21
22
|
attr_accessor :ordered
|
@@ -29,6 +30,7 @@ module Coopy
|
|
29
30
|
attr_accessor :acts
|
30
31
|
attr_accessor :ids
|
31
32
|
attr_accessor :columns_to_ignore
|
33
|
+
attr_accessor :allow_nested_cells
|
32
34
|
|
33
35
|
def filter(act,allow)
|
34
36
|
if @acts == nil
|
data/lib/lib/coopy/coopy.rb
CHANGED
@@ -9,6 +9,9 @@ module Coopy
|
|
9
9
|
@format_preference = nil
|
10
10
|
@delim_preference = nil
|
11
11
|
@output_format = "copy"
|
12
|
+
@nested_output = false
|
13
|
+
@order_set = false
|
14
|
+
@order_preference = false
|
12
15
|
end
|
13
16
|
|
14
17
|
# protected - in ruby this doesn't play well with static/inline methods
|
@@ -17,6 +20,9 @@ module Coopy
|
|
17
20
|
attr_accessor :delim_preference
|
18
21
|
attr_accessor :extern_preference
|
19
22
|
attr_accessor :output_format
|
23
|
+
attr_accessor :nested_output
|
24
|
+
attr_accessor :order_set
|
25
|
+
attr_accessor :order_preference
|
20
26
|
attr_accessor :io
|
21
27
|
attr_accessor :mv
|
22
28
|
|
@@ -25,10 +31,12 @@ module Coopy
|
|
25
31
|
ext = ""
|
26
32
|
pt = name.rindex(".",nil || 0) || -1
|
27
33
|
if pt >= 0
|
28
|
-
ext = name
|
34
|
+
ext = HxOverrides.substr(name,pt + 1,nil).to_lower_case
|
29
35
|
case(ext)
|
30
36
|
when "json"
|
31
37
|
@format_preference = "json"
|
38
|
+
when "ndjson"
|
39
|
+
@format_preference = "ndjson"
|
32
40
|
when "csv"
|
33
41
|
@format_preference = "csv"
|
34
42
|
@delim_preference = ","
|
@@ -38,10 +46,16 @@ module Coopy
|
|
38
46
|
when "ssv"
|
39
47
|
@format_preference = "csv"
|
40
48
|
@delim_preference = ";"
|
49
|
+
when "sqlite3"
|
50
|
+
@format_preference = "sqlite"
|
51
|
+
when "sqlite"
|
52
|
+
@format_preference = "sqlite"
|
41
53
|
else
|
42
54
|
ext = ""
|
43
55
|
end
|
44
56
|
end
|
57
|
+
@nested_output = @format_preference == "json" || @format_preference == "ndjson"
|
58
|
+
@order_preference = !@nested_output
|
45
59
|
return ext
|
46
60
|
end
|
47
61
|
|
@@ -55,12 +69,17 @@ module Coopy
|
|
55
69
|
self.set_format(@output_format) if @output_format != "copy"
|
56
70
|
txt = ""
|
57
71
|
self.check_format(name)
|
58
|
-
if @format_preference
|
72
|
+
if @format_preference == "csv"
|
59
73
|
csv = ::Coopy::Csv.new(@delim_preference)
|
60
74
|
txt = csv.render_table(t)
|
75
|
+
elsif @format_preference == "ndjson"
|
76
|
+
txt = ::Coopy::Ndjson.new(t).render
|
77
|
+
elsif @format_preference == "sqlite"
|
78
|
+
@io.write_stderr("! Cannot yet output to sqlite, aborting\n")
|
79
|
+
return false
|
61
80
|
else
|
62
81
|
value = ::Coopy::Coopy.jsonify(t)
|
63
|
-
txt = ::Haxe::Format::JsonPrinter._print(value,nil,
|
82
|
+
txt = ::Haxe::Format::JsonPrinter._print(value,nil," ")
|
64
83
|
end
|
65
84
|
return self.save_text(name,txt)
|
66
85
|
end
|
@@ -77,14 +96,40 @@ module Coopy
|
|
77
96
|
def load_table(name)
|
78
97
|
txt = @io.get_content(name)
|
79
98
|
ext = self.check_format(name)
|
99
|
+
if ext == "sqlite"
|
100
|
+
sql = @io.open_sqlite_database(name)
|
101
|
+
if sql == nil
|
102
|
+
@io.write_stderr("! Cannot open database, aborting\n")
|
103
|
+
return nil
|
104
|
+
end
|
105
|
+
helper = ::Coopy::SqliteHelper.new
|
106
|
+
names = helper.get_table_names(sql)
|
107
|
+
if names == nil
|
108
|
+
@io.write_stderr("! Cannot find database tables, aborting\n")
|
109
|
+
return nil
|
110
|
+
end
|
111
|
+
if names.length == 0
|
112
|
+
@io.write_stderr("! No tables in database, aborting\n")
|
113
|
+
return nil
|
114
|
+
end
|
115
|
+
tab = ::Coopy::SqlTable.new(sql,::Coopy::SqlTableName.new(names[0]),helper)
|
116
|
+
return tab
|
117
|
+
end
|
118
|
+
if ext == "ndjson"
|
119
|
+
t = ::Coopy::SimpleTable.new(0,0)
|
120
|
+
ndjson = ::Coopy::Ndjson.new(t)
|
121
|
+
ndjson.parse(txt)
|
122
|
+
return t
|
123
|
+
end
|
80
124
|
begin
|
81
125
|
json = ::Haxe::Format::JsonParser.new(txt).parse_rec
|
82
126
|
@format_preference = "json"
|
83
|
-
|
84
|
-
raise "JSON failed" if
|
85
|
-
return
|
127
|
+
t1 = ::Coopy::Coopy.json_to_table(json)
|
128
|
+
raise hx_raise("JSON failed") if t1 == nil
|
129
|
+
return t1
|
86
130
|
rescue => e
|
87
|
-
|
131
|
+
e = hx_rescued(e)
|
132
|
+
raise hx_raise(e) if ext == "json"
|
88
133
|
end if ext == "json" || ext == ""
|
89
134
|
@format_preference = "csv"
|
90
135
|
csv = ::Coopy::Csv.new(@delim_preference)
|
@@ -344,6 +389,19 @@ module Coopy
|
|
344
389
|
git = true
|
345
390
|
args.slice!(i,1)
|
346
391
|
break
|
392
|
+
elsif tag == "--unordered"
|
393
|
+
more = true
|
394
|
+
flags.ordered = false
|
395
|
+
flags.unchanged_context = 0
|
396
|
+
@order_set = true
|
397
|
+
args.slice!(i,1)
|
398
|
+
break
|
399
|
+
elsif tag == "--ordered"
|
400
|
+
more = true
|
401
|
+
flags.ordered = true
|
402
|
+
@order_set = true
|
403
|
+
args.slice!(i,1)
|
404
|
+
break
|
347
405
|
elsif tag == "--color"
|
348
406
|
more = true
|
349
407
|
color = true
|
@@ -415,7 +473,7 @@ module Coopy
|
|
415
473
|
io.write_stderr("Call as:\n")
|
416
474
|
io.write_stderr(" daff [--color] [--output OUTPUT.csv] a.csv b.csv\n")
|
417
475
|
io.write_stderr(" daff [--output OUTPUT.csv] parent.csv a.csv b.csv\n")
|
418
|
-
io.write_stderr(" daff [--output OUTPUT.
|
476
|
+
io.write_stderr(" daff [--output OUTPUT.ndjson] a.ndjson b.ndjson\n")
|
419
477
|
io.write_stderr(" daff patch [--inplace] [--output OUTPUT.csv] a.csv patch.csv\n")
|
420
478
|
io.write_stderr(" daff merge [--inplace] [--output OUTPUT.csv] parent.csv a.csv b.csv\n")
|
421
479
|
io.write_stderr(" daff trim [--output OUTPUT.csv] source.csv\n")
|
@@ -428,14 +486,16 @@ module Coopy
|
|
428
486
|
io.write_stderr("\n")
|
429
487
|
io.write_stderr("If you need more control, here is the full list of flags:\n")
|
430
488
|
io.write_stderr(" daff diff [--output OUTPUT.csv] [--context NUM] [--all] [--act ACT] a.csv b.csv\n")
|
431
|
-
io.write_stderr(" --
|
432
|
-
io.write_stderr(" --
|
489
|
+
io.write_stderr(" --act ACT: show only a certain kind of change (update, insert, delete)\n")
|
490
|
+
io.write_stderr(" --all: do not prune unchanged rows\n")
|
433
491
|
io.write_stderr(" --color: highlight changes with terminal colors\n")
|
434
492
|
io.write_stderr(" --context NUM: show NUM rows of context\n")
|
435
|
-
io.write_stderr(" --
|
436
|
-
io.write_stderr(" --
|
493
|
+
io.write_stderr(" --id: specify column to use as primary key (repeat for multi-column key)\n")
|
494
|
+
io.write_stderr(" --ignore: specify column to ignore completely (can repeat)\n")
|
437
495
|
io.write_stderr(" --input-format [csv|tsv|ssv|json]: set format to expect for input\n")
|
496
|
+
io.write_stderr(" --ordered: assume row order is meaningful (default for CSV)\n")
|
438
497
|
io.write_stderr(" --output-format [csv|tsv|ssv|json|copy]: set format for output\n")
|
498
|
+
io.write_stderr(" --unordered: assume row order is meaningless (default for json formats)\n")
|
439
499
|
io.write_stderr("\n")
|
440
500
|
io.write_stderr(" daff diff --git path old-file old-hex old-mode new-file new-hex new-mode\n")
|
441
501
|
io.write_stderr(" --git: process arguments provided by git to diff drivers\n")
|
@@ -501,6 +561,11 @@ module Coopy
|
|
501
561
|
output = "-" if output == nil
|
502
562
|
ok = true
|
503
563
|
if cmd1 == "diff"
|
564
|
+
if !@order_set
|
565
|
+
flags.ordered = @order_preference
|
566
|
+
flags.unchanged_context = 0 if !flags.ordered
|
567
|
+
end
|
568
|
+
flags.allow_nested_cells = @nested_output
|
504
569
|
ct1 = ::Coopy::Coopy.compare_tables3(parent,a,b,flags)
|
505
570
|
align = ct1.align
|
506
571
|
td = ::Coopy::TableDiff.new(align,flags)
|
@@ -545,7 +610,7 @@ module Coopy
|
|
545
610
|
class << self
|
546
611
|
attr_accessor :version
|
547
612
|
end
|
548
|
-
@version = "1.2.
|
613
|
+
@version = "1.2.4"
|
549
614
|
|
550
615
|
def Coopy.compare_tables(local,remote,flags = nil)
|
551
616
|
comp = ::Coopy::TableComparisonState.new
|
@@ -578,6 +643,7 @@ module Coopy
|
|
578
643
|
hp = ::Coopy::HighlightPatch.new(nil,nil)
|
579
644
|
csv = ::Coopy::Csv.new
|
580
645
|
tm = ::Coopy::TableModifier.new(nil)
|
646
|
+
sc = ::Coopy::SqlCompare.new(nil,nil,nil)
|
581
647
|
return 0
|
582
648
|
end
|
583
649
|
|
@@ -697,11 +763,7 @@ module Coopy
|
|
697
763
|
x = _g1
|
698
764
|
_g1+=1
|
699
765
|
v = t.get_cell(x,y)
|
700
|
-
|
701
|
-
row.push(v[:to_s].call)
|
702
|
-
else
|
703
|
-
row.push(nil)
|
704
|
-
end
|
766
|
+
row.push(v)
|
705
767
|
end
|
706
768
|
end
|
707
769
|
sheet.push(row)
|
data/lib/lib/coopy/csv.rb
CHANGED
@@ -188,7 +188,7 @@ module Coopy
|
|
188
188
|
return nil if result == "NULL"
|
189
189
|
if first_non_underscore > start
|
190
190
|
del = first_non_underscore - start
|
191
|
-
return result
|
191
|
+
return HxOverrides.substr(result,1,nil) if HxOverrides.substr(result,del,nil) == "NULL"
|
192
192
|
end
|
193
193
|
end
|
194
194
|
return result
|
@@ -17,6 +17,7 @@ module Coopy
|
|
17
17
|
attr_accessor :td_close
|
18
18
|
attr_accessor :open
|
19
19
|
attr_accessor :pretty_arrows
|
20
|
+
attr_accessor :section
|
20
21
|
|
21
22
|
public
|
22
23
|
|
@@ -32,6 +33,22 @@ module Coopy
|
|
32
33
|
|
33
34
|
def begin_table
|
34
35
|
self.insert("<table>\n")
|
36
|
+
@section = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_section(str)
|
40
|
+
return if str == @section
|
41
|
+
if @section != nil
|
42
|
+
self.insert("</t")
|
43
|
+
self.insert(@section)
|
44
|
+
self.insert(">\n")
|
45
|
+
end
|
46
|
+
@section = str
|
47
|
+
if @section != nil
|
48
|
+
self.insert("<t")
|
49
|
+
self.insert(@section)
|
50
|
+
self.insert(">\n")
|
51
|
+
end
|
35
52
|
end
|
36
53
|
|
37
54
|
def begin_row(mode)
|
@@ -41,9 +58,8 @@ module Coopy
|
|
41
58
|
if mode == "header"
|
42
59
|
@td_open = "<th"
|
43
60
|
@td_close = "</th>"
|
44
|
-
else
|
45
|
-
row_class = mode
|
46
61
|
end
|
62
|
+
row_class = mode
|
47
63
|
tr = "<tr>"
|
48
64
|
tr = "<tr class=\"" + _hx_str(row_class) + "\">" if row_class != ""
|
49
65
|
self.insert(tr)
|
@@ -62,6 +78,7 @@ module Coopy
|
|
62
78
|
end
|
63
79
|
|
64
80
|
def end_table
|
81
|
+
self.set_section(nil)
|
65
82
|
self.insert("</table>\n")
|
66
83
|
end
|
67
84
|
|
@@ -80,9 +97,9 @@ module Coopy
|
|
80
97
|
render = self
|
81
98
|
render.begin_table
|
82
99
|
change_row = -1
|
83
|
-
tt = ::Coopy::TableText.new(tab)
|
84
100
|
cell = ::Coopy::CellInfo.new
|
85
|
-
|
101
|
+
view = tab.get_cell_view
|
102
|
+
corner = view.to_s(tab.get_cell(0,0))
|
86
103
|
off = nil
|
87
104
|
if corner == "@:@"
|
88
105
|
off = 1
|
@@ -99,11 +116,16 @@ module Coopy
|
|
99
116
|
row = _g1
|
100
117
|
_g1+=1
|
101
118
|
open = false
|
102
|
-
txt =
|
119
|
+
txt = view.to_s(tab.get_cell(off,row))
|
103
120
|
txt = "" if txt == nil
|
104
|
-
::Coopy::DiffRender.examine_cell(
|
121
|
+
::Coopy::DiffRender.examine_cell(off,row,view,txt,"",txt,corner,cell,off)
|
105
122
|
row_mode = cell.category
|
106
123
|
change_row = row if row_mode == "spec"
|
124
|
+
if row_mode == "header" || row_mode == "spec" || row_mode == "index"
|
125
|
+
self.set_section("head")
|
126
|
+
else
|
127
|
+
self.set_section("body")
|
128
|
+
end
|
107
129
|
render.begin_row(row_mode)
|
108
130
|
begin
|
109
131
|
_g3 = 0
|
@@ -111,7 +133,7 @@ module Coopy
|
|
111
133
|
while(_g3 < _g2)
|
112
134
|
c = _g3
|
113
135
|
_g3+=1
|
114
|
-
::Coopy::DiffRender.examine_cell(c,row,
|
136
|
+
::Coopy::DiffRender.examine_cell(c,row,view,tab.get_cell(c,row),((change_row >= 0) ? view.to_s(tab.get_cell(c,change_row)) : ""),txt,corner,cell,off)
|
115
137
|
render.insert_cell(((@pretty_arrows) ? cell.pretty_value : cell.value),cell.category_given_tr)
|
116
138
|
end
|
117
139
|
end
|
@@ -123,17 +145,20 @@ module Coopy
|
|
123
145
|
end
|
124
146
|
|
125
147
|
def sample_css
|
126
|
-
return ".highlighter .add { \n background-color: #7fff7f;\n}\n\n.highlighter .remove { \n background-color: #ff7f7f;\n}\n\n.highlighter td.modify { \n background-color: #7f7fff;\n}\n\n.highlighter td.conflict { \n background-color: #f00;\n}\n\n.highlighter .spec { \n background-color: #aaa;\n}\n\n.highlighter .move { \n background-color: #ffa;\n}\n\n.highlighter .null { \n color: #888;\n}\n\n.highlighter table { \n border-collapse:collapse;\n}\n\n.highlighter td, .highlighter th {\n border: 1px solid #2D4068;\n padding: 3px 7px 2px;\n}\n\n.highlighter th, .highlighter .header { \n background-color: #aaf;\n font-weight: bold;\n padding-bottom: 4px;\n padding-top: 5px;\n text-align:left;\n}\n\n.highlighter tr
|
148
|
+
return ".highlighter .add { \n background-color: #7fff7f;\n}\n\n.highlighter .remove { \n background-color: #ff7f7f;\n}\n\n.highlighter td.modify { \n background-color: #7f7fff;\n}\n\n.highlighter td.conflict { \n background-color: #f00;\n}\n\n.highlighter .spec { \n background-color: #aaa;\n}\n\n.highlighter .move { \n background-color: #ffa;\n}\n\n.highlighter .null { \n color: #888;\n}\n\n.highlighter table { \n border-collapse:collapse;\n}\n\n.highlighter td, .highlighter th {\n border: 1px solid #2D4068;\n padding: 3px 7px 2px;\n}\n\n.highlighter th, .highlighter .header { \n background-color: #aaf;\n font-weight: bold;\n padding-bottom: 4px;\n padding-top: 5px;\n text-align:left;\n}\n\n.highlighter tr.header th {\n border-bottom: 2px solid black;\n}\n\n.highlighter tr.index td, .highlighter .index, .highlighter tr.header th.index {\n background-color: white;\n border: none;\n}\n\n.highlighter .gap {\n color: #888;\n}\n\n.highlighter td {\n empty-cells: show;\n}\n"
|
127
149
|
end
|
128
150
|
|
129
151
|
def complete_html
|
130
|
-
@text_to_insert.insert(0,"<html>\n<meta charset='utf-8'>\n<
|
152
|
+
@text_to_insert.insert(0,"<!DOCTYPE html>\n<html>\n<head>\n<meta charset='utf-8'>\n<style TYPE='text/css'>\n")
|
131
153
|
@text_to_insert.insert(1,self.sample_css)
|
132
154
|
@text_to_insert.insert(2,"</style>\n</head>\n<body>\n<div class='highlighter'>\n")
|
133
155
|
@text_to_insert.push("</div>\n</body>\n</html>\n")
|
134
156
|
end
|
135
157
|
|
136
|
-
def DiffRender.examine_cell(x,y,
|
158
|
+
def DiffRender.examine_cell(x,y,view,raw,vcol,vrow,vcorner,cell,offset = 0)
|
159
|
+
nested = view.is_hash(raw)
|
160
|
+
value = nil
|
161
|
+
value = view.to_s(raw) if !nested
|
137
162
|
cell.category = ""
|
138
163
|
cell.category_given_tr = ""
|
139
164
|
cell.separator = ""
|
@@ -148,6 +173,7 @@ module Coopy
|
|
148
173
|
vcol = "" if vcol == nil
|
149
174
|
removed_column = false
|
150
175
|
cell.category = "move" if vrow == ":"
|
176
|
+
cell.category = "index" if vrow == "" && offset == 1 && y == 0
|
151
177
|
if (vcol.index("+++",nil || 0) || -1) >= 0
|
152
178
|
cell.category_given_tr = cell.category = "add"
|
153
179
|
elsif (vcol.index("---",nil || 0) || -1) >= 0
|
@@ -158,6 +184,8 @@ module Coopy
|
|
158
184
|
cell.category = "spec"
|
159
185
|
elsif vrow == "@@"
|
160
186
|
cell.category = "header"
|
187
|
+
elsif vrow == "..."
|
188
|
+
cell.category = "gap"
|
161
189
|
elsif vrow == "+++"
|
162
190
|
cell.category = "add" if !removed_column
|
163
191
|
elsif vrow == "---"
|
@@ -168,20 +196,30 @@ module Coopy
|
|
168
196
|
full = vrow
|
169
197
|
part = tokens[1]
|
170
198
|
part = full if part == nil
|
171
|
-
if (cell.value.index(part,nil || 0) || -1) >= 0
|
199
|
+
if nested || (cell.value.index(part,nil || 0) || -1) >= 0
|
172
200
|
cat = "modify"
|
173
201
|
div = part
|
174
202
|
if part != full
|
175
|
-
if
|
203
|
+
if nested
|
204
|
+
cell.conflicted = view.hash_exists(raw,"theirs")
|
205
|
+
else
|
206
|
+
cell.conflicted = (cell.value.index(full,nil || 0) || -1) >= 0
|
207
|
+
end
|
208
|
+
if cell.conflicted
|
176
209
|
div = full
|
177
210
|
cat = "conflict"
|
178
|
-
cell.conflicted = true
|
179
211
|
end
|
180
212
|
end
|
181
213
|
cell.updated = true
|
182
214
|
cell.separator = div
|
183
215
|
cell.pretty_separator = div
|
184
|
-
if
|
216
|
+
if nested
|
217
|
+
if cell.conflicted
|
218
|
+
tokens = [view.hash_get(raw,"before"),view.hash_get(raw,"ours"),view.hash_get(raw,"theirs")]
|
219
|
+
else
|
220
|
+
tokens = [view.hash_get(raw,"before"),view.hash_get(raw,"after")]
|
221
|
+
end
|
222
|
+
elsif cell.pretty_value == div
|
185
223
|
tokens = ["",""]
|
186
224
|
else
|
187
225
|
tokens = cell.pretty_value.split(div)
|
@@ -199,18 +237,19 @@ module Coopy
|
|
199
237
|
cell.pretty_separator = [8594].pack("U")
|
200
238
|
cell.pretty_value = pretty_tokens.join(cell.pretty_separator)
|
201
239
|
cell.category_given_tr = cell.category = cat
|
202
|
-
|
240
|
+
offset1 = nil
|
203
241
|
if cell.conflicted
|
204
|
-
|
242
|
+
offset1 = 1
|
205
243
|
else
|
206
|
-
|
244
|
+
offset1 = 0
|
207
245
|
end
|
208
|
-
cell.lvalue = tokens[
|
209
|
-
cell.rvalue = tokens[
|
246
|
+
cell.lvalue = tokens[offset1]
|
247
|
+
cell.rvalue = tokens[offset1 + 1]
|
210
248
|
cell.pvalue = tokens[0] if cell.conflicted
|
211
249
|
end
|
212
250
|
end
|
213
251
|
end
|
252
|
+
cell.category_given_tr = cell.category = "index" if x == 0 && offset > 0
|
214
253
|
end
|
215
254
|
|
216
255
|
# protected - in ruby this doesn't play well with static/inline methods
|
@@ -244,16 +283,16 @@ module Coopy
|
|
244
283
|
|
245
284
|
public
|
246
285
|
|
247
|
-
def DiffRender.render_cell(
|
286
|
+
def DiffRender.render_cell(tab,view,x,y)
|
248
287
|
cell = ::Coopy::CellInfo.new
|
249
|
-
corner =
|
288
|
+
corner = view.to_s(tab.get_cell(0,0))
|
250
289
|
off = nil
|
251
290
|
if corner == "@:@"
|
252
291
|
off = 1
|
253
292
|
else
|
254
293
|
off = 0
|
255
294
|
end
|
256
|
-
::Coopy::DiffRender.examine_cell(x,y,
|
295
|
+
::Coopy::DiffRender.examine_cell(x,y,view,tab.get_cell(x,y),view.to_s(tab.get_cell(x,off)),view.to_s(tab.get_cell(off,y)),corner,cell,off)
|
257
296
|
return cell
|
258
297
|
end
|
259
298
|
|