class Coopy::Coopy

Attributes

version[RW]
cache_txt[RW]
css_output[RW]
csv_eol_preference[RW]
daff_cmd[RW]
delim_preference[RW]
extern_preference[RW]
flags[RW]
format_preference[RW]

protected - in ruby this doesn't play well with static/inline methods

fragment[RW]
io[RW]
mv[RW]
nested_output[RW]
order_preference[RW]
order_set[RW]
output_format[RW]
output_format_set[RW]
status[RW]

protected - in ruby this doesn't play well with static/inline methods

strategy[RW]

Public Class Methods

align(local,remote,flags,comp) click to toggle source
# File lib/lib/coopy/coopy.rb, line 927
def Coopy.align(local,remote,flags,comp)
  comp.a = ::Coopy::Coopy.tablify(local)
  comp.b = ::Coopy::Coopy.tablify(remote)
  flags = ::Coopy::CompareFlags.new if flags == nil
  comp.compare_flags = flags
  ct = ::Coopy::CompareTable.new(comp)
  align = ct.align
  td = ::Coopy::TableDiff.new(align,flags)
  td
end
cell_for(x) click to toggle source
# File lib/lib/coopy/coopy.rb, line 983
def Coopy.cell_for(x)
  x
end
compare_tables(local,remote,flags = nil) click to toggle source
# File lib/lib/coopy/coopy.rb, line 945
def Coopy.compare_tables(local,remote,flags = nil)
  comp = ::Coopy::TableComparisonState.new
  comp.a = ::Coopy::Coopy.tablify(local)
  comp.b = ::Coopy::Coopy.tablify(remote)
  comp.compare_flags = flags
  ct = ::Coopy::CompareTable.new(comp)
  ct
end
compare_tables3(parent,local,remote,flags = nil) click to toggle source
# File lib/lib/coopy/coopy.rb, line 954
def Coopy.compare_tables3(parent,local,remote,flags = nil)
  comp = ::Coopy::TableComparisonState.new
  comp.p = ::Coopy::Coopy.tablify(parent)
  comp.a = ::Coopy::Coopy.tablify(local)
  comp.b = ::Coopy::Coopy.tablify(remote)
  comp.compare_flags = flags
  ct = ::Coopy::CompareTable.new(comp)
  ct
end
diff(local,remote,flags = nil) click to toggle source
# File lib/lib/coopy/coopy.rb, line 906
def Coopy.diff(local,remote,flags = nil)
  comp = ::Coopy::TableComparisonState.new
  td = ::Coopy::Coopy.align(local,remote,flags,comp)
  o = ::Coopy::Coopy.get_blank_table(td,comp)
  o = comp.a.create if comp.a != nil
  o = comp.b.create if o == nil && comp.b != nil
  o = ::Coopy::SimpleTable.new(0,0) if o == nil
  td.hilite(o)
  o
end
diff_as_ansi(local,remote,flags = nil) click to toggle source
# File lib/lib/coopy/coopy.rb, line 897
def Coopy.diff_as_ansi(local,remote,flags = nil)
  tool = ::Coopy::Coopy.new(::Coopy::TableIO.new)
  tool.cache_txt = ""
  flags = ::Coopy::CompareFlags.new if flags == nil
  tool.output_format = "csv"
  tool.run_diff(flags.parent,local,remote,flags,nil)
  tool.cache_txt
end
diff_as_html(local,remote,flags = nil) click to toggle source
# File lib/lib/coopy/coopy.rb, line 884
def Coopy.diff_as_html(local,remote,flags = nil)
  comp = ::Coopy::TableComparisonState.new
  td = ::Coopy::Coopy.align(local,remote,flags,comp)
  o = ::Coopy::Coopy.get_blank_table(td,comp)
  o = comp.a.create if comp.a != nil
  o = comp.b.create if o == nil && comp.b != nil
  o = ::Coopy::SimpleTable.new(0,0) if o == nil
  os = ::Coopy::Tables.new(o)
  td.hilite_with_nesting(os)
  render = ::Coopy::DiffRender.new
  render.render_tables(os).html
end
get_blank_table(td,comp) click to toggle source

protected - in ruby this doesn't play well with static/inline methods

# File lib/lib/coopy/coopy.rb, line 919
def Coopy.get_blank_table(td,comp)
  o = nil
  o = comp.a.create if comp.a != nil
  o = comp.b.create if o == nil && comp.b != nil
  o = ::Coopy::SimpleTable.new(0,0) if o == nil
  o
