~w-vollprecht/uberwriter/uberwriter_development

« back to all changes in this revision

Viewing changes to uberwriter/FixTable.py

  • Committer: Wolf Vollprecht
  • Date: 2012-11-09 10:45:13 UTC
  • Revision ID: w.vollprecht@gmail.com-20121109104513-xdz1fh4ugfzip7d1
added fixtable file

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import re
 
2
from gi.repository import Gtk
 
3
 
 
4
import logging
 
5
logger = logging.getLogger('uberwriter')
 
6
logger.critical("RASDAOD JKJD ASJD SJ")
 
7
 
 
8
class FixTable():
 
9
 
 
10
    def __init__(self, TextBuffer):
 
11
        self.TextBuffer = TextBuffer
 
12
 
 
13
    @staticmethod
 
14
    def create_seperator(widths, char):
 
15
        """
 
16
            Generate a line of + and - as sepeartor
 
17
 
 
18
            Example:
 
19
            >>> create_separarator([2, 4], '-')
 
20
            '+----+------+'
 
21
        """
 
22
        line = []
 
23
 
 
24
        for w in widths:
 
25
            line.append("+" + char * (w + 2))
 
26
 
 
27
        line.append("+")
 
28
        return ''.join(line)
 
29
 
 
30
    @staticmethod
 
31
    def create_line(columns, widths):
 
32
        """
 
33
            Crea una fila de la tabla separando los campos con un '|'.
 
34
 
 
35
            El argumento `columns` es una lista con las celdas que se
 
36
            quieren imprimir y el argumento `widths` tiene el ancho
 
37
            de cada columna. Si la columna es mas ancha que el texto
 
38
            a imprimir se agregan espacios vacíos.
 
39
 
 
40
            Example
 
41
                >>> create_line(['nombre', 'apellido'], [7, 10])
 
42
                '| nombre  | apellido   |'
 
43
        """
 
44
 
 
45
        line = zip(columns, widths)
 
46
        result = []
 
47
 
 
48
        for text, width in line:
 
49
            spaces = " " * (width - len(text))
 
50
            text = "| " + text + spaces + " "
 
51
            result.append(text)
 
52
 
 
53
        result.append("|")
 
54
        return ''.join(result)
 
55
 
 
56
    @staticmethod
 
57
    def create_table(content):
 
58
        """Imprime una tabla en formato restructuredText.
 
59
 
 
60
        El argumento `content` tiene que ser una lista
 
61
        de celdas.
 
62
 
 
63
        Example:
 
64
 
 
65
            >>> print create_table([['software', 'vesion'], ['python', '3.2'],
 
66
                ['vim', '7.3']])
 
67
+----------+--------+
 
68
| software | vesion |
 
69
+==========+========+
 
70
| python   | 3.2    |
 
71
+----------+--------+
 
72
| vim      | 7.3    |
 
73
+----------+--------+
 
74
        """
 
75
 
 
76
        # obtiene las columnas de toda la tabla.
 
77
        columns = zip(*content)
 
78
        # calcula el tamano maximo que debe tener cada columna.
 
79
        # replace with len()
 
80
        widths = [max([len(x) for x in i]) for i in columns]
 
81
 
 
82
        result = []
 
83
 
 
84
        result.append(FixTable.create_seperator(widths, '-'))
 
85
        print(content, widths)
 
86
        result.append(FixTable.create_line(content[0], widths))
 
87
        result.append(FixTable.create_seperator(widths, '='))
 
88
 
 
89
        for line in content[1:]:
 
90
            result.append(FixTable.create_line(line, widths))
 
91
            result.append(FixTable.create_seperator(widths, '-'))
 
92
 
 
93
        return '\n'.join(result)
 
94
 
 
95
    @staticmethod
 
96
    def are_in_a_table(current_line):
 
97
        "Line in a table?"
 
98
        return "|" in current_line or "+" in current_line
 
99
 
 
100
    @staticmethod
 
101
    def are_in_a_paragraph(current_line):
 
102
        "Line in a paragraph?"
 
103
        return len(current_line.strip()) >= 1
 
104
 
 
105
    def get_table_bounds(self, are_in_callback):
 
106
        """
 
107
            Gets the row number where the table begins and ends.
 
108
            are_in_callback argument must be a function
 
109
            indicating whether a particular line belongs or not
 
110
            to the table to be measured (or create).
 
111
            Returns two values ​​as a tuple
 
112
        """
 
