I get the following error from the code below. Doesn't repro
in gdb
at all:
% ./box_parse.rb
./box_parse.rb:95: warning: ambiguous first argument; put
parentheses
or even spaces
Loaded suite ./box_parse
Started
EFEEE..EFE
Finished in 0.016785 seconds.
/usr/local/lib/ruby/1.8/test/unit/util/backtracefilter.rb:17
: [BUG]
rb_gc_mark(): unknown data type 0x1b(0x435530) non object
ruby 1.8.5 (2006-09-29) [i686-darwin8.7.1]
Abort trap
-----
#!/usr/local/bin/ruby -w
require 'set'
class Box
attr_accessor , :y,
:right, :bottom
def initialize(x, y, right, bottom)
x, y, right, bottom = x, y, right, bottom
end
end
module BoxParser
def box_x_delimeters(boxes)
boxes.map { |box| box.right }.uniq.sort
end
def box_y_delimeters(boxes)
boxes.map { |box| box.bottom }.uniq.sort
end
def box_rowspans(boxes)
colspans = Hash.new(0)
boxes.each do |box| colspans[box] end
box_y_delimeters(boxes).each do |delim|
boxes.each do |box|
rowspans[box] += 1 if box.y < delim and
box.bottom >= delim
end
end
rowspans
end
def box_colspans(boxes)
colspans = Hash.new(0)
boxes.each do |box| colspans[box] end
box_y_delimeters(boxes).each do |delim|
boxes.each do |box|
colspans[box] += 1 if box.x < delim and
box.right >= delim
end
end
colspans
end
def box_rows(boxes)
rows, boxes_left = [], boxes.uniq
box_y_delimeters(boxes).each do |box|
boxes_in_row = boxes_left.find_all { |box| box.y <
delim }
boxes_left -= boxes_in_row
rows.push(*boxes_in_row.map { |box| box.x}.sort)
end
rows
end
# Rendering and parsing tables.
def render_html_table(boxes)
rowspans, colspans = box_rowspans(boxes),
box_colspans(boxes)
table = '<table border="border">n'
box_rows(boxes).each do |row|
table += ' <tr>n'
row.each do |box|
table += " <td rowspan="%d"
colspan="%d">%s</td>n" %
[rowspans[box], colspans[box], 'blank<br/>' *
(box.bottom - box.y)]
end
table += ' </tr>n'
end
table += '</table>n'
table
end
def char(grid, x, y)
return grid[y][x] if 0 <= y and y < grid.size and
0 <= x and x <
grid[y].size
return " "
end
def box_right(x, y)
# todo: find
(x..grid[y+1].size).each do |right|
return right if char(grid, right + 1, y + 1) == '|'
end
raise RuntimeError("Unterminated box.")
end
def box_bottom(x, y)
# todo: find
(y..grid.size).each do |bottom|
return bottom if char(grid, x + 1, bottom + 1) == '-'
end
raise RuntimeError("Unterminated box.")
end
def parse_ascii_table(table)
grid = table.split /n/
boxes = []
grid.size.times do |y|
grid[y].size.times do |x|
if %w(- |).include? char(grid, x, y) and
char(grid, x, y + 1) == '|' and
char(grid, x + 1, y) == '-' then
boxes << Box.new(x, y, box_right(x, y),
box_bottom(x, y))
end
end
end
return boxes
end
end
include BoxParser
require 'test/unit/testcase'
require 'test/unit' if __FILE__ == $0
class TestBoxParser < Test::Unit::TestCase
# +---+---+
# | | |
# +---+---+
# | |
# +---+---+
def setup
boxes = []
boxes << Box.new(0, 0, 4, 2)
boxes << Box.new(4, 0, 8, 2)
boxes << Box.new(0, 2, 8, 4)
end
def test_box_bottom
assert_equal :foo, box_bottom( boxes)
end
def test_box_colspans
assert_equal :foo, box_colspans( boxes)
end
def test_box_right
assert_equal :foo, box_right( boxes)
end
def test_box_rows
assert_equal :foo, box_rows( boxes)
end
def test_box_rowspans
assert_equal :foo, box_rowspans( boxes)
end
def test_box_x_delimeters
assert_equal [4, 8], box_x_delimeters( boxes)
end
def test_box_y_delimeters
assert_equal [2, 4], box_y_delimeters( boxes)
end
def test_char
assert_equal :foo, char( boxes)
end
def test_render_html_table
# html = render_html_table(boxes)
# assert_equal :blah, html
assert_equal :foo, :blah, html( boxes)
end
def test_parse_ascii_table
table = "
---------------------------
| | | |
| | | |
| | | |
| |-------| |
| | | |
| | |-------|
| | | |
| | | |
|---------| |-------|
| | | | |
| | |-------| |
| | | | |
| | | | |
| | | | |
---------------------------
"
boxes = parse_ascii_table(table)
assert_equal :blah, boxes
end
end
|