end
jsonify(t) click to toggle source
# File lib/lib/coopy/coopy.rb, line 1026
def Coopy.jsonify(t)
  workbook = {}
  sheet = Array.new
  w = t.get_width
  h = t.get_height
  txt = ""
  begin
    _g = 0
    while(_g < h) 
      y = _g
      _g+=1
      row = Array.new
      begin
        _g1 = 0
        while(_g1 < w) 
          x = _g1
          _g1+=1
          v = t.get_cell(x,y)
          row.push(v)
        end
      end
      sheet.push(row)
    end
  end
  workbook["sheet"] = sheet
  workbook
end
keep_around() click to toggle source

protected - in ruby this doesn't play well with static/inline methods

# File lib/lib/coopy/coopy.rb, line 966
def Coopy.keep_around 
  st = ::Coopy::SimpleTable.new(1,1)
  v = ::Coopy::Viterbi.new
  td = ::Coopy::TableDiff.new(nil,nil)
  cf = ::Coopy::CompareFlags.new
  idx = ::Coopy::Index.new(cf)
  dr = ::Coopy::DiffRender.new
  hp = ::Coopy::HighlightPatch.new(nil,nil)
  csv = ::Coopy::Csv.new
  tm = ::Coopy::TableModifier.new(nil)
  sc = ::Coopy::SqlCompare.new(nil,nil,nil,nil)
  sq = ::Coopy::SqliteHelper.new
  sm = ::Coopy::SimpleMeta.new(nil)
  ct = ::Coopy::CombinedTable.new(nil)
  0
end
main() click to toggle source
# File lib/lib/coopy/coopy.rb, line 989
def Coopy.main 
  io = ::Coopy::TableIO.new
  coopy1 = ::Coopy::Coopy.new
  ret = coopy1.coopyhx(io)
  HxSys.exit(ret) if ret != 0
  ret
end
new(io = nil) click to toggle source
# File lib/lib/coopy/coopy.rb, line 7
def initialize(io = nil)
  self.init
  @io = io
end
patch(local,patch,flags = nil) click to toggle source
# File lib/lib/coopy/coopy.rb, line 940
def Coopy.patch(local,patch,flags = nil)
  patcher = ::Coopy::HighlightPatch.new(::Coopy::Coopy.tablify(local),::Coopy::Coopy.tablify(patch))
  patcher.apply
end
show(t) click to toggle source

protected - in ruby this doesn't play well with static/inline methods

# File lib/lib/coopy/coopy.rb, line 999
def Coopy.show(t)
  w = t.get_width
  h = t.get_height
  txt = ""
  begin
    _g = 0
    while(_g < h) 
      y = _g
      _g+=1
      begin
        _g1 = 0
        while(_g1 < w) 
          x = _g1
          _g1+=1
          begin
            s = t.get_cell(x,y)
            txt += s.to_s
          end
          txt += " "
        end
      end
      txt += "\n"
    end
  end
  puts txt
end
tablify(data) click to toggle source
# File lib/lib/coopy/coopy.rb, line 1056
def Coopy.tablify(data)
  return data if data == nil
  return data if data.respond_to? :get_cell_view
  ::Coopy::TableView.new(data)
end

Public Instance Methods

apply_renderer(name,renderer) click to toggle source
# File lib/lib/coopy/coopy.rb, line 106
def apply_renderer(name,renderer)
  renderer.complete_html if !@fragment
  if @format_preference == "www" 
    @io.send_to_browser(renderer.html)
  else 
    self.save_text(name,renderer.html)
  end
  self.save_text(@css_output,renderer.sample_css) if @css_output != nil
  true
end
check_format(name) click to toggle source
# File lib/lib/coopy/coopy.rb, line 48
def check_format(name)
  return @format_preference if @extern_preference
  ext = ""
  if name != nil 
    pt = name.rindex(".",nil || 0) || -1
    if pt >= 0 
      begin
        _this = name[pt + 1..-1]
        ext = _this.downcase
      end
      case(ext)
      when "json"
        @format_preference = "json"
      when "ndjson"
        @format_preference = "ndjson"
      when "csv"
        @format_preference = "csv"
        @delim_preference = ","
      when "tsv"
        @format_preference = "csv"
        @delim_preference = "\t"
      when "ssv"
        @format_preference = "csv"
        @delim_preference = ";"
        @format_preference = "csv"
      when "psv"
        @format_preference = "csv"
        @delim_preference = [128169].pack("U")
      when "sqlite3"
        @format_preference = "sqlite"
      when "sqlite"
        @format_preference = "sqlite"
      when "html","htm"
        @format_preference = "html"
      when "www"
        @format_preference = "www"
      else
        ext = ""
      end
    end
  end
  @nested_output = @format_preference == "json" || @format_preference == "ndjson"
  @order_preference = !@nested_output
  ext
