forked from vkocubinsky/SublimeTableEditor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
table_line_parser.py
123 lines (89 loc) · 3.82 KB
/
table_line_parser.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# table_line_parser.py - Parse one line in a table.
# Copyright (C) 2012 Free Software Foundation, Inc.
# Author: Valery Kocubinsky
# Package: SublimeTableEditor
# Homepage: https://github.com/vkocubinsky/SublimeTableEditor
# This file is part of SublimeTableEditor.
# SublimeTableEditor is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# SublimeTableEditor is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with SublimeTableEditor. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
from __future__ import division
import re
class LineRegion:
def __init__(self, begin, end):
self.begin = begin
self.end = end
def __repr__(self):
return "LineRegion(begin={0.begin}, end={0.end})".format(self)
def __str__(self):
return self.__repr__()
class LineCell:
def __init__(self, line_text, left_border, right_border):
self.cell_region = LineRegion(left_border.end, right_border.begin)
self.left_border = left_border
self.right_border = right_border
self.text = line_text[self.cell_region.begin:self.cell_region.end]
if self.right_border.begin == self.right_border.end:
self.right_border_text = '|'
else:
self.right_border_text = line_text[self.right_border.begin:self.right_border.end]
self.left_border_text = line_text[self.left_border.begin:self.left_border.end]
class Line:
def __init__(self):
self.cells = []
self.prefix = ""
def str_cols(self):
return [cell.text for cell in self.cells]
def field_num(self, pos):
for ind, cell in enumerate(self.cells):
if cell.right_border.end > pos:
return ind
else:
return len(self.cells) - 1
class LineParser:
def __init__(self, border_pattern):
self.border_pattern = border_pattern
def parse(self, line_text):
line = Line()
mo = re.search(r"[^\s]", line_text)
if mo:
line.prefix = line_text[:mo.start()]
else:
line.prefix = ""
borders = []
last_border_end = 0
for m in re.finditer(self.border_pattern, line_text):
borders.append(LineRegion(m.start(), m.end()))
last_border_end = m.end()
if last_border_end < len(line_text.rstrip()):
borders.append(LineRegion(len(line_text), len(line_text)))
left_border = None
for right_border in borders:
if left_border is None:
left_border = right_border
else:
line.cells.append(LineCell(line_text, left_border, right_border))
left_border = right_border
return line
class LineParserPlus:
def __init__(self, border_pattern):
self.plus_line_parser = LineParser("(?:[+|])")
self.plus_line_pattern = re.compile("^\s*[+]")
self.single_hline_pattern = re.compile('^\s*[|+]\s*-[\s|+-]+$')
self.double_hline_pattern = re.compile('^\s*[|+]\s*=[\s|+=]+$')
self.data_line_parser = LineParser(border_pattern)
def parse(self, line_text):
if (self.single_hline_pattern.match(line_text) or
self.double_hline_pattern.match(line_text) or
self.plus_line_pattern.match(line_text)):
return self.plus_line_parser.parse(line_text)
else:
return self.data_line_parser.parse(line_text)