113
        top = 0
 
114
 
 
115
        buf = self.TextBuffer
 
116
        start_iter = buf.get_start_iter()
 
117
        end_iter = buf.get_end_iter()
 
118
 
 
119
        text = self.TextBuffer.get_text(start_iter, end_iter, False).split('\n')
 
120
        logger.debug(text)
 
121
        length = len(text)
 
122
        bottom = length - 1
 
123
 
 
124
        insert_mark = self.TextBuffer.get_insert()
 
125
        insert_iter = self.TextBuffer.get_iter_at_mark(insert_mark)
 
126
        current_row_index = insert_iter.get_line()
 
127
 
 
128
        for a in range(current_row_index, top, -1):
 
129
            if not are_in_callback(text[a]):
 
130
                top = a + 1
 
131
                break
 
132
 
 
133
        for b in range(current_row_index, length):
 
134
            if not are_in_callback(text[b]):
 
135
                bottom = b - 1
 
136
                break
 
137
 
 
138
        return top, bottom
 
139
 
 
140
    @staticmethod
 
141
    def remove_spaces(string):
 
142
        """Remove unnecessary spaces"""
 
143
        return re.sub("\s\s+", " ", string)
 
144
 
 
145
    @staticmethod
 
146
    def create_separators_removing_spaces(string):
 
147
        return re.sub("\s\s+", "|", string)
 
148
 
 
149
    @staticmethod
 
150
    def extract_cells_as_list(string):
 
151
        "Extrae el texto de una fila de tabla y lo retorna como una lista."
 
152
        string = FixTable.remove_spaces(string)
 
153
        return [item.strip() for item in string.split('|') if item]
 
154
 
 
155
    @staticmethod
 
156
    def extract_table(text, top, bottom):
 
157
        full_table_text = text[top:bottom]
 
158
        # selecciona solamente las lineas que tienen celdas con texto.
 
159
        only_text_lines = [x for x in full_table_text if '|' in x]
 
160
        # extrae las celdas y descarta los separadores innecesarios.
 
161
        return [FixTable.extract_cells_as_list(x) for x in only_text_lines]
 
162
 
 
163
    @staticmethod
 
164
    def extract_words_as_lists(text, top, bottom):
 
165
        "Genera una lista de palabras para crear una lista."
 
166
 
 
167
        lines = text[top:bottom + 1]
 
168
        return [FixTable.create_separators_removing_spaces(line).split('|') for line in lines]
 
169
 
 
170
    def fix_table(self):
 
171
        """
 
172
            Fix Table, so all columns have the same width (again)
 
173
 
 
174
            `initial_row` is a int idicationg the current row index
 
175
        """
 
176
 
 
177
        cursor_mark = self.TextBuffer.get_insert()
 
178
        cursor_iter = self.TextBuffer.get_iter_at_mark(cursor_mark)
 
179
        cursor_iter.set_line(cursor_iter.get_line())
 
180
 
 
181
        end_line = cursor_iter.copy()
 
182
        end_line.forward_to_line_end()
 
183
 
 
184
 
 
185
        line_text = self.TextBuffer.get_text(cursor_iter, end_line, False)
 
186
        if FixTable.are_in_a_table(line_text):
 
187
 
 
188
            # obtiene el indice donde comienza y termina la tabla.
 
189
            r1, r2 = self.get_table_bounds(FixTable.are_in_a_table)
 
190
 
 
191
            logger.debug('asdasd ')
 
192
 
 
193
            # extrae de la tabla solo las celdas de texto
 
194
            buf = self.TextBuffer
 
195
            start_iter = buf.get_start_iter()
 
196
            end_iter = buf.get_end_iter()
 
197
 
 
198
            text = self.TextBuffer.get_text(start_iter, end_iter, False).split('\n')
 
199
 
 
200
            table_as_list = FixTable.extract_table(text, r1, r2)
 
201
            logger.debug(table_as_list)
 
202
            # genera una nueva tabla tipo restructured text y la dibuja en el buffer.
 
203
            table_content = FixTable.create_table(table_as_list)
 
204
            logger.debug(table_content)
 
205
            # Insert table back into Buffer ... 
 
206
            self.TextBuffer.insert(start_iter, table_content, -1)
 
207
        else:
 
208
            logger.debug("Not in a table")
 
209
            print("Not in table")