end
command(io,cmd,args) click to toggle source
# File lib/lib/coopy/coopy.rb, line 346
def command(io,cmd,args)
  r = 0
  r = io.command(cmd,args) if io.async
  if r != 999 
    io.write_stdout("$ " + _hx_str(cmd))
    begin
      _g = 0
      while(_g < args.length) 
        arg = args[_g]
        _g+=1
        io.write_stdout(" ")
        spaced = (arg.index(" ",nil || 0) || -1) >= 0
        io.write_stdout("\"") if spaced
        io.write_stdout(arg)
        io.write_stdout("\"") if spaced
      end
    end
    io.write_stdout("\n")
  end
  r = io.command(cmd,args) if !io.async
  r
end
coopyhx(io) click to toggle source
# File lib/lib/coopy/coopy.rb, line 872
def coopyhx(io)
  args = io.args
  return ::Coopy::Coopy.keep_around if args[0] == "--keep"
  self.run(args,io)
end
encode_table(name,t,render = nil) click to toggle source
# File lib/lib/coopy/coopy.rb, line 135
def encode_table(name,t,render = nil)
  self.set_format(@output_format) if @output_format != "copy"
  txt = ""
  self.check_format(name)
  @format_preference = "csv" if @format_preference == "sqlite" && !@extern_preference
  if render == nil 
    if @format_preference == "csv" 
      csv = ::Coopy::Csv.new(@delim_preference,@csv_eol_preference)
      txt = csv.render_table(t)
    elsif @format_preference == "ndjson" 
      txt = ::Coopy::Ndjson.new(t).render
    elsif @format_preference == "html" || @format_preference == "www" 
      self.render_table(name,t)
      return nil
    elsif @format_preference == "sqlite" 
      @io.write_stderr("! Cannot yet output to sqlite, aborting\n")
      return ""
    else 
      value = ::Coopy::Coopy.jsonify(t)
      txt = ::Haxe::Format::JsonPrinter._print(value,nil,"  ")
    end
  else 
    txt = render.render(t)
  end
  txt
end
get_renderer() click to toggle source
# File lib/lib/coopy/coopy.rb, line 100
def get_renderer 
  renderer = ::Coopy::DiffRender.new
  renderer.use_pretty_arrows(@flags.use_glyphs)
  renderer
end
init() click to toggle source
# File lib/lib/coopy/coopy.rb, line 31
def init 
  @extern_preference = false
  @format_preference = nil
  @delim_preference = nil
  @csv_eol_preference = nil
  @output_format = "copy"
  @output_format_set = false
  @nested_output = false
  @order_set = false
  @order_preference = false
  @strategy = nil
  @css_output = nil
  @fragment = false
  @flags = nil
  @cache_txt = nil
