Moved stringify cruft into a render module.
[pseudoku.git] / pseudoku / render / __init__.py
1 from ..grid import symbols
2
3 class GridRenderer(object):
4 """Class that renders a grid in some human-consumable form.
5
6 This base class's methods result in a flat string of symbols, but it's easy
7 to create a more useful rendering by just overriding a few methods.
8 """
9
10 def render_grid(self, grid):
11 """Renders the entire grid. Code on the outside probably only needs to
12 call this.
13
14 Returns a string.
15 """
16 parts = []
17
18 parts.append(self.before_grid(grid))
19 for idx, row in enumerate(grid._rows):
20 if idx and idx % grid._box_height == 0:
21 parts.append(self.inside_grid(grid))
22 parts.append(self.render_row(row))
23 parts.append(self.after_grid(grid))
24
25 return ''.join(parts)
26
27 def render_row(self, row):
28 """Renders a single row."""
29 parts = []
30
31 parts.append(self.before_row(row))
32 for idx, cell in enumerate(row.cells):
33 if idx and idx % row._grid._box_width == 0:
34 parts.append(self.inside_row(row))
35 parts.extend(self.render_cell(cell))
36 parts.append(self.after_row(row))
37
38 return ''.join(parts)
39
40 def render_cell(self, cell):
41 """Renders a single cell."""
42 return ''.join([
43 self.before_cell(cell),
44 self.inside_cell(cell),
45 self.after_cell(cell),
46 ])
47
48
49 def before_grid(self, grid):
50 """Content prepended before the entire grid."""
51 return self.inside_grid(grid)
52
53 def inside_grid(self, grid):
54 """Content inserted within the grid, between boxes."""
55 return ''
56
57 def after_grid(self, grid):
58 """Content appended after the entire grid."""
59 return self.inside_grid(grid)
60
61
62 def before_row(self, row):
63 """Content prepended before each row."""
64 return self.inside_row(row)
65
66 def inside_row(self, row):
67 """Content inserted within each row, between boxes."""
68 return ''
69
70 def after_row(self, row):
71 """Content appended after each row.
72
73 Note that newlines are not assumed; you must provide one if you want
74 one included in the rendering.
75 """
76
77 return self.inside_row(row)
78
79
80 def before_cell(self, cell):
81 """Content prepended before each cell in a row."""
82 return ''
83
84 def inside_cell(self, cell):
85 """Content used to represent the actual cell value."""
86 if cell.value:
87 return symbols[cell.value]
88 else:
89 return '.'
90
91 def after_cell(self, cell):
92 """Content appended after each row in a cell."""
93 return ''
94