From 9d7eff9d56fb6869ef84cffbd2c24a2cc8fe6fe6 Mon Sep 17 00:00:00 2001 From: Oleg Lupats Date: Thu, 11 Jun 2020 10:57:48 +0300 Subject: [PATCH] Relative links resolution --- pyxlsb2/formula.py | 13 +++++++++++-- pyxlsb2/ptgs.py | 16 +++++++++++----- pyxlsb2/workbook.py | 1 - test.py | 9 +++++---- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/pyxlsb2/formula.py b/pyxlsb2/formula.py index 7ad7bbc..2a13f92 100644 --- a/pyxlsb2/formula.py +++ b/pyxlsb2/formula.py @@ -1,3 +1,4 @@ +from .ptgs import NamePtg from .tokenreader import TokenReader @@ -11,10 +12,18 @@ def __repr__(self): def __str__(self): return self.stringify() - def stringify(self, workbook): + def stringify(self, workbook, row=None, col=None): tokens = self._tokens[:] - return tokens.pop().stringify(tokens, workbook) + current_token = tokens.pop() + if isinstance(current_token, NamePtg): + return current_token.stringify(tokens, workbook, row, col) + else: + return current_token.stringify(tokens, workbook) @classmethod def parse(cls, data): return cls(TokenReader(data)) + + @property + def tokens(self): + return self._tokens diff --git a/pyxlsb2/ptgs.py b/pyxlsb2/ptgs.py index 2901583..44852e8 100644 --- a/pyxlsb2/ptgs.py +++ b/pyxlsb2/ptgs.py @@ -1,3 +1,4 @@ +import re import sys from enum import Enum from . import recordtypes as rt @@ -26,9 +27,6 @@ def write(self, writer): pass - - - class ClassifiedPtg(BasePtg): def __init__(self, ptg, *args, **kwargs): super(ClassifiedPtg, self).__init__(*args, **kwargs) @@ -392,10 +390,18 @@ def __init__(self, idx, reserved, *args, **kwargs): self.idx = idx self._reserved = reserved - def stringify(self, tokens, workbook): + def stringify(self, tokens, workbook, row=None, col=None): defined = workbook.defined_names[workbook.list_names[self.idx - 1]] # return '%s (%s)' % (defined.name, defined.formula) - return defined.formula + formula = defined.formula + if row is not None and col is not None: + for link in re.findall(r'R\[?-?\d+\]?C\[?-?\d+\]?[,)\s]', formula): + address = re.match(r'R\[?-?\d+\]?C\[?-?\d+\]?', link).group() + p = address[1:].split('C') + r = int(p[0][1:-1]) + row + 1 if p[0].startswith('[') else row + 1 + c = ClassifiedPtg.convert_to_column_name(int(p[1][1:-1]) + col + 1 if p[1].startswith('[') else col + 1) + formula = formula.replace(link, link.replace(address, '%s%s' % (c, r))) + return formula @classmethod def read(cls, reader, ptg): diff --git a/pyxlsb2/workbook.py b/pyxlsb2/workbook.py index 96f34ea..06d7bcf 100644 --- a/pyxlsb2/workbook.py +++ b/pyxlsb2/workbook.py @@ -28,7 +28,6 @@ def __init__(self, pkg): self._pkg = pkg self._parse() - def __enter__(self): return self diff --git a/test.py b/test.py index c2d990f..35fce71 100644 --- a/test.py +++ b/test.py @@ -16,12 +16,13 @@ for row in sheet: for cell in row: formula_str = Formula.parse(cell.formula) - if formula_str._tokens: + if formula_str.tokens: try: - print(formula_str.stringify(wb)) + pass + print(formula_str.stringify(wb, cell.row_num, cell.col)) except NotImplementedError as exp: print('ERROR({}) {}'.format(exp, str(cell))) - except Exception: - print('ERROR ' + str(cell)) + except Exception as e: + print('ERROR ' + str(cell)) + ' (%s)' % e d = time.time() - a print('Done! ({} seconds)'.format(d))