end
install_git_driver(io,formats) click to toggle source
# File lib/lib/coopy/coopy.rb, line 369
def install_git_driver(io,formats)
  r = 0
  if @status == nil 
    @status = {}
    @daff_cmd = ""
  end
  key = "hello"
  if !@status.include?(key) 
    io.write_stdout("Setting up git to use daff on")
    begin
      _g = 0
      while(_g < formats.length) 
        format = formats[_g]
        _g+=1
        io.write_stdout(" *." + _hx_str(format))
      end
    end
    io.write_stdout(" files\n")
    @status[key] = r
  end
  key = "can_run_git"
  if !@status.include?(key) 
    r = self.command(io,"git",["--version"])
    return r if r == 999
    @status[key] = r
    if r != 0 
      io.write_stderr("! Cannot run git, aborting\n")
      return 1
    end
    io.write_stdout("- Can run git\n")
  end
  daffs = ["daff","daff.rb","daff.py"]
  if @daff_cmd == "" 
    begin
      _g1 = 0
      while(_g1 < daffs.length) 
        daff = daffs[_g1]
        _g1+=1
        key1 = "can_run_" + _hx_str(daff)
        if !@status.include?(key1) 
          r = self.command(io,daff,["version"])
          return r if r == 999
          @status[key1] = r
          if r == 0 
            @daff_cmd = daff
            io.write_stdout("- Can run " + _hx_str(daff) + " as \"" + _hx_str(daff) + "\"\n")
            break
          end
        end
      end
    end
    if @daff_cmd == "" 
      io.write_stderr("! Cannot find daff, is it in your path?\n")
      return 1
    end
  end
  begin
    _g2 = 0
    while(_g2 < formats.length) 
      format1 = formats[_g2]
      _g2+=1
      key = "have_diff_driver_" + _hx_str(format1)
      if !@status.include?(key) 
        r = self.command(io,"git",["config","--global","--get","diff.daff-" + _hx_str(format1) + ".command"])
        return r if r == 999
        @status[key] = r
      end
      have_diff_driver = @status[key] == 0
      key = "add_diff_driver_" + _hx_str(format1)
      if !@status.include?(key) 
        r = self.command(io,"git",["config","--global","diff.daff-" + _hx_str(format1) + ".command",_hx_str(@daff_cmd) + " diff --git"])
        return r if r == 999
        io.write_stdout("- Cleared existing daff diff driver for " + _hx_str(format1) + "\n") if have_diff_driver
        io.write_stdout("- Added diff driver for " + _hx_str(format1) + "\n")
        @status[key] = r
      end
      key = "have_merge_driver_" + _hx_str(format1)
      if !@status.include?(key) 
        r = self.command(io,"git",["config","--global","--get","merge.daff-" + _hx_str(format1) + ".driver"])
        return r if r == 999
        @status[key] = r
      end
      have_merge_driver = @status[key] == 0
      key = "name_merge_driver_" + _hx_str(format1)
      if !@status.include?(key) 
        if !have_merge_driver 
          r = self.command(io,"git",["config","--global","merge.daff-" + _hx_str(format1) + ".name","daff tabular " + _hx_str(format1) + " merge"])
          return r if r == 999
        else 
          r = 0
        end
        @status[key] = r
      end
      key = "add_merge_driver_" + _hx_str(format1)
      if !@status.include?(key) 
        r = self.command(io,"git",["config","--global","merge.daff-" + _hx_str(format1) + ".driver",_hx_str(@daff_cmd) + " merge --output %A %O %A %B"])
        return r if r == 999
        io.write_stdout("- Cleared existing daff merge driver for " + _hx_str(format1) + "\n") if have_merge_driver
        io.write_stdout("- Added merge driver for " + _hx_str(format1) + "\n")
        @status[key] = r
      end
    end
  end
  if !io.exists(".git/config") 
    io.write_stderr("! This next part needs to happen in a git repository.\n")
    io.write_stderr("! Please run again from the root of a git repository.\n")
    return 1
  end
  attr = ".gitattributes"
  txt = ""
  post = ""
  if !io.exists(attr) 
    io.write_stdout("- No .gitattributes file\n")
  else 
    io.write_stdout("- You have a .gitattributes file\n")
    txt = io.get_content(attr)
  end
  need_update = false
  begin
    _g3 = 0
    while(_g3 < formats.length) 
      format2 = formats[_g3]
      _g3+=1
      if (txt.index("*." + _hx_str(format2),nil || 0) || -1) >= 0 
        io.write_stderr("- Your .gitattributes file already mentions *." + _hx_str(format2) + "\n")
      else 
        post += "*." + _hx_str(format2) + " diff=daff-" + _hx_str(format2) + "\n"
        post += "*." + _hx_str(format2) + " merge=daff-" + _hx_str(format2) + "\n"
        io.write_stdout("- Placing the following lines in .gitattributes:\n")
        io.write_stdout(post)
        txt += "\n" if txt != "" && !need_update
        txt += post
        need_update = true
      end
    end
  end
  io.save_content(attr,txt) if need_update
  io.write_stdout("- Done!\n")
  0
end
json_to_table(json) click to toggle source
# File lib/lib/coopy/coopy.rb, line 222
def json_to_table(json)
  output = nil
  begin
    _g = 0
    _g1 = Reflect.fields(json)
    while(_g < _g1.length) 
      name = _g1[_g]
      _g+=1
      t = Reflect.field(json,name)
      columns = Reflect.field(t,"columns")
      next if columns == nil
      rows = Reflect.field(t,"rows")
      next if rows == nil
      output = ::Coopy::SimpleTable.new(columns.length,rows.length)
      has_hash = false
      has_hash_known = false
      begin
        _g3 = 0
        _g2 = rows.length
        while(_g3 < _g2) 
          i = _g3
          _g3+=1
          row = rows[i]
          if !has_hash_known 
            has_hash = true if Reflect.fields(row).length == columns.length
            has_hash_known = true
          end
          if !has_hash 
            lst = row
            begin
              _g5 = 0
              _g4 = columns.length
              while(_g5 < _g4) 
                j = _g5
                _g5+=1
                val = lst[j]
                output.set_cell(j,i,::Coopy::Coopy.cell_for(val))
              end
            end
          else 
            _g51 = 0
            _g41 = columns.length
            while(_g51 < _g41) 
              j1 = _g51
              _g51+=1
              val1 = Reflect.field(row,columns[j1])
              output.set_cell(j1,i,::Coopy::Coopy.cell_for(val1))
            end
          end
        end
      end
    end
  end
  output.trim_blank if output != nil
  output
