| 1521 | |
| 1522 | |
| 1523 | class Table: |
| 1524 | def __init__(self, page, cells): |
| 1525 | self.page = page |
| 1526 | self.textpage = None |
| 1527 | self.cells = cells |
| 1528 | self.header = self._get_header() # PyMuPDF extension |
| 1529 | |
| 1530 | @property |
| 1531 | def bbox(self): |
| 1532 | c = self.cells |
| 1533 | return ( |
| 1534 | min(map(itemgetter(0), c)), |
| 1535 | min(map(itemgetter(1), c)), |
| 1536 | max(map(itemgetter(2), c)), |
| 1537 | max(map(itemgetter(3), c)), |
| 1538 | ) |
| 1539 | |
| 1540 | @property |
| 1541 | def rows(self) -> list: |
| 1542 | _sorted = sorted(self.cells, key=itemgetter(1, 0)) |
| 1543 | xs = list(sorted(set(map(itemgetter(0), self.cells)))) |
| 1544 | rows = [] |
| 1545 | for y, row_cells in itertools.groupby(_sorted, itemgetter(1)): |
| 1546 | xdict = {cell[0]: cell for cell in row_cells} |
| 1547 | row = TableRow([xdict.get(x) for x in xs]) |
| 1548 | rows.append(row) |
| 1549 | return rows |
| 1550 | |
| 1551 | @property |
| 1552 | def row_count(self) -> int: # PyMuPDF extension |
| 1553 | return len(self.rows) |
| 1554 | |
| 1555 | @property |
| 1556 | def col_count(self) -> int: # PyMuPDF extension |
| 1557 | return max([len(r.cells) for r in self.rows]) |
| 1558 | |
| 1559 | def extract(self, **kwargs) -> list: |
| 1560 | chars = CHARS |
| 1561 | table_arr = [] |
| 1562 | |
| 1563 | def char_in_bbox(char, bbox) -> bool: |
| 1564 | v_mid = (char["top"] + char["bottom"]) / 2 |
| 1565 | h_mid = (char["x0"] + char["x1"]) / 2 |
| 1566 | x0, top, x1, bottom = bbox |
| 1567 | return bool( |
| 1568 | (h_mid >= x0) and (h_mid < x1) and (v_mid >= top) and (v_mid < bottom) |
| 1569 | ) |
| 1570 | |
| 1571 | for row in self.rows: |
| 1572 | arr = [] |
| 1573 | row_chars = [char for char in chars if char_in_bbox(char, row.bbox)] |
| 1574 | |
| 1575 | for cell in row.cells: |
| 1576 | if cell is None: |
| 1577 | cell_text = None |
| 1578 | else: |
| 1579 | cell_chars = [ |
| 1580 | char for char in row_chars if char_in_bbox(char, cell) |
no outgoing calls
no test coverage detected
searching dependent graphs…