wordhelpers 0.1.4__tar.gz → 0.1.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wordhelpers
3
- Version: 0.1.4
3
+ Version: 0.1.6
4
4
  Summary: Helpers for working with python-docx
5
5
  Author: AJ Cruz
6
6
  Author-email: 15045766-a-cruz@users.noreply.gitlab.com
@@ -65,6 +65,7 @@ The WordTablesModel class has a number of methods available to help you build th
65
65
  - ```model_dump()```
66
66
  - ```pretty_print()```
67
67
  - ```write()```
68
+ - ```sort_rows_by_columns(primary_col: int, secondary_col: int | None = None, *, ascending: bool = True,)```
68
69
 
69
70
  If you prefer to create the tables manually via Python dictionary, the dictionary must follow a strict schema that looks something like this:
70
71
  ```python
@@ -49,6 +49,7 @@ The WordTablesModel class has a number of methods available to help you build th
49
49
  - ```model_dump()```
50
50
  - ```pretty_print()```
51
51
  - ```write()```
52
+ - ```sort_rows_by_columns(primary_col: int, secondary_col: int | None = None, *, ascending: bool = True,)```
52
53
 
53
54
  If you prefer to create the tables manually via Python dictionary, the dictionary must follow a strict schema that looks something like this:
54
55
  ```python
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "wordhelpers"
3
- version = "0.1.4"
3
+ version = "0.1.6"
4
4
  description = "Helpers for working with python-docx"
5
5
  authors = [
6
6
  {name = "AJ Cruz",email = "15045766-a-cruz@users.noreply.gitlab.com"}
@@ -97,17 +97,15 @@ def inject_table(
97
97
  # Locate the paragraph from the supplied placeholder text
98
98
  paragraph: Paragraph = get_para_by_string(doc_obj, placeholder)
99
99
  if not paragraph:
100
- raise ValueError(
101
- f'WARNING: Could not locate placeholder "{placeholder}"'
102
- )
100
+ raise ValueError(f'WARNING: Could not locate placeholder "{placeholder}"')
103
101
 
104
102
  # Build the word table and add it to the end of the document
105
103
  table = (
106
- build_table(
107
- doc_obj, table, remove_leading_para=remove_leading_para
108
- )
104
+ build_table(doc_obj, table, remove_leading_para=remove_leading_para)
109
105
  if isinstance(table, dict)
110
- else build_table(doc_obj, table.model_dump(), remove_leading_para=remove_leading_para)
106
+ else build_table(
107
+ doc_obj, table.model_dump(), remove_leading_para=remove_leading_para
108
+ )
111
109
  )
112
110
 
113
111
  # Move the Word table to a new paragraph immediately after the placeholder paragraph
@@ -107,7 +107,7 @@ class WordTableModel(BaseModel):
107
107
  if text:
108
108
  paragraphs = [
109
109
  WordParagraphModel(
110
- style=style, alignment=alignment, text=[text.pop(0)]
110
+ style=style, alignment=alignment, text=text.pop(0)
111
111
  )
112
112
  ]
113
113
  cells.append(
@@ -319,3 +319,56 @@ class WordTableModel(BaseModel):
319
319
  def write(self, filepath: str) -> None:
320
320
  with open(filepath, "w") as f:
321
321
  json.dump(self.model_dump(), f, indent=4)
322
+
323
+ def _row_text_at(self, row: WordRowModel, col_index: int) -> str:
324
+ if col_index >= len(row.cells):
325
+ return ""
326
+
327
+ cell = row.cells[col_index]
328
+
329
+ if isinstance(cell, str): # "merge"
330
+ return ""
331
+
332
+ if not cell.paragraphs:
333
+ return ""
334
+
335
+ paragraph = cell.paragraphs[0]
336
+ text = paragraph.text
337
+
338
+ if isinstance(text, list) and text:
339
+ return text[0].lower()
340
+
341
+ if isinstance(text, str):
342
+ return text.lower()
343
+
344
+ return ""
345
+
346
+ def sort_rows_by_columns(
347
+ self,
348
+ primary_col: int,
349
+ secondary_col: int | None = None,
350
+ *,
351
+ ascending: bool = True,
352
+ ) -> None:
353
+ if len(self.rows) <= 1:
354
+ return
355
+
356
+ header = self.rows[0]
357
+ body = self.rows[1:]
358
+
359
+ def sort_key(row: WordRowModel):
360
+ primary = self._row_text_at(row, primary_col)
361
+ secondary = (
362
+ self._row_text_at(row, secondary_col)
363
+ if secondary_col is not None
364
+ else ""
365
+ )
366
+ return (primary, secondary)
367
+
368
+ body_sorted = sorted(
369
+ body,
370
+ key=sort_key,
371
+ reverse=not ascending,
372
+ )
373
+
374
+ self.rows = [header] + body_sorted