end
json_to_tables(json) click to toggle source
# File lib/lib/coopy/coopy.rb, line 216
def json_to_tables(json)
  tables = Reflect.field(json,"tables")
  return self.json_to_table(json) if tables == nil
  ::Coopy::JsonTables.new(json,@flags)
end
load_table(name) click to toggle source
# File lib/lib/coopy/coopy.rb, line 304
def load_table(name)
  ext = self.check_format(name)
  if ext == "sqlite" 
    sql = @io.open_sqlite_database(name)
    if sql == nil 
      @io.write_stderr("! Cannot open database, aborting\n")
      return nil
    end
    tab = ::Coopy::SqlTables.new(sql,@flags)
    return tab
  end
  txt = @io.get_content(name)
  if ext == "ndjson" 
    t = ::Coopy::SimpleTable.new(0,0)
    ndjson = ::Coopy::Ndjson.new(t)
    ndjson.parse(txt)
    return t
  end
  begin
    json = ::Haxe::Format::JsonParser.new(txt).parse_rec
    @format_preference = "json"
    t1 = self.json_to_tables(json)
    raise hx_raise("JSON failed") if t1 == nil
    return t1
  rescue => e
    e = hx_rescued(e)
    raise hx_raise(e) if ext == "json"
  end if ext == "json" || ext == ""
  @format_preference = "csv"
  csv = ::Coopy::Csv.new(@delim_preference)
  output = ::Coopy::SimpleTable.new(0,0)
  csv.parse_table(txt,output)
  @csv_eol_preference = csv.get_discovered_eol if @csv_eol_preference == nil
  output.trim_blank if output != nil
  output
end
render_table(name,t) click to toggle source
# File lib/lib/coopy/coopy.rb, line 117
def render_table(name,t)
  renderer = self.get_renderer
  renderer.render(t)
  self.apply_renderer(name,renderer)
end
render_tables(name,t) click to toggle source
# File lib/lib/coopy/coopy.rb, line 123
def render_tables(name,t)
  renderer = self.get_renderer
  renderer.render_tables(t)
  self.apply_renderer(name,renderer)
