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