Class: Chunk

Inherits:
Object
  • Object
show all
Defined in:
lib/merge3.rb

Overview

this is a little holder class (struct?) that represents a piece of text in a file.

Direct Known Subclasses

Deleted

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(start, length, string, from = -1)) ⇒ Chunk

Returns a new instance of Chunk.



525
526
527
528
529
# File 'lib/merge3.rb', line 525

def initialize( start , length , string , from = -1)
  raise "Error nil string passed start=#{start} length=#{length} str=-#{str}=" if string.nil?
  @start , @length ,  @str , @from = start , length , string , from
  @whitespace = []
end

Instance Attribute Details

#addedObject

a chunk that was added (if there is such a one)



513
514
515
# File 'lib/merge3.rb', line 513

def added
  @added
end

#fromObject (readonly)

the index into the original file where the string starts, -1 for adds



512
513
514
# File 'lib/merge3.rb', line 512

def from
  @from
end

#lengthObject (readonly)

length of the string (somewhat redundant with the string below)



508
509
510
# File 'lib/merge3.rb', line 508

def length
  @length
end

#startObject (readonly)

the byte index into the file where the string is in (the edited file)



506
507
508
# File 'lib/merge3.rb', line 506

def start
  @start
end

#strObject (readonly)

the actual string. This is just here for convinience, it’s in the file



510
511
512
# File 'lib/merge3.rb', line 510

def str
  @str
end

#whitespaceObject

the table for whitespace



514
515
516
# File 'lib/merge3.rb', line 514

def whitespace
  @whitespace
end

Class Method Details

.short_string(s) ⇒ Object

cut the chunk to max 71 characters for readable output



517
518
519
520
521
522
523
# File 'lib/merge3.rb', line 517

def Chunk::short_string( s )
  if s.length < 71
    return "--" + s.to_s + "--"
  else 
    return "--"  +  s[0,20] + "...Cut #{s.length-40} chars..." + s[s.length - 20 , 20] + "--"
  end
end

Instance Method Details

#add?Boolean

adds are not copied, hence have no from attribute.

Returns:

  • (Boolean)


644
645
646
# File 'lib/merge3.rb', line 644

def add?  # adds are not copied, hence have no from attribute. 
  @from == -1  #   a copy carries a positive number as offset into the original
end

#includes_copy?(copy) ⇒ Boolean

is the copy chunk fully inside this

Returns:

  • (Boolean)


653
654
655
# File 'lib/merge3.rb', line 653

def includes_copy? copy  # is the copy chunk fully inside this
  (copy.start >= @start) and (copy.stop <= stop)
end

#join_adds(add) ⇒ Object

this joins two chunks, which are presumed to be adds (so no fiddling with from) self is changed and the argument untouched (to be deleted)



677
678
679
680
# File 'lib/merge3.rb', line 677

def join_adds add
  @str += add.str
  @length = @str.length
end

#org_includes?(point) ⇒ Boolean

is the point (char index) in the original copied string

Returns:

  • (Boolean)


649
650
651
# File 'lib/merge3.rb', line 649

def org_includes? point  
  ( @from != -1 ) and ( @from <= point ) and ( point < org_stop )   
end

#org_overlaps?(two) ⇒ Boolean

does any part of the original overlap (from - org_stop )

Returns:

  • (Boolean)


671
672
673
# File 'lib/merge3.rb', line 671

def org_overlaps? two  
  from > two.from ?  from < two.org_stop : org_stop > two.from
end

#org_stopObject

index of where the string ends in the original file (nonsense for adds)



640
641
642
# File 'lib/merge3.rb', line 640

def org_stop 
  @from + @length
end

#overlaps?(two) ⇒ Boolean

does some part of two overlap. always takes me 5 minutes to get

Returns:

  • (Boolean)


666
667
668
# File 'lib/merge3.rb', line 666

def overlaps? two           # but a drawing helps
  start > two.start ?  start < two.stop : stop > two.start
end

#popObject

return the first char, and remove it from the string, adjusting length + start also return any whitespace entry, if there is such a thing



565
566
567
568
569
570
571
572
573
574
575
576
577
# File 'lib/merge3.rb', line 565

def pop
  white = nil
  if (not @whitespace.empty?)  and  (@whitespace.first[0] == @start  )
    white = @whitespace.delete_at(0)
    puts "White --#{white}--#{@start}"
  end
  char = @str[0]
  @str = @str[1..-1]
  @length  -= 1
  @start += 1
  @from += 1 if @from != -1
  return [ char , white ]
end

#push(arg) ⇒ Object

puts the char at the end of the string, adjusting the length add the whitespace if it’s not nil



556
557
558
559
560
561
# File 'lib/merge3.rb', line 556

def push( arg )
  char , space = arg
  @str << char
  @length += 1
  @whitespace << space unless space.nil?
