daff 1.1.2 → 1.1.5

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.
@@ -0,0 +1,242 @@
1
+ [![Build Status](https://travis-ci.org/paulfitz/daff.svg?branch=master)](https://travis-ci.org/paulfitz/daff)
2
+ [![NPM version](https://badge.fury.io/js/daff.svg)](http://badge.fury.io/js/daff)
3
+ [![Gem Version](https://badge.fury.io/rb/daff.svg)](http://badge.fury.io/rb/daff)
4
+ [![PyPI version](https://badge.fury.io/py/daff.svg)](http://badge.fury.io/py/daff)
5
+
6
+ daff: data diff
7
+ ===============
8
+
9
+ This is a library for comparing tables, producing a summary of their
10
+ differences, and using such a summary as a patch file. It is
11
+ optimized for comparing tables that share a common origin, in other
12
+ words multiple versions of the "same" table.
13
+
14
+ For a live demo, see:
15
+ > http://paulfitz.github.com/daff/
16
+
17
+ Download the code for your preferred language here:
18
+ > https://github.com/paulfitz/daff/releases
19
+
20
+ For certain languages you can use the command-line:
21
+ ````sh
22
+ npm install daff # node/javascript
23
+ pip3 install daff # python3
24
+ gem install daff # ruby
25
+ ````
26
+
27
+ Or use the library to view csv diffs on github via a chrome extension:
28
+ > https://github.com/theodi/csvhub
29
+
30
+ The diff format used by `daff` is specified here:
31
+ > http://dataprotocols.org/tabular-diff-format/
32
+
33
+ This library is a stripped down version of the coopy toolbox (see
34
+ http://share.find.coop). To compare tables from different origins,
35
+ or with automatically generated IDs, or other complications, check out
36
+ the coopy toolbox.
37
+
38
+ The program
39
+ -----------
40
+
41
+ You can run `daff`/`daff.py`/`daff.rb` as a utility program:
42
+ ````
43
+ $ daff
44
+ daff can produce and apply tabular diffs.
45
+ Call as:
46
+ daff [--output OUTPUT.csv] a.csv b.csv
47
+ daff [--output OUTPUT.csv] parent.csv a.csv b.csv
48
+ daff [--output OUTPUT.jsonbook] a.jsonbook b.jsonbook
49
+ daff patch [--output OUTPUT.csv] source.csv patch.csv
50
+ daff trim [--output OUTPUT.csv] source.csv
51
+ daff render [--output OUTPUT.html] diff.csv
52
+
53
+ If you need more control, here is the full list of flags:
54
+ daff diff [--output OUTPUT.csv] [--context NUM] [--all] [--act ACT] a.csv b.csv
55
+ --context NUM: show NUM rows of context
56
+ --all: do not prune unchanged rows
57
+ --act ACT: show only a certain kind of change (update, insert, delete)
58
+
59
+ daff render [--output OUTPUT.html] [--css CSS.css] [--fragment] [--plain] diff.csv
60
+ --css CSS.css: generate a suitable css file to go with the html
61
+ --fragment: generate just a html fragment rather than a page
62
+ --plain: do not use fancy utf8 characters to make arrows prettier
63
+ ````
64
+
65
+ Using with git
66
+ --------------
67
+
68
+ Run `daff git csv` to see how to use daff to improve `git`'s handling
69
+ of csv files.
70
+
71
+ ````
72
+ $ daff git csv
73
+ You can use daff to improve git's handling of csv files, by using it as a
74
+ diff driver (for showing what has changed) and as a merge driver (for merging
75
+ changes between multiple versions). Here is how.
76
+
77
+ Create and add a file called .gitattributes in the root directory of your
78
+ repository, containing:
79
+
80
+ *.csv diff=daff-diff
81
+ *.csv merge=daff-merge
82
+
83
+ Create a file called .gitconfig in your home directory (or alternatively
84
+ open .git/config for a particular repository) and add:
85
+
86
+ [merge "daff-merge"]
87
+ name = daff tabular merge
88
+ driver = daff merge --output %A %O %A %B
89
+
90
+ [diff "daff-diff"]
91
+ command = daff diff --git
92
+
93
+ Make sure you can run daff from the command-line as just "daff" - if not,
94
+ replace "daff" in the driver and command lines above with the correct way
95
+ to call it.
96
+ ````
97
+
98
+ The library
99
+ -----------
100
+
101
+ You can use `daff` as a library from any supported language. We take
102
+ here the example of Javascript. To use `daff` on a webpage,
103
+ first include `daff.js`:
104
+ ```html
105
+ <script src="daff.js"></script>
106
+ ```
107
+ Or if using node outside the browser:
108
+ ```js
109
+ var daff = require('daff');
110
+ ```
111
+
112
+ For concreteness, assume we have two versions of a table,
113
+ `data1` and `data2`:
114
+ ```js
115
+ var data1 = [
116
+ ['Country','Capital'],
117
+ ['Ireland','Dublin'],
118
+ ['France','Paris'],
119
+ ['Spain','Barcelona']
120
+ ];
121
+ var data2 = [
122
+ ['Country','Code','Capital'],
123
+ ['Ireland','ie','Dublin'],
124
+ ['France','fr','Paris'],
125
+ ['Spain','es','Madrid'],
126
+ ['Germany','de','Berlin']
127
+ ];
128
+ ```
129
+
130
+ To make those tables accessible to the library, we wrap them
131
+ in `daff.TableView`:
132
+ ```js
133
+ var table1 = new daff.TableView(data1);
134
+ var table2 = new daff.TableView(data2);
135
+ ```
136
+
137
+ We can now compute the alignment between the rows and columns
138
+ in the two tables:
139
+ ```js
140
+ var alignment = daff.compareTables(table1,table2).align();
141
+ ```
142
+
143
+ To produce a diff from the alignment, we first need a table
144
+ for the output:
145
+ ```js
146
+ var data_diff = [];
147
+ var table_diff = new daff.TableView(data_diff);
148
+ ```
149
+
150
+ Using default options for the diff:
151
+ ```js
152
+ var flags = new daff.CompareFlags();
153
+ var highlighter = new daff.TableDiff(alignment,flags);
154
+ highlighter.hilite(table_diff);
155
+ ```
156
+
157
+ The diff is now in `data_diff` in highlighter format, see
158
+ specification here:
159
+ > http://share.find.coop/doc/spec_hilite.html
160
+
161
+ ```js
162
+ [ [ '!', '', '+++', '' ],
163
+ [ '@@', 'Country', 'Code', 'Capital' ],
164
+ [ '+', 'Ireland', 'ie', 'Dublin' ],
165
+ [ '+', 'France', 'fr', 'Paris' ],
166
+ [ '->', 'Spain', 'es', 'Barcelona->Madrid' ],
167
+ [ '+++', 'Germany', 'de', 'Berlin' ] ]
168
+ ```
169
+
170
+ For visualization, you may want to convert this to a HTML table
171
+ with appropriate classes on cells so you can color-code inserts,
172
+ deletes, updates, etc. You can do this with:
173
+ ```js
174
+ var diff2html = new daff.DiffRender();
175
+ diff2html.render(table_diff);
176
+ var table_diff_html = diff2html.html();
177
+ ```
178
+
179
+ For 3-way differences (that is, comparing two tables given knowledge
180
+ of a common ancestor) use `daff.compareTables3` (give ancestor
181
+ table as the first argument).
182
+
183
+ Here is how to apply that difference as a patch:
184
+ ```js
185
+ var patcher = new daff.HighlightPatch(table1,table_diff);
186
+ patcher.apply();
187
+ // table1 should now equal table2
188
+ ```
189
+
190
+ For other languages, you should find sample code in
191
+ the packages on the [Releases](https://github.com/paulfitz/daff/releases) page.
192
+
193
+
194
+ Supported languages
195
+ -------------------
196
+
197
+ The `daff` library is written in [Haxe](http://haxe.org/), which
198
+ can be translated reasonably well into at least the following languages:
199
+
200
+ * Javascript
201
+ * PHP
202
+ * Python
203
+ * Java
204
+ * C#
205
+ * C++
206
+ * (via a hack, just for `daff`) Ruby
207
+
208
+ Some translations are done for you on the
209
+ [Releases](https://github.com/paulfitz/daff/releases) page.
210
+ To make another translation,
211
+ follow the
212
+ [Haxe getting started tutorial](http://haxe.org/doc/start) for the
213
+ language you care about, then do one of:
214
+
215
+ ```
216
+ make js
217
+ make php
218
+ make py
219
+ make java
220
+ make cs
221
+ make cpp
222
+ ```
223
+
224
+ [@Floppy](https://github.com/Floppy) has made a lovingly-hand-written [native Ruby port](https://github.com/theodi/coopy-ruby) that covers core functionality. I've made a brutally-machine-converted port that is a full translation but less idiomatic.
225
+
226
+ For each language, the `daff` library expects to be handed an interface to tables you create, rather than creating them
227
+ itself. This is to avoid inefficient copies from one format to another. You'll find a `SimpleTable` class you can use if
228
+ you find this awkward.
229
+
230
+ Reading material
231
+ ----------------
232
+
233
+ * http://dataprotocols.org/tabular-diff-format/ : a specification of the diff format we use.
234
+ * http://theodi.org/blog/csvhub-github-diffs-for-csv-files : using this library with github.
235
+ * http://theodi.org/blog/adapting-git-simple-data : using this library with gitlab.
236
+ * http://okfnlabs.org/blog/2013/08/08/diffing-and-patching-data.html : a summary of where the library came from.
237
+ * http://blog.okfn.org/2013/07/02/git-and-github-for-data/ : a post about storing small data in git/github.
238
+ * http://blog.ouseful.info/2013/08/27/diff-or-chop-github-csv-data-files-and-openrefine/ : counterpoint - a post discussing tracked-changes rather than diffs.
239
+
240
+ ## License
241
+
242
+ daff is distributed under the MIT License.
@@ -36,6 +36,7 @@ require_relative 'lib/coopy/highlight_patch_unit'
36
36
  require_relative 'lib/coopy/index'
37
37
  require_relative 'lib/coopy/index_item'
38
38
  require_relative 'lib/coopy/index_pair'
39
+ require_relative 'lib/coopy/merger'
39
40
  require_relative 'lib/coopy/mover'
40
41
  require_relative 'lib/coopy/ordering'
41
42
  require_relative 'lib/coopy/report'
@@ -223,6 +223,8 @@ module Coopy
223
223
  css_output = nil
224
224
  fragment = false
225
225
  pretty = true
226
+ inplace = false
227
+ git = false
226
228
  flags = ::Coopy::CompareFlags.new
227
229
  flags.always_show_header = true
228
230
  while(more)
@@ -275,6 +277,16 @@ module Coopy
275
277
  flags.unchanged_context = context if context >= 0
276
278
  args.slice!(i,2)
277
279
  break
280
+ elsif tag == "--inplace"
281
+ more = true
282
+ inplace = true
283
+ args.slice!(i,1)
284
+ break
285
+ elsif tag == "--git"
286
+ more = true
287
+ git = true
288
+ args.slice!(i,1)
289
+ break
278
290
  end
279
291
  end
280
292
  end
@@ -286,9 +298,13 @@ module Coopy
286
298
  io.write_stderr(" daff [--output OUTPUT.csv] a.csv b.csv\n")
287
299
  io.write_stderr(" daff [--output OUTPUT.csv] parent.csv a.csv b.csv\n")
288
300
  io.write_stderr(" daff [--output OUTPUT.jsonbook] a.jsonbook b.jsonbook\n")
289
- io.write_stderr(" daff patch [--output OUTPUT.csv] source.csv patch.csv\n")
301
+ io.write_stderr(" daff patch [--inplace] [--output OUTPUT.csv] a.csv patch.csv\n")
302
+ io.write_stderr(" daff merge [--inplace] [--output OUTPUT.csv] parent.csv a.csv b.csv\n")
290
303
  io.write_stderr(" daff trim [--output OUTPUT.csv] source.csv\n")
291
304
  io.write_stderr(" daff render [--output OUTPUT.html] diff.csv\n")
305
+ io.write_stderr(" daff git csv\n")
306
+ io.write_stderr("\n")
307
+ io.write_stderr("The --inplace option to patch and merge will result in modification of a.csv.\n")
292
308
  io.write_stderr("\n")
293
309
  io.write_stderr("If you need more control, here is the full list of flags:\n")
294
310
  io.write_stderr(" daff diff [--output OUTPUT.csv] [--context NUM] [--all] [--act ACT] a.csv b.csv\n")
@@ -296,21 +312,65 @@ module Coopy
296
312
  io.write_stderr(" --all: do not prune unchanged rows\n")
297
313
  io.write_stderr(" --act ACT: show only a certain kind of change (update, insert, delete)\n")
298
314
  io.write_stderr("\n")
315
+ io.write_stderr(" daff diff --git path old-file old-hex old-mode new-file new-hex new-mode\n")
316
+ io.write_stderr(" --git: process arguments provided by git to diff drivers\n")
317
+ io.write_stderr("\n")
299
318
  io.write_stderr(" daff render [--output OUTPUT.html] [--css CSS.css] [--fragment] [--plain] diff.csv\n")
300
319
  io.write_stderr(" --css CSS.css: generate a suitable css file to go with the html\n")
301
320
  io.write_stderr(" --fragment: generate just a html fragment rather than a page\n")
302
321
  io.write_stderr(" --plain: do not use fancy utf8 characters to make arrows prettier\n")
303
322
  return 1
304
323
  end
305
- output = "-" if output == nil
306
324
  cmd1 = args[0]
307
325
  offset = 1
308
- if !Lambda.has(["diff","patch","trim","render"],cmd1)
326
+ if !Lambda.has(["diff","patch","merge","trim","render","git"],cmd1)
309
327
  if (cmd1.index(".",nil || 0) || -1) != -1 || (cmd1.index("--",nil || 0) || -1) == 0
310
328
  cmd1 = "diff"
311
329
  offset = 0
312
330
  end
313
331
  end
332
+ if cmd1 == "git"
333
+ types = args.slice!(offset,args.length - offset)
334
+ io.write_stdout("You can use daff to improve git's handling of csv files, by using it as a\ndiff driver (for showing what has changed) and as a merge driver (for merging\nchanges between multiple versions). Here is how.\n")
335
+ io.write_stdout("\n")
336
+ io.write_stdout("Create and add a file called .gitattributes in the root directory of your\nrepository, containing:\n\n")
337
+ begin
338
+ _g2 = 0
339
+ while(_g2 < types.length)
340
+ t = types[_g2]
341
+ _g2+=1
342
+ io.write_stdout(" *." + _hx_str(t) + " diff=daff-diff\n")
343
+ io.write_stdout(" *." + _hx_str(t) + " merge=daff-merge\n")
344
+ end
345
+ end
346
+ io.write_stdout("\nCreate a file called .gitconfig in your home directory (or alternatively\nopen .git/config for a particular repository) and add:\n\n")
347
+ io.write_stdout(" [merge \"daff-merge\"]\n")
348
+ io.write_stdout(" name = daff tabular merge\n")
349
+ io.write_stdout(" driver = daff merge --output %A %O %A %B\n\n")
350
+ io.write_stdout(" [diff \"daff-diff\"]\n")
351
+ io.write_stdout(" command = daff diff --git\n")
352
+ io.write_stderr("\n")
353
+ io.write_stderr("Make sure you can run daff from the command-line as just \"daff\" - if not,\nreplace \"daff\" in the driver and command lines above with the correct way\nto call it.")
354
+ io.write_stderr("\n")
355
+ return 0
356
+ end
357
+ if git
358
+ ct = args.length - offset
359
+ if ct != 7
360
+ io.write_stderr("Expected 7 parameters from git, but got " + _hx_str(ct) + "\n")
361
+ return 1
362
+ end
363
+ git_args = args.slice!(offset,ct)
364
+ args.slice!(0,args.length)
365
+ offset = 0
366
+ path = git_args[0]
367
+ old_file = git_args[1]
368
+ new_file = git_args[4]
369
+ io.write_stdout("--- a/" + _hx_str(path) + "\n")
370
+ io.write_stdout("+++ b/" + _hx_str(path) + "\n")
371
+ args.push(old_file)
372
+ args.push(new_file)
373
+ end
314
374
  tool = ::Coopy::Coopy.new
315
375
  tool.io = io
316
376
  parent = nil
@@ -318,12 +378,20 @@ module Coopy
318
378
  parent = tool.load_table(args[offset])
319
379
  offset+=1
320
380
  end
321
- a = tool.load_table(args[offset])
381
+ aname = args[offset]
382
+ a = tool.load_table(aname)
322
383
  b = nil
323
384
  b = tool.load_table(args[1 + offset]) if args.length - offset >= 2
385
+ if inplace
386
+ io.write_stderr("Please do not use --inplace when specifying an output.\n") if output != nil
387
+ output = aname
388
+ return 1
389
+ end
390
+ output = "-" if output == nil
391
+ ok = true
324
392
  if cmd1 == "diff"
325
- ct = ::Coopy::Coopy.compare_tables3(parent,a,b)
326
- align = ct.align
393
+ ct1 = ::Coopy::Coopy.compare_tables3(parent,a,b)
394
+ align = ct1.align
327
395
  td = ::Coopy::TableDiff.new(align,flags)
328
396
  o = ::Coopy::SimpleTable.new(0,0)
329
397
  td.hilite(o)
@@ -332,6 +400,12 @@ module Coopy
332
400
  patcher = ::Coopy::HighlightPatch.new(a,b)
333
401
  patcher.apply
334
402
  tool.save_table(output,a)
403
+ elsif cmd1 == "merge"
404
+ merger = ::Coopy::Merger.new(parent,a,b,flags)
405
+ conflicts = merger.apply
406
+ ok = conflicts == 0
407
+ io.write_stderr(_hx_str(conflicts) + " conflict" + _hx_str((((conflicts > 1) ? "s" : ""))) + "\n") if conflicts > 0
408
+ tool.save_table(output,a)
335
409
  elsif cmd1 == "trim"
336
410
  tool.save_table(output,a)
337
411
  elsif cmd1 == "render"
@@ -342,7 +416,11 @@ module Coopy
342
416
  tool.save_text(output,renderer.html)
343
417
  tool.save_text(css_output,renderer.sample_css) if css_output != nil
344
418
  end
345
- return 0
419
+ if ok
420
+ return 0
421
+ else
422
+ return 1
423
+ end
346
424
  end
347
425
 
348
426
  def Coopy.main
@@ -374,7 +452,7 @@ module Coopy
374
452
  txt += "\n"
375
453
  end
376
454
  end
377
- ::Haxe::Log._trace.call(txt,{ file_name: "Coopy.hx", line_number: 353, class_name: "coopy.Coopy", method_name: "show"})
455
+ ::Haxe::Log._trace.call(txt,{ file_name: "Coopy.hx", line_number: 432, class_name: "coopy.Coopy", method_name: "show"})
378
456
  end
379
457
 
380
458
  def Coopy.jsonify(t)
@@ -0,0 +1,183 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ module Coopy
5
+ class Merger
6
+
7
+ def initialize(parent,local,remote,flags)
8
+ @parent = parent
9
+ @local = local
10
+ @remote = remote
11
+ @flags = flags
12
+ end
13
+
14
+ # protected - in ruby this doesn't play well with static/inline methods
15
+
16
+ attr_accessor :parent
17
+ attr_accessor :local
18
+ attr_accessor :remote
19
+ attr_accessor :flags
20
+ attr_accessor :order
21
+ attr_accessor :units
22
+ attr_accessor :column_order
23
+ attr_accessor :column_units
24
+ attr_accessor :row_mix_local
25
+ attr_accessor :row_mix_remote
26
+ attr_accessor :column_mix_local
27
+ attr_accessor :column_mix_remote
28
+ attr_accessor :conflicts
29
+
30
+ public
31
+
32
+ def shuffle_dimension(dim_units,len,fate,cl,cr)
33
+ at = 0
34
+ begin
35
+ _g = 0
36
+ while(_g < dim_units.length)
37
+ cunit = dim_units[_g]
38
+ _g+=1
39
+ if cunit.p < 0
40
+ if cunit.l < 0
41
+ if cunit.r >= 0
42
+ begin
43
+ cr[cunit.r] = at
44
+ at
45
+ end
46
+ at+=1
47
+ end
48
+ else
49
+ begin
50
+ cl[cunit.l] = at
51
+ at
52
+ end
53
+ at+=1
54
+ end
55
+ elsif cunit.l >= 0
56
+ if cunit.r < 0
57
+ else
58
+ begin
59
+ cl[cunit.l] = at
60
+ at
61
+ end
62
+ at+=1
63
+ end
64
+ end
65
+ end
66
+ end
67
+ begin
68
+ _g1 = 0
69
+ while(_g1 < len)
70
+ x = _g1
71
+ _g1+=1
72
+ idx = cl[x]
73
+ if idx == nil
74
+ fate.push(-1)
75
+ else
76
+ fate.push(idx)
77
+ end
78
+ end
79
+ end
80
+ return at
81
+ end
82
+
83
+ def shuffle_columns
84
+ @column_mix_local = {}
85
+ @column_mix_remote = {}
86
+ fate = Array.new
87
+ wfate = self.shuffle_dimension(@column_units,@local.get_width,fate,@column_mix_local,@column_mix_remote)
88
+ @local.insert_or_delete_columns(fate,wfate)
89
+ end
90
+
91
+ def shuffle_rows
92
+ @row_mix_local = {}
93
+ @row_mix_remote = {}
94
+ fate = Array.new
95
+ hfate = self.shuffle_dimension(@units,@local.get_height,fate,@row_mix_local,@row_mix_remote)
96
+ @local.insert_or_delete_rows(fate,hfate)
97
+ end
98
+
99
+ def apply
100
+ @conflicts = 0
101
+ ct = ::Coopy::Coopy.compare_tables3(@parent,@local,@remote)
102
+ align = ct.align
103
+ @order = align.to_order_pruned(true)
104
+ @units = @order.get_list
105
+ @column_order = align.meta.to_order_pruned(false)
106
+ @column_units = @column_order.get_list
107
+ allow_insert = @flags.allow_insert
108
+ allow_delete = @flags.allow_delete
109
+ allow_update = @flags.allow_update
110
+ view = @parent.get_cell_view
111
+ begin
112
+ _g = 0
113
+ _g1 = @units
114
+ while(_g < _g1.length)
115
+ row = _g1[_g]
116
+ _g+=1
117
+ if row.l >= 0 && row.r >= 0 && row.p >= 0
118
+ _g2 = 0
119
+ _g3 = @column_units
120
+ while(_g2 < _g3.length)
121
+ col = _g3[_g2]
122
+ _g2+=1
123
+ if col.l >= 0 && col.r >= 0 && col.p >= 0
124
+ pcell = @parent.get_cell(col.p,row.p)
125
+ rcell = @remote.get_cell(col.r,row.r)
126
+ if !view.equals(pcell,rcell)
127
+ lcell = @local.get_cell(col.l,row.l)
128
+ if view.equals(pcell,lcell)
129
+ @local.set_cell(col.l,row.l,rcell)
130
+ else
131
+ @local.set_cell(col.l,row.l,::Coopy::Merger.make_conflicted_cell(view,pcell,lcell,rcell))
132
+ @conflicts+=1
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+ self.shuffle_columns
141
+ self.shuffle_rows
142
+ _it = ::Rb::RubyIterator.new(@column_mix_remote.keys)
143
+ while(_it.has_next) do
144
+ x = _it._next
145
+ x2 = @column_mix_remote[x]
146
+ begin
147
+ _g4 = 0
148
+ _g11 = @units
149
+ while(_g4 < _g11.length)
150
+ unit = _g11[_g4]
151
+ _g4+=1
152
+ if unit.l >= 0 && unit.r >= 0
153
+ @local.set_cell(x2,@row_mix_local[unit.l],@remote.get_cell(x,unit.r))
154
+ elsif unit.p < 0 && unit.r >= 0
155
+ @local.set_cell(x2,@row_mix_remote[unit.r],@remote.get_cell(x,unit.r))
156
+ end
157
+ end
158
+ end
159
+ end
160
+ _it2 = ::Rb::RubyIterator.new(@row_mix_remote.keys)
161
+ while(_it2.has_next) do
162
+ y = _it2._next
163
+ y2 = @row_mix_remote[y]
164
+ begin
165
+ _g5 = 0
166
+ _g12 = @column_units
167
+ while(_g5 < _g12.length)
168
+ unit1 = _g12[_g5]
169
+ _g5+=1
170
+ @local.set_cell(@column_mix_local[unit1.l],y2,@remote.get_cell(unit1.r,y)) if unit1.l >= 0 && unit1.r >= 0
171
+ end
172
+ end
173
+ end
174
+ return @conflicts
175
+ end
176
+
177
+ def Merger.make_conflicted_cell(view,pcell,lcell,rcell)
178
+ return view.to_datum("((( " + _hx_str(view.to_s(pcell)) + " ))) " + _hx_str(view.to_s(lcell)) + " /// " + _hx_str(view.to_s(rcell)))
179
+ end
180
+
181
+ end
182
+
183
+ end
@@ -12,6 +12,8 @@ module Coopy
12
12
  def insertOrDeleteRows(fate,hfate) puts "Abstract Table.insertOrDeleteRows called" end
13
13
  def insertOrDeleteColumns(fate,wfate) puts "Abstract Table.insertOrDeleteColumns called" end
14
14
  def trimBlank() puts "Abstract Table.trimBlank called" end
15
+ def get_width() puts "Abstract Table.get_width called" end
16
+ def get_height() puts "Abstract Table.get_height called" end
15
17
  end
16
18
 
17
19
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: daff
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-06-10 00:00:00.000000000 Z
13
+ date: 2014-07-10 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description: Diff and patch tables
16
16
  email:
@@ -61,6 +61,7 @@ files:
61
61
  - lib/lib/coopy/table_comparison_state.rb
62
62
  - lib/lib/coopy/csv.rb
63
63
  - lib/lib/coopy/ordering.rb
64
+ - lib/lib/coopy/merger.rb
64
65
  - lib/lib/coopy/change.rb
65
66
  - lib/lib/coopy/sparse_sheet.rb
66
67
  - lib/lib/coopy/report.rb
@@ -82,6 +83,7 @@ files:
82
83
  - lib/lib/haxe/format/json_printer.rb
83
84
  - lib/lib/sys.rb
84
85
  - bin/daff.rb
86
+ - README.md
85
87
  homepage: https://github.com/paulfitz/daff
86
88
  licenses:
87
89
  - MIT
@@ -106,44 +108,59 @@ rubyforge_project:
106
108
  rubygems_version: 1.8.23
107
109
  signing_key:
108
110
  specification_version: 3
109
- summary: ! 'daff: data diff =============== This is a library for comparing tables,
110
- producing a summary of their differences, and using such a summary as a patch file. It
111
- is optimized for comparing tables that share a common origin, in other words multiple
112
- versions of the "same" table. For a live demo, see: > http://paulfitz.github.com/daff/ Get
113
- the core library for your preferred language here: > https://github.com/paulfitz/daff/releases Or
114
- with node: ````sh npm install daff ```` Or with pip: ````sh pip3 install daff #
115
- currently needs python3 ```` Or use the library to view csv diffs on github via
116
- a chrome extension: > https://github.com/theodi/csvhub The diff format used by
117
- `daff` is specified here: > http://dataprotocols.org/tabular-diff-format/ This
111
+ summary: ! '[![Build Status](https://travis-ci.org/paulfitz/daff.svg?branch=master)](https://travis-ci.org/paulfitz/daff)
112
+ [![NPM version](https://badge.fury.io/js/daff.svg)](http://badge.fury.io/js/daff)
113
+ [![Gem Version](https://badge.fury.io/rb/daff.svg)](http://badge.fury.io/rb/daff)
114
+ [![PyPI version](https://badge.fury.io/py/daff.svg)](http://badge.fury.io/py/daff) daff:
115
+ data diff =============== This is a library for comparing tables, producing a summary
116
+ of their differences, and using such a summary as a patch file. It is optimized
117
+ for comparing tables that share a common origin, in other words multiple versions
118
+ of the "same" table. For a live demo, see: > http://paulfitz.github.com/daff/ Download
119
+ the code for your preferred language here: > https://github.com/paulfitz/daff/releases For
120
+ certain languages you can use the command-line: ````sh npm install daff # node/javascript
121
+ pip3 install daff # python3 gem install daff # ruby ```` Or use the library
122
+ to view csv diffs on github via a chrome extension: > https://github.com/theodi/csvhub The
123
+ diff format used by `daff` is specified here: > http://dataprotocols.org/tabular-diff-format/ This
118
124
  library is a stripped down version of the coopy toolbox (see http://share.find.coop). To
119
125
  compare tables from different origins, or with automatically generated IDs, or
120
- other complications, check out the coopy toolbox. The program ----------- There
121
- is a commandline utility wrapping the core functions of the library: ```` $ daff
122
- daff can produce and apply tabular diffs. Call as: daff [--output OUTPUT.csv] a.csv
123
- b.csv daff [--output OUTPUT.csv] parent.csv a.csv b.csv daff [--output OUTPUT.jsonbook]
124
- a.jsonbook b.jsonbook daff patch [--output OUTPUT.csv] source.csv patch.csv daff
125
- trim [--output OUTPUT.csv] source.csv daff render [--output OUTPUT.html] diff.csv If
126
- you need more control, here is the full list of flags: daff diff [--output OUTPUT.csv]
127
- [--context NUM] [--all] [--act ACT] a.csv b.csv --context NUM: show NUM rows of
128
- context --all: do not prune unchanged rows --act ACT: show only a certain
129
- kind of change (update, insert, delete) daff render [--output OUTPUT.html] [--css
130
- CSS.css] [--fragment] [--plain] diff.csv --css CSS.css: generate a suitable css
131
- file to go with the html --fragment: generate just a html fragment rather than
132
- a page --plain: do not use fancy utf8 characters to make arrows prettier ```` The
133
- library ----------- To use this library from Javascript, first include `daff.js`
134
- on a webpage: ```html <script src="daff.js"></script> ``` Or with nodejs: ```js
135
- var daff = require(''daff''); ``` For concreteness, assume we have two versions
136
- of a table, `data1` and `data2`: ```js var data1 = [ [''Country'',''Capital''],
137
- [''Ireland'',''Dublin''], [''France'',''Paris''], [''Spain'',''Barcelona''] ]; var
138
- data2 = [ [''Country'',''Code'',''Capital''], [''Ireland'',''ie'',''Dublin''], [''France'',''fr'',''Paris''],
139
- [''Spain'',''es'',''Madrid''], [''Germany'',''de'',''Berlin''] ]; ``` To make those
140
- tables accessible to the library, we wrap them in `daff.TableView`: ```js var table1
141
- = new daff.TableView(data1); var table2 = new daff.TableView(data2); ``` We can
142
- now compute the alignment between the rows and columns in the two tables: ```js
143
- var alignment = daff.compareTables(table1,table2).align(); ``` To produce a diff
144
- from the alignment, we first need a table for the output: ```js var data_diff =
145
- []; var table_diff = new daff.TableView(data_diff); ``` Using default options for
146
- the diff: ```js var flags = new daff.CompareFlags(); var highlighter = new daff.TableDiff(alignment,flags);
126
+ other complications, check out the coopy toolbox. The program ----------- You
127
+ can run `daff`/`daff.py`/`daff.rb` as a utility program: ```` $ daff daff can produce
128
+ and apply tabular diffs. Call as: daff [--output OUTPUT.csv] a.csv b.csv daff [--output
129
+ OUTPUT.csv] parent.csv a.csv b.csv daff [--output OUTPUT.jsonbook] a.jsonbook b.jsonbook
130
+ daff patch [--output OUTPUT.csv] source.csv patch.csv daff trim [--output OUTPUT.csv]
131
+ source.csv daff render [--output OUTPUT.html] diff.csv If you need more control,
132
+ here is the full list of flags: daff diff [--output OUTPUT.csv] [--context NUM]
133
+ [--all] [--act ACT] a.csv b.csv --context NUM: show NUM rows of context --all: do
134
+ not prune unchanged rows --act ACT: show only a certain kind of change (update,
135
+ insert, delete) daff render [--output OUTPUT.html] [--css CSS.css] [--fragment]
136
+ [--plain] diff.csv --css CSS.css: generate a suitable css file to go with the html
137
+ --fragment: generate just a html fragment rather than a page --plain: do
138
+ not use fancy utf8 characters to make arrows prettier ```` Using with git -------------- Run
139
+ `daff git csv` to see how to use daff to improve `git`''s handling of csv files. ````
140
+ $ daff git csv You can use daff to improve git''s handling of csv files, by using
141
+ it as a diff driver (for showing what has changed) and as a merge driver (for merging
142
+ changes between multiple versions). Here is how. Create and add a file called
143
+ .gitattributes in the root directory of your repository, containing: *.csv diff=daff-diff
144
+ *.csv merge=daff-merge Create a file called .gitconfig in your home directory (or
145
+ alternatively open .git/config for a particular repository) and add: [merge "daff-merge"]
146
+ name = daff tabular merge driver = daff merge --output %A %O %A %B [diff "daff-diff"]
147
+ command = daff diff --git Make sure you can run daff from the command-line as just
148
+ "daff" - if not, replace "daff" in the driver and command lines above with the correct
149
+ way to call it. ```` The library ----------- You can use `daff` as a library from
150
+ any supported language. We take here the example of Javascript. To use `daff`
151
+ on a webpage, first include `daff.js`: ```html <script src="daff.js"></script> ```
152
+ Or if using node outside the browser: ```js var daff = require(''daff''); ``` For
153
+ concreteness, assume we have two versions of a table, `data1` and `data2`: ```js
154
+ var data1 = [ [''Country'',''Capital''], [''Ireland'',''Dublin''], [''France'',''Paris''],
155
+ [''Spain'',''Barcelona''] ]; var data2 = [ [''Country'',''Code'',''Capital''], [''Ireland'',''ie'',''Dublin''],
156
+ [''France'',''fr'',''Paris''], [''Spain'',''es'',''Madrid''], [''Germany'',''de'',''Berlin'']
157
+ ]; ``` To make those tables accessible to the library, we wrap them in `daff.TableView`:
158
+ ```js var table1 = new daff.TableView(data1); var table2 = new daff.TableView(data2);
159
+ ``` We can now compute the alignment between the rows and columns in the two tables:
160
+ ```js var alignment = daff.compareTables(table1,table2).align(); ``` To produce
161
+ a diff from the alignment, we first need a table for the output: ```js var data_diff
162
+ = []; var table_diff = new daff.TableView(data_diff); ``` Using default options
163
+ for the diff: ```js var flags = new daff.CompareFlags(); var highlighter = new daff.TableDiff(alignment,flags);
147
164
  highlighter.hilite(table_diff); ``` The diff is now in `data_diff` in highlighter
148
165
  format, see specification here: > http://share.find.coop/doc/spec_hilite.html ```js
149
166
  [ [ ''!'', '''', ''+++'', '''' ], [ ''@@'', ''Country'', ''Code'', ''Capital'' ],
@@ -156,22 +173,22 @@ summary: ! 'daff: data diff =============== This is a library for comparing tab
156
173
  differences (that is, comparing two tables given knowledge of a common ancestor)
157
174
  use `daff.compareTables3` (give ancestor table as the first argument). Here is
158
175
  how to apply that difference as a patch: ```js var patcher = new daff.HighlightPatch(table1,table_diff);
159
- patcher.apply(); // table1 should now equal table2 ``` Other languages --------------- The
160
- `daff` library is written in [Haxe](http://haxe.org/), which can be translated reasonably
161
- well into at least the following languages: * Javascript * PHP * Python * Java
162
- * C# * C++ The Javascript translation is available via npm. PHP and C++ translations
163
- are posted on the [Releases](https://github.com/paulfitz/daff/releases) page. To
164
- make another translation, follow the [Haxe getting started tutorial](http://haxe.org/doc/start)
176
+ patcher.apply(); // table1 should now equal table2 ``` For other languages, you
177
+ should find sample code in the packages on the [Releases](https://github.com/paulfitz/daff/releases)
178
+ page. Supported languages ------------------- The `daff` library is written in
179
+ [Haxe](http://haxe.org/), which can be translated reasonably well into at least
180
+ the following languages: * Javascript * PHP * Python * Java * C# * C++ * (via a
181
+ hack, just for `daff`) Ruby Some translations are done for you on the [Releases](https://github.com/paulfitz/daff/releases)
182
+ page. To make another translation, follow the [Haxe getting started tutorial](http://haxe.org/doc/start)
165
183
  for the language you care about, then do one of: ``` make js make php make py make
166
184
  java make cs make cpp ``` [@Floppy](https://github.com/Floppy) has made a lovingly-hand-written
167
185
  [native Ruby port](https://github.com/theodi/coopy-ruby) that covers core functionality. I''ve
168
- made a brutally-machine-converted [Ruby port](https://github.com/paulfitz/coopy-ruby)
169
- that is a full translation but may include utter gibberish. For each language,
170
- the `daff` library expects to be handed an interface to tables you create, rather
171
- than creating them itself. This is to avoid inefficient copies from one format
172
- to another. You''ll find a `SimpleTable` class you can use if you find this awkward. Reading
173
- material ---------------- * http://dataprotocols.org/tabular-diff-format/ : a specification
174
- of the diff format we use. * http://theodi.org/blog/csvhub-github-diffs-for-csv-files
186
+ made a brutally-machine-converted port that is a full translation but less idiomatic. For
187
+ each language, the `daff` library expects to be handed an interface to tables you
188
+ create, rather than creating them itself. This is to avoid inefficient copies from
189
+ one format to another. You''ll find a `SimpleTable` class you can use if you find
190
+ this awkward. Reading material ---------------- * http://dataprotocols.org/tabular-diff-format/
191
+ : a specification of the diff format we use. * http://theodi.org/blog/csvhub-github-diffs-for-csv-files
175
192
  : using this library with github. * http://theodi.org/blog/adapting-git-simple-data
176
193
  : using this library with gitlab. * http://okfnlabs.org/blog/2013/08/08/diffing-and-patching-data.html
177
194
  : a summary of where the library came from. * http://blog.okfn.org/2013/07/02/git-and-github-for-data/