From b5e1e0d50ba28ea831ce6ba3e8a98ed34964675f Mon Sep 17 00:00:00 2001 From: Philippe Le Van Date: Thu, 11 Apr 2024 15:41:44 +0200 Subject: [PATCH] v1.6.0 : var inside header or footer --- .gitignore | 1 + README.md | 5 ++- lotemplate/Statement/TextStatement.py | 28 ++++++++++++---- .../content/text_var_in_header.expected.txt | 3 ++ .../files/content/text_var_in_header.json | 6 ++++ .../files/content/text_var_in_header.odt | Bin 0 -> 13065 bytes .../files/templates/text_var_in_header.odt | Bin 0 -> 12056 bytes lotemplate/unittest/test_content.py | 31 ++++++++++++++---- lotemplate/unittest/test_template_scan.py | 7 ++++ requirements.txt | 1 + 10 files changed, 68 insertions(+), 14 deletions(-) create mode 100644 lotemplate/unittest/files/content/text_var_in_header.expected.txt create mode 100644 lotemplate/unittest/files/content/text_var_in_header.json create mode 100644 lotemplate/unittest/files/content/text_var_in_header.odt create mode 100644 lotemplate/unittest/files/templates/text_var_in_header.odt diff --git a/.gitignore b/.gitignore index bd454da..348bdd0 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ exports/ /lotemplate/unittest/files/content/debug.odt /lotemplate/unittest/files/content/debug.json /lotemplate/unittest/files/content/*.unittest.odt +/lotemplate/unittest/files/content/*.unittest.pdf /venv /output*.* .fontconfig/ diff --git a/README.md b/README.md index b0ba95f..a5d7dc7 100644 --- a/README.md +++ b/README.md @@ -839,7 +839,10 @@ For trying to fix these problems, you can try: Versions ------------------------------- - +- v1.6.0 : 2024-04-11 + - allow put variables inside headers and footers + - fix a bug when a variable is both inside the text content and inside a table (it should not arrive, but it is fixed) + - a new unit test system based on PDF converted to text in order to test contents that are not converted to text with a simple saveAs - v1.5.2 : 2024-02-24 : Better README - Rewrite for a betterdocker DockerFile without bug - v1.5.1 : 2024-02-16 : Better README diff --git a/lotemplate/Statement/TextStatement.py b/lotemplate/Statement/TextStatement.py index 10093b1..1dfd9f0 100644 --- a/lotemplate/Statement/TextStatement.py +++ b/lotemplate/Statement/TextStatement.py @@ -7,7 +7,8 @@ class TextStatement: - text_regex = regex.compile(r'\$(\w+(\(((?:\\.|.)*?)\))?)') + text_regex_as_string = r'\$(\w+(\(((?:\\.|.)*?)\))?)' + text_regex = regex.compile(text_regex_as_string) def __init__(self, text_string): self.text_string = text_string @@ -19,11 +20,21 @@ def scan_text(doc: XComponent) -> dict[str, dict[str, str]]: :return: the scanned variables """ - raw_string = doc.getText().getString() - matches = TextStatement.text_regex.finditer(raw_string) + search = doc.createSearchDescriptor() + search.SearchString = TextStatement.text_regex_as_string + search.SearchRegularExpression = True + search.SearchCaseSensitive = False + founded = doc.findAll(search) + + simple_var_list = [] + for x_found in founded: + text = x_found.getText() + cursor = text.createTextCursorByRange(x_found) + simple_var_list.append(cursor.String) + plain_vars = {} - for var in matches: - key_name = var[0][1:] + for var in simple_var_list: + key_name = var[1:] # add to plain_vars if it doesn't matche ForStatement.foritem_regex if not re.search(ForStatement.forindex_regex, key_name, re.IGNORECASE): plain_vars[key_name] = {'type': 'text', 'value': ''} @@ -38,8 +49,11 @@ def scan_text(doc: XComponent) -> dict[str, dict[str, str]]: text_fields_vars = (text_fields_vars | {var.group(0)[1:]: {'type': 'text', 'value': ''} for var in matches}) - for var in TableStatement.scan_table(doc, get_list=True): - if '$' + var in plain_vars: + table_var_list = TableStatement.scan_table(doc, get_list=True) + for var in table_var_list: + if var.startswith("$"): + var = var[1:] + if var in plain_vars: del plain_vars[var] for var in ForStatement.scan_for(doc): diff --git a/lotemplate/unittest/files/content/text_var_in_header.expected.txt b/lotemplate/unittest/files/content/text_var_in_header.expected.txt new file mode 100644 index 0000000..879eaa6 --- /dev/null +++ b/lotemplate/unittest/files/content/text_var_in_header.expected.txt @@ -0,0 +1,3 @@ +Can we change the following var my replaced text in the header ? +This document test the replacement of a variable in the header. +And in the footer the var “my replaced text” is still ther diff --git a/lotemplate/unittest/files/content/text_var_in_header.json b/lotemplate/unittest/files/content/text_var_in_header.json new file mode 100644 index 0000000..b8cff19 --- /dev/null +++ b/lotemplate/unittest/files/content/text_var_in_header.json @@ -0,0 +1,6 @@ +{ + "my_var": { + "type": "text", + "value": "my replaced text" + } +} \ No newline at end of file diff --git a/lotemplate/unittest/files/content/text_var_in_header.odt b/lotemplate/unittest/files/content/text_var_in_header.odt new file mode 100644 index 0000000000000000000000000000000000000000..664802c29774846ab70e73b3fea717713a5d1d05 GIT binary patch literal 13065 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 Sm)j7ZKL*c>P73+U)&By79kTua literal 0 HcmV?d00001 diff --git a/lotemplate/unittest/test_content.py b/lotemplate/unittest/test_content.py index 45cf5ca..51e0de2 100644 --- a/lotemplate/unittest/test_content.py +++ b/lotemplate/unittest/test_content.py @@ -10,6 +10,7 @@ import lotemplate as ot from time import sleep import subprocess +from pypdf import PdfReader subprocess.call(f'soffice "--accept=socket,host=localhost,port=2002;urp;StarOffice.ServiceManager" &', shell=True) sleep(2) @@ -28,7 +29,10 @@ def to_data(file: str): return ot.convert_to_datas_template(file_to_dict(file)) -def compare_files(name: str): +def compare_files(name: str, format: str = 'txt'): + if format not in ['txt', 'pdf']: + return False + base_path = 'lotemplate/unittest/files/content' def get_filename(ext: str): @@ -50,17 +54,29 @@ def get_filename(ext: str): temp.search_error(to_data(get_filename('json'))) temp.fill(file_to_dict(get_filename('json'))) - if os.path.isfile(get_filename('unittest.txt')): - os.remove(get_filename('unittest.txt')) - temp.export(get_filename('unittest.txt'), True) + if os.path.isfile(get_filename('unittest.'+format)): + os.remove(get_filename('unittest.'+format)) + temp.export(get_filename('unittest.'+format), True) # temp.close() if os.path.isfile(get_filename('unittest.odt')): os.remove(get_filename('unittest.odt')) temp.export(get_filename('unittest.odt'), True) temp.close() + + # The PDF format is used to test some documents with headers or footers that are not supported by the text saveAs from + # LibreOffice. The PDF is then converted to text to compare with the expected text. + if format == 'pdf': + # convert to text + reader = PdfReader(get_filename('unittest.pdf')) + text = "" + for page in reader.pages: + text += page.extract_text() + "\n" + if os.path.isfile(get_filename('unittest.txt')): + os.remove(get_filename('unittest.txt')) + with open(get_filename('unittest.txt'), 'w') as f: + f.write(text) + response = filecmp.cmp(get_filename('unittest.txt'), get_filename('expected.txt')) - # if os.path.isfile(get_filename('unittest.txt')): - # os.remove(get_filename('unittest.txt')) return response @@ -112,5 +128,8 @@ def test_image(self): def test_counter(self): self.assertTrue(compare_files('counter')) + def test_text_var_in_header(self): + self.assertTrue(compare_files('text_var_in_header', 'pdf')) + def test_debug(self): self.assertTrue(compare_files('debug')) diff --git a/lotemplate/unittest/test_template_scan.py b/lotemplate/unittest/test_template_scan.py index 322f18a..f8e2172 100644 --- a/lotemplate/unittest/test_template_scan.py +++ b/lotemplate/unittest/test_template_scan.py @@ -40,6 +40,13 @@ def test_format(self): (doc := ot.Template("lotemplate/unittest/files/templates/text_vars.odt", cnx, False)).scan()) doc.close() + def test_text_var_in_header(self): + self.assertEqual( + {"my_var": {"type": "text", "value": ""}}, + (doc := ot.Template("lotemplate/unittest/files/templates/text_var_in_header.odt", cnx, False)).scan() + ) + doc.close() + def test_static_table(self): self.assertEqual( {"var1": {"type": "text", "value": ""}, "var2": {"type": "text", "value": ""}}, diff --git a/requirements.txt b/requirements.txt index 339000a..d38e4bc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,4 @@ gunicorn~=20.1.0 Werkzeug~=2.2.2 sorcery~=0.2.1 regex~=2022.10.31 +pypdf~=4.2.0 \ No newline at end of file