end

#real_stringObject

unsqueeze whitespace if present



598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
# File 'lib/merge3.rb', line 598

def real_string
  return @str if @whitespace.empty?
  stri = @str.dup
  #puts "--" + str + "--" + @str.length.to_s
  begin 
    @whitespace.reverse.each do | index , st |
      stri[index - @start ,1] = st
    end
  rescue
    st = "start=#{start} len=#{length} stop=#{stop} from=#{from} org_stop=#{org_stop} "   + @str
    st += " \n  whitespace=#{@whitespace.length} " 
    @whitespace.each do | start , s |
      st += "-" + start.to_s + " " + s.length.to_s + " " 
      st += "n " if s.include?( "\n" )
    end
    puts st
    raise
  end
  stri
end

#rotateObject

put the first character at the end



549
550
551
552
# File 'lib/merge3.rb', line 549

def rotate
  @str = @str[1..-1] + @str[0,1]
  @start += 1
end

#rstring(fro, to) ⇒ Object

return a substring in the original files coordinates



658
659
660
661
662
663
# File 'lib/merge3.rb', line 658

def rstring( fro , to )
  to = org_stop if to == -1
  throw "error #{fro} #{to} #{self}" if fro < @from or to > org_stop
  @length -= to - fro
  @str[ fro - @from , to - @from ] 
end

#split_at_org!(pos) ⇒ Object

split the chunk into two at the given position, change this and return the right one



684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
# File 'lib/merge3.rb', line 684

def split_at_org! pos
  #puts "SPLIT #{pos}  #{self}"
  throw "position not in chunk #{pos} : #{self}" unless org_includes?( pos )
  left_length = pos - @from 
  right_length = org_stop - pos 
  right = Chunk.new( @start + left_length , right_length , @str[left_length, right_length] , pos )
  right.whitespace = @whitespace.dup.delete_if do | index , s |
    index < right.start 
  end 
  #puts " split #{right} "
  throw "Right split error #{self} , #{right} :#{pos}" if right.length != right_length
  @str = @str[0, left_length]
  raise "Error nil string =#{start} length=#{length} str=-#{@str}=" if @str.nil?
  @length = @str.length 
  @whitespace.delete_if do | index , s |
    index >= right.start 
  end 
  #puts " white #{@whitespace} "
  #puts " left #{self} "
  throw "Left split error #{self} , #{right} :#{pos} :#{left_length}" if @length != left_length
  return right
end

#squeezeObject

squeeze the whitespace, ie for all sequences of whitespace(space,tab,newline), and all non space whitespaces, replace it with a single whitespace and record the change in the array



582
583
584
585
586
587
588
589
590
591
592
593
594
595
# File 'lib/merge3.rb', line 582

def squeeze
  old = @str.dup
  @whitespace = []
  at = 0 
  while ( index =  @str.index(/\s+/ , at ) )
    at = index + $&.length
    if $& != ' '  # do nothing for single spaces
      @whitespace.push [ index , $&  ]
      @str[index , $&.length] = ' '
    end
  end
  @length = @str.length
  throw old if DEBUG and old != real_string 
end

#stopObject

index of where the string ends. this should be called end, but that’s a keyword.



635
636
637
# File 'lib/merge3.rb', line 635

def stop 
  @start + @length 
end

#subchunk(startt, len, fromm) ⇒ Object

get a substring from the chunk and carry whitespace table accross start is in the files coordinates (not the strings of the chunk)



621
622
623
624
625
626
627
628
629
630
631
# File 'lib/merge3.rb', line 621

def subchunk( startt  , len , fromm )
  stri = @str[ startt - @start , len ]
  table = []
  @whitespace.each do | arr |
    table << arr if arr[0] >= startt and arr[0]  < ( startt + len )
  end  
  chunk = Chunk.new( startt , len , stri , fromm )
  chunk.whitespace = table
  #puts "SUB at #{startt} #{len} #{chunk}" if fromm == 62
  chunk
end

#to_sObject

outputs all attributes and a readable version of the string also whitespace if present



533
534
535
536
537
538
539
540
541
542
543
544
545
546
# File 'lib/merge3.rb', line 533

def to_s  #for debug output
  st = "start=#{start} len=#{length} stop=#{stop} from=#{from} org_stop=#{org_stop} " 
  st += Chunk::short_string(real_string)
  st += " \n  added=#{added} " unless added.nil?
  st += " \n  whitespace=#{@whitespace.length} " unless @whitespace.empty? 
  ws_count = 0 
  @whitespace.each do | start , s |
    st += "-" + start.to_s + " " + s.length.to_s + " " 
    st += "n " if s.include?( "\n" )
    ws_count += 1
    break if ws_count  > 5
  end 
  st
end