Class: TextGraph::Parser

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

Instance Method Summary collapse

Constructor Details

#initialize(str) ⇒ Parser

Returns a new instance of Parser.



20
21
22
# File 'lib/textgraph.rb', line 20

def initialize(str)
  @chars = CharMap.new(str)
end

Instance Method Details

#cell_at(cells, x, y) ⇒ Object

Raises:

  • (ArgumentError)


43
44
45
46
47
48
49
50
51
# File 'lib/textgraph.rb', line 43

def cell_at(cells, x, y)
  cells.each_with_index{|cell, i|
    if (cell.x ... (cell.x + cell.w)) === x and
       (cell.y ... (cell.y + cell.h)) === y
      return i
    end
  }
  raise ArgumentError, "no cell found at #{x},#{y}"
end

#collect_cellsObject



69
70
71
72
73
74
75
76
# File 'lib/textgraph.rb', line 69

def collect_cells
  collect_chars(?*).map{|x,y|
    w, h = is_cell?(x,y)
    if w && h
      Cell.new(x, y, w, h, get_str(x, y, w, h))
    end
  }.compact
end

#collect_chars(char) ⇒ Object



121
122
123
124
125
# File 'lib/textgraph.rb', line 121

def collect_chars(char)
  @chars.map{|x,y,c|
    (c == char) ? [x,y] : nil
  }.compact
end

#find_end(x, y, dx, dy, goal) ⇒ Object

Raises:

  • (ArgumentError)


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/textgraph.rb', line 103

def find_end(x, y, dx, dy, goal)
  raise ArgumentError, "holiz/vert only" if dx != 0 && dy != 0
  begin
    x += dx
    y += dy
    case @chars[x, y] 
    when goal
      return [x,y] 
    when ?-, ?|, ?+, ?v, ?^, ?>, ?<
      ;
    else
      break
    end
  end while x < @chars.width && y < @chars.height

  return nil
end


30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/textgraph.rb', line 30

def find_links(cells)
  #[[0,1], [1,3], [3,2], [2,0]]
  collect_chars(?+).map do |x,y|
    #dx, dy, goal = get_direction(x,y)
    #$B$R$I$$%"%k%4%j%:%`$@(B
    x2, y2 = find_end(x, y, 1, 0, ?>)
    x2, y2 = find_end(x, y,-1, 0, ?<) if x2.nil?
    x2, y2 = find_end(x, y, 0, 1, ?v) if x2.nil?
    x2, y2 = find_end(x, y, 0,-1, ?^) if x2.nil?
    [cell_at(cells,x,y), cell_at(cells,x2,y2)]
  end
end

#get_direction(x, y) ⇒ Object

Raises:

  • (ArgumentError)


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/textgraph.rb', line 53

def get_direction(x,y)
  raise ArgumentError, "not start" if @chars[x,y] != ?+
  case
  when [?-, ?>].include?(@chars[x+1,y])
    [1, 0, ?>]
  when [?|, ?v].include?(@chars[x,y+1])
    [0, 1, ?v]
  when [?-, ?<].include?(@chars[x-1,y])
    [-1, 0, ?<]
  when [?|, ?^].include?(@chars[x,y-1])
    [0, -1, ?^]
  else
    raise ArgumentError, "can't decide direction"
  end
end

#get_str(x, y, w, h) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/textgraph.rb', line 78

def get_str(x, y, w, h)
  a = []
  (y+1).upto(y+(h-1)-1) do |yy|
    s = ""
    (x+1).upto(x+(w-1)-1) do |xx|
      s << @chars[xx, yy].chr
    end
    a << s 
  end
  a.join("\n")
end

#is_cell?(x, y) ⇒ Boolean

Returns:

  • (Boolean)


90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/textgraph.rb', line 90

def is_cell?(x, y)
  if [?-, ?v, ?+].include?(@chars[x+1, y]) and [?|, ?>, ?+].include?(@chars[x, y+1])
    x2 = find_end(x, y,  1, 0, ?*)[0]
    y2 = find_end(x, y,  0, 1, ?*)[1]
    x3 = find_end(x, y2, 1, 0, ?*)[0]
    y3 = find_end(x2, y, 0, 1, ?*)[1]

    return (x2==x3 && y2==y3) ? [x2-x+1, y2-y+1] : false
  else
    return false
  end
end

#parseObject



24
25
26
27
28
# File 'lib/textgraph.rb', line 24

def parse
  cells = collect_cells()
  links = find_links(cells)
  Graph.new(cells, links)
end