end
run(args,io = nil) click to toggle source
# File lib/lib/coopy/coopy.rb, line 512
def run(args,io = nil)
  io = ::Coopy::TableIO.new if io == nil
  if io == nil 
    puts "No system interface available"
    return 1
  end
  self.init
  @io = io
  more = true
  output = nil
  inplace = false
  git = false
  @flags = ::Coopy::CompareFlags.new
  @flags.always_show_header = true
  while(more) 
    more = false
    begin
      _g1 = 0
      _g = args.length
      while(_g1 < _g) 
        i = _g1
        _g1+=1
        tag = args[i]
        if tag == "--output" 
          more = true
          output = args[i + 1]
          args.slice!(i,2)
          break
        elsif tag == "--css" 
          more = true
          @fragment = true
          @css_output = args[i + 1]
          args.slice!(i,2)
          break
        elsif tag == "--fragment" 
          more = true
          @fragment = true
          args.slice!(i,1)
          break
        elsif tag == "--plain" 
          more = true
          @flags.use_glyphs = false
          args.slice!(i,1)
          break
        elsif tag == "--all" 
          more = true
          @flags.show_unchanged = true
          @flags.show_unchanged_columns = true
          args.slice!(i,1)
          break
        elsif tag == "--all-rows" 
          more = true
          @flags.show_unchanged = true
          args.slice!(i,1)
          break
        elsif tag == "--all-columns" 
          more = true
          @flags.show_unchanged_columns = true
          args.slice!(i,1)
          break
        elsif tag == "--act" 
          more = true
          @flags.acts = {} if @flags.acts == nil
          begin
            @flags.acts[args[i + 1]] = true
            true
          end
          args.slice!(i,2)
          break
        elsif tag == "--context" 
          more = true
          context = args[i + 1].to_i
          @flags.unchanged_context = context if context >= 0
          args.slice!(i,2)
          break
        elsif tag == "--inplace" 
          more = true
          inplace = true
          args.slice!(i,1)
          break
        elsif tag == "--git" 
          more = true
          git = true
          args.slice!(i,1)
          break
        elsif tag == "--unordered" 
          more = true
          @flags.ordered = false
          @flags.unchanged_context = 0
          @order_set = true
          args.slice!(i,1)
          break
        elsif tag == "--ordered" 
          more = true
          @flags.ordered = true
          @order_set = true
          args.slice!(i,1)
          break
        elsif tag == "--color" 
          more = true
          @flags.terminal_format = "ansi"
          args.slice!(i,1)
          break
        elsif tag == "--no-color" 
          more = true
          @flags.terminal_format = "plain"
          args.slice!(i,1)
          break
        elsif tag == "--input-format" 
          more = true
          self.set_format(args[i + 1])
          args.slice!(i,2)
          break
        elsif tag == "--output-format" 
          more = true
          @output_format = args[i + 1]
          @output_format_set = true
          args.slice!(i,2)
          break
        elsif tag == "--id" 
          more = true
          @flags.ids = Array.new if @flags.ids == nil
          @flags.ids.push(args[i + 1])
          args.slice!(i,2)
          break
        elsif tag == "--ignore" 
          more = true
          @flags.ignore_column(args[i + 1])
          args.slice!(i,2)
          break
        elsif tag == "--index" 
          more = true
          @flags.always_show_order = true
          @flags.never_show_order = false
          args.slice!(i,1)
          break
        elsif tag == "--www" 
          more = true
          @output_format = "www"
          @output_format_set = true
          args.slice!(i,1)
        elsif tag == "--table" 
          more = true
          @flags.add_table(args[i + 1])
          args.slice!(i,2)
          break
        elsif tag == "-w" || tag == "--ignore-whitespace" 
          more = true
          @flags.ignore_whitespace = true
          args.slice!(i,1)
          break
        elsif tag == "-i" || tag == "--ignore-case" 
          more = true
          @flags.ignore_case = true
          args.slice!(i,1)
          break
        elsif tag == "--padding" 
          more = true
          @flags.padding_strategy = args[i + 1]
          args.slice!(i,2)
          break
        elsif tag == "-e" || tag == "--eol" 
          more = true
          ending = args[i + 1]
          if ending == "crlf" 
            ending = "\r\n"
          elsif ending == "lf" 
            ending = "\n"
          elsif ending == "cr" 
            ending = "\r"
          elsif ending == "auto" 
            ending = nil
          else 
            io.write_stderr("Expected line ending of either 'crlf' or 'lf' but got " + _hx_str(ending) + "\n")
            return 1
          end
          @csv_eol_preference = ending
          args.slice!(i,2)
          break
        end
      end
    end
  end
  cmd = args[0]
  if args.length < 2 
    if cmd == "version" 
      io.write_stdout(_hx_str(::Coopy::Coopy.version) + "\n")
      return 0
    end
    if cmd == "git" 
      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).\n")
      io.write_stdout("\n")
      io.write_stdout("Automatic setup\n")
      io.write_stdout("---------------\n\n")
      io.write_stdout("Run:\n")
      io.write_stdout("  daff git csv\n")
      io.write_stdout("\n")
      io.write_stdout("Manual setup\n")
      io.write_stdout("------------\n\n")
      io.write_stdout("Create and add a file called .gitattributes in the root directory of your\nrepository, containing:\n\n")
      io.write_stdout("  *.csv diff=daff-csv\n")
      io.write_stdout("  *.csv merge=daff-csv\n")
      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")
      io.write_stdout("  [diff \"daff-csv\"]\n")
      io.write_stdout("  command = daff diff --git\n")
      io.write_stderr("\n")
      io.write_stdout("  [merge \"daff-csv\"]\n")
      io.write_stdout("  name = daff tabular merge\n")
      io.write_stdout("  driver = daff merge --output %A %O %A %B\n\n")
      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. Add --no-color if your terminal does not support ANSI colors.")
      io.write_stderr("\n")
      return 0
    end
    if args.length < 1 
      io.write_stderr("daff can produce and apply tabular diffs.\n")
      io.write_stderr("Call as:\n")
      io.write_stderr("  daff [--color] [--no-color] [--output OUTPUT.csv] a.csv b.csv\n")
      io.write_stderr("  daff [--output OUTPUT.html] a.csv b.csv\n")
      io.write_stderr("  daff [--output OUTPUT.csv] parent.csv a.csv b.csv\n")
      io.write_stderr("  daff [--output OUTPUT.ndjson] a.ndjson b.ndjson\n")
      io.write_stderr("  daff [--www] a.csv b.csv\n")
      io.write_stderr("  daff patch [--inplace] [--output OUTPUT.csv] a.csv patch.csv\n")
      io.write_stderr("  daff merge [--inplace] [--output OUTPUT.csv] parent.csv a.csv b.csv\n")
      io.write_stderr("  daff trim [--output OUTPUT.csv] source.csv\n")
      io.write_stderr("  daff render [--output OUTPUT.html] diff.csv\n")
      io.write_stderr("  daff copy in.csv out.tsv\n")
      io.write_stderr("  daff in.csv\n")
      io.write_stderr("  daff git\n")
      io.write_stderr("  daff version\n")
      io.write_stderr("\n")
      io.write_stderr("The --inplace option to patch and merge will result in modification of a.csv.\n")
      io.write_stderr("\n")
      io.write_stderr("If you need more control, here is the full list of flags:\n")
      io.write_stderr("  daff diff [--output OUTPUT.csv] [--context NUM] [--all] [--act ACT] a.csv b.csv\n")
      io.write_stderr("     --act ACT:     show only a certain kind of change (update, insert, delete)\n")
      io.write_stderr("     --all:         do not prune unchanged rows or columns\n")
      io.write_stderr("     --all-rows:    do not prune unchanged rows\n")
      io.write_stderr("     --all-columns: do not prune unchanged columns\n")
      io.write_stderr("     --color:       highlight changes with terminal colors (default in terminals)\n")
      io.write_stderr("     --context NUM: show NUM rows of context\n")
      io.write_stderr("     --id:          specify column to use as primary key (repeat for multi-column key)\n")
      io.write_stderr("     --ignore:      specify column to ignore completely (can repeat)\n")
      io.write_stderr("     --index:       include row/columns numbers from original tables\n")
      io.write_stderr("     --input-format [csv|tsv|ssv|psv|json]: set format to expect for input\n")
      io.write_stderr("     --eol [crlf|lf|cr|auto]: separator between rows of csv output.\n")
      io.write_stderr("     --no-color:    make sure terminal colors are not used\n")
      io.write_stderr("     --ordered:     assume row order is meaningful (default for CSV)\n")
      io.write_stderr("     --output-format [csv|tsv|ssv|psv|json|copy|html]: set format for output\n")
      io.write_stderr("     --padding [dense|sparse|smart]: set padding method for aligning columns\n")
      io.write_stderr("     --table NAME:  compare the named table, used with SQL sources\n")
      io.write_stderr("     --unordered:   assume row order is meaningless (default for json formats)\n")
      io.write_stderr("     -w / --ignore-whitespace: ignore changes in leading/trailing whitespace\n")
      io.write_stderr("     -i / --ignore-case: ignore differences in case\n")
      io.write_stderr("\n")
      io.write_stderr("  daff render [--output OUTPUT.html] [--css CSS.css] [--fragment] [--plain] diff.csv\n")
      io.write_stderr("     --css CSS.css: generate a suitable css file to go with the html\n")
      io.write_stderr("     --fragment:    generate just a html fragment rather than a page\n")
      io.write_stderr("     --plain:       do not use fancy utf8 characters to make arrows prettier\n")
      io.write_stderr("     --www:         send output to a browser\n")
      return 1
    end
  end
  cmd1 = args[0]
  offset = 1
  if !Lambda.has(["diff","patch","merge","trim","render","git","version","copy"],cmd1) 
    if (cmd1.index("--",nil || 0) || -1) == 0 
      cmd1 = "diff"
      offset = 0
    elsif (cmd1.index(".",nil || 0) || -1) != -1 
      if args.length == 2 
        cmd1 = "diff"
        offset = 0
      elsif args.length == 1 
        cmd1 = "copy"
        offset = 0
      end
    end
  end
  if cmd1 == "git" 
    types = args.slice!(offset,args.length - offset)
    return self.install_git_driver(io,types)
  end
  if git 
    ct = args.length - offset
    if ct != 7 && ct != 9 
      io.write_stderr("Expected 7 or 9 parameters from git, but got " + _hx_str(ct) + "\n")
      return 1
    end
    git_args = args.slice!(offset,ct)
    args.slice!(0,args.length)
    offset = 0
    old_display_path = git_args[0]
    new_display_path = git_args[0]
    old_file = git_args[1]
    new_file = git_args[4]
    if ct == 9 
      io.write_stdout(git_args[8])
      new_display_path = git_args[7]
    end
    io.write_stdout("--- a/" + _hx_str(old_display_path) + "\n")
    io.write_stdout("+++ b/" + _hx_str(new_display_path) + "\n")
    args.push(old_file)
    args.push(new_file)
  end
  parent = nil
  if args.length - offset >= 3 
    parent = self.load_table(args[offset])
    offset+=1
  end
  aname = args[offset]
  a = self.load_table(aname)
  b = nil
  if args.length - offset >= 2 
    if cmd1 != "copy" 
      b = self.load_table(args[1 + offset])
    else 
      output = args[1 + offset]
    end
  end
  @flags.diff_strategy = @strategy
  if inplace 
    io.write_stderr("Please do not use --inplace when specifying an output.\n") if output != nil
    output = aname
    return 1
  end
  output = "-" if output == nil
  ok = true
  if cmd1 == "diff" 
    if !@order_set 
      @flags.ordered = @order_preference
      @flags.unchanged_context = 0 if !@flags.ordered
    end
    @flags.allow_nested_cells = @nested_output
    self.run_diff(parent,a,b,@flags,output)
  elsif cmd1 == "patch" 
    patcher = ::Coopy::HighlightPatch.new(a,b)
    patcher.apply
    self.save_table(output,a)
  elsif cmd1 == "merge" 
    merger = ::Coopy::Merger.new(parent,a,b,@flags)
    conflicts = merger.apply
    ok = conflicts == 0
    io.write_stderr(_hx_str(conflicts) + " conflict" + _hx_str((((conflicts > 1) ? "s" : ""))) + "\n") if conflicts > 0
    self.save_table(output,a)
  elsif cmd1 == "trim" 
    self.save_table(output,a)
  elsif cmd1 == "render" 
    self.render_table(output,a)
  elsif cmd1 == "copy" 
    os = ::Coopy::Tables.new(a)
    os.add("untitled")
    self.save_tables(output,os,self.use_color(@flags,output),false)
  end
  if ok 
    return 0
  else 
    return 1
  end
end
run_diff(parent,a,b,flags,output) click to toggle source
# File lib/lib/coopy/coopy.rb, line 291
def run_diff(parent,a,b,flags,output)
  ct = ::Coopy::Coopy.compare_tables3(parent,a,b,flags)
  align = ct.align
  td = ::Coopy::TableDiff.new(align,flags)
  o = ::Coopy::SimpleTable.new(0,0)
  os = ::Coopy::Tables.new(o)
  td.hilite_with_nesting(os)
  use_color = self.use_color(flags,output)
  self.save_tables(output,os,use_color,true)
end
save_table(name,t,render = nil) click to toggle source
# File lib/lib/coopy/coopy.rb, line 129
def save_table(name,t,render = nil)
  txt = self.encode_table(name,t,render)
  return true if txt == nil
  self.save_text(name,txt)
end
save_tables(name,os,use_color,is_diff) click to toggle source
# File lib/lib/coopy/coopy.rb, line 162
def save_tables(name,os,use_color,is_diff)
  self.set_format(@output_format) if @output_format != "copy"
  txt = ""
  self.check_format(name)
  render = nil
  render = ::Coopy::TerminalDiffRender.new(@flags,@delim_preference,is_diff) if use_color
  order = os.get_order
  return self.save_table(name,os.one,render) if order.length == 1
  return self.render_tables(name,os) if @format_preference == "html" || @format_preference == "www"
  need_blank = false
  if order.length == 0 || os.has_ins_del 
    txt += self.encode_table(name,os.one,render)
    need_blank = true
  end
  if order.length > 1 
    _g1 = 1
    _g = order.length
    while(_g1 < _g) 
      i = _g1
      _g1+=1
      t = os.get(order[i])
      if t != nil 
        txt += "\n" if need_blank
        need_blank = true
        txt += _hx_str(order[i]) + "\n"
        line = ""
        begin
          _g3 = 0
          _g2 = order[i].length
          while(_g3 < _g2) 
            i1 = _g3
            _g3+=1
            line += "="
          end
        end
        txt += _hx_str(line) + "\n"
        txt += self.encode_table(name,os.get(order[i]),render)
      end
    end
  end
  self.save_text(name,txt)
end
save_text(name,txt) click to toggle source
# File lib/lib/coopy/coopy.rb, line 205
def save_text(name,txt)
  if name == nil 
    @cache_txt += txt
  elsif name != "-" 
    @io.save_content(name,txt)
  else 
    @io.write_stdout(txt)
  end
  true
end
set_format(name) click to toggle source
# File lib/lib/coopy/coopy.rb, line 94
def set_format(name)
  @extern_preference = false
  self.check_format("." + _hx_str(name))
  @extern_preference = true
end
use_color(flags,output) click to toggle source
# File lib/lib/coopy/coopy.rb, line 279
def use_color(flags,output)
  use_color = flags.terminal_format == "ansi"
  if flags.terminal_format == nil 
    if (output == nil || output == "-") && (@output_format == "copy" || @output_format == "csv" || @output_format == "psv") 
      if @io != nil 
        use_color = @io.is_tty if @io.is_tty_known
      end
    end
  end
  use_color
end