Class: LinkParser::Linkage

Inherits:
Object show all
Defined in:
lib/linkparser/linkage.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(words = [], connections = []) ⇒ Linkage

Returns a new instance of Linkage.



32
33
34
35
# File 'lib/linkparser/linkage.rb', line 32

def initialize( words=[], connections=[] )
  @connections = connections
  @words = words
end

Instance Attribute Details

#connectionsObject (readonly)

the connections of this linkage



38
39
40
# File 'lib/linkparser/linkage.rb', line 38

def connections
  @connections
end

#wordsObject (readonly)

the words in this linkage



41
42
43
# File 'lib/linkparser/linkage.rb', line 41

def words
  @words
end

Instance Method Details

#add_connections(*connections) ⇒ Object Also known as: addConnections

add new connections to the list of connections



51
52
53
54
# File 'lib/linkparser/linkage.rb', line 51

def add_connections(*connections)
  @connections += connections
  self
end

#combine(other) ⇒ Object Also known as: +

Combine two linkages together.



44
45
46
47
# File 'lib/linkparser/linkage.rb', line 44

def combine(other)
  Linkage::new( @words.superimpose(other.words),
          @connections + other.connections )
end

#connected?Boolean

returns whether the linkage is connected

Returns:

  • (Boolean)


80
81
82
# File 'lib/linkparser/linkage.rb', line 80

def connected? 
  @words.length == @words.compact.length
end

#eql?(o) ⇒ Boolean

Equality based only on the “important” parts.

Returns:

  • (Boolean)


90
91
92
# File 'lib/linkparser/linkage.rb', line 90

def eql?(o)
  @connections.sort.eql?(o.connections.sort)
end

#hashObject

Hash on the only important part - the connections.



85
86
87
# File 'lib/linkparser/linkage.rb', line 85

def hash 
  @connections.sort.hash
end

#insert(connection, left, right, left_word, right_word) ⇒ Object

Inserts into this linkage the connection and words found in the supplied arguments.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/linkparser/linkage.rb', line 59

def insert(connection, left, right, left_word, right_word)
  @connections << connection
  if @words[left]
    @words[left].combine!(left_word)
  else
    @words[left] = left_word
  end
  if @words[right]
    @words[right].combine!(right_word)
  else
    @words[right] = right_word
  end
  self
end

#inspectObject

string display



95
96
97
98
99
# File 'lib/linkparser/linkage.rb', line 95

def inspect
  result = @words.collect {|word| word.to_s}.join(" ") +
    " --- " + @connections.join(" ")
  #:TODO: ?
end

#to_sObject

pretty string display



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/linkparser/linkage.rb', line 102

def to_s
  rows = [] # the diagram
  rows.unshift(@words.join(' ').split('')) # insert the words
  pos = 0
  starts = @words.map {|word| # the starting position of each word
    start = pos
    pos += word.to_s.length + 1
    start
  }
  offsets = @words.map {|word| word.to_s.length / 2}
  centers = (starts.zip(offsets)).map {|c| c[0]+c[1]} # where to attach connections to each word
  pos = 0
  spaces = [] # where there are spaces between words
  @words.each {|word|
    spaces << ((pos - 1)..(pos - 1)) if pos.nonzero?
    pos += word.to_s.length + 1
  }
  rows.unshift(Array.new(rows[0].length, " "))
  centers.each {|i| rows[0][i] = "|"}
  conns = @connections.dup
  until conns.empty?
    row = Array.new(rows[0].length, " ")
    these = []
    conns.delete_if {|conn| conn.length == (rows.length - 1) and these << conn}
    #:TODO: loops infinitely - need to use counter instead of rows.length
    #next if these.empty?
    these.each {|conn|
      first = centers[conn.lword.position]
      last = centers[conn.rword.position]
      span = (first..last)
      dist = span.to_a.length
      disp = "+" + conn.to_s + "+" # minimum display string
      if disp.length > dist
        #:TODO: *ack*
        # i will need to expand the spaces inbetween the words,
        # as well as between the connection arcs, and then
        # update the centers and spaces array.  this could be
        # done one space at a time, cycling through the possible
        # word gaps.
        space_affect = (spaces.index(spaces.find {|r| first <= r.first}))..(spaces.length - 1)
        cent_affect = (centers.index(centers.find {|i| first <= i}))..(centers.length - 1)
        until dist >= disp.length
          #:?:
          dist += 1
#               centers.map! {|i|
#                 cent_affect.member?(centers.index(i)) ? i + 1 : i
#               }
#               first = centers[conn.lword.position]
#               last = centers[conn.rword.position]
#               span = (first..last)
#               dist = span.to_a.length
        end
      elsif disp.length < dist
        side = true
        until disp.length >= dist
          if side
            disp[0] = "+-"
          else
            disp[-1] = "-+"
          end
          side = ! side
        end
      end
      first.upto(last) do |i|
        row[i] = disp.slice!(0).chr
      end
    }
    centers.each_with_index {|i,w|
      row[i] = "|" if row[i] == " " and
        conns.find {|conn| [conn.rword, conn.lword].include?(@words[w])}
    }
    rows.unshift(row)
  end
  return (rows.map {|row| row.join('')}).join("\n")
end

#to_strObject

string conversion



179
180
181
# File 'lib/linkparser/linkage.rb', line 179

def to_str 
  @words.join(' ')
end

#valid?Boolean

returns whether or not the linkage is valid

Returns:

  • (Boolean)


75
76
77
# File 'lib/linkparser/linkage.rb', line 75

def valid? 
  (@connections.length + 1) >= @words.length
end