tesorotools-python 0.0.39__tar.gz → 0.0.41__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.
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/PKG-INFO +1 -1
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/pyproject.toml +1 -1
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/assets/plots.yaml +3 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/content/table.py +148 -55
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/.gitignore +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/__init__.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/_build_context.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/_registry.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/artists/__init__.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/artists/_common.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/artists/barh_plot.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/artists/line_plot.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/artists/stacked.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/artists/type_curve.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/assets/README.md +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/assets/fonts/CabinetGrotesk-Black.otf +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/assets/fonts/CabinetGrotesk-Bold.otf +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/assets/fonts/CabinetGrotesk-Extrabold.otf +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/assets/fonts/CabinetGrotesk-Extralight.otf +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/assets/fonts/CabinetGrotesk-Light.otf +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/assets/fonts/CabinetGrotesk-Medium.otf +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/assets/fonts/CabinetGrotesk-Regular.otf +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/assets/fonts/CabinetGrotesk-Thin.otf +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/assets/fonts/README.md +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/assets/tesoro.mplstyle +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/data_sources/__init__.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/data_sources/debug.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/database/__init__.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/database/local.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/database/push.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/database/shared.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/dependencies/__init__.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/dependencies/node.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/dependencies/resolution.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/driver.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/manifest.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/offsets/__init__.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/offsets/offsets.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/offsets/outliers.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/orchestration.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/pipeline/__init__.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/pipeline/diagnose.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/pipeline/engine.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/pipeline/rules.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/providers/__init__.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/providers/base.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/providers/bde.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/providers/ecb.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/py.typed +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/__init__.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/content/__init__.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/content/content.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/content/images.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/content/section.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/content/subtitle.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/content/text.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/content/title.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/report.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/testing/__init__.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/testing/compare.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/utils/__init__.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/utils/config.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/utils/format.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/utils/globals.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/utils/matplotlib.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/utils/series.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/utils/shortcuts.py +0 -0
- {tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/utils/template.py +0 -0
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/content/table.py
RENAMED
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
# pyright: reportPrivateUsage=false
|
|
4
4
|
from dataclasses import dataclass
|
|
5
5
|
from pathlib import Path
|
|
6
|
-
from typing import Any, Self
|
|
6
|
+
from typing import Any, Self, TypedDict
|
|
7
7
|
|
|
8
8
|
import numpy as np
|
|
9
9
|
import pandas as pd
|
|
@@ -15,6 +15,7 @@ from docx.oxml.ns import nsdecls, qn
|
|
|
15
15
|
from docx.shared import Inches, Pt, RGBColor
|
|
16
16
|
from docx.table import Table as TableDocx
|
|
17
17
|
from docx.table import _Cell as TableCell
|
|
18
|
+
from docx.table import _Row as TableRow
|
|
18
19
|
from yaml import MappingNode
|
|
19
20
|
|
|
20
21
|
from tesorotools.utils.config import read_config
|
|
@@ -24,6 +25,35 @@ from tesorotools.utils.template import TemplateLoader
|
|
|
24
25
|
RENDER_CONFIG: dict[str, Any] = read_config(PLOT_CONFIG_FILE)["table"]
|
|
25
26
|
|
|
26
27
|
|
|
28
|
+
class BlockSeparatorConfig(TypedDict, total=False):
|
|
29
|
+
"""User-facing visual config for the inter-block separator band.
|
|
30
|
+
|
|
31
|
+
The band is rendered as **two adjacent rows** sharing the same
|
|
32
|
+
fill, so the pair shifts Word's automatic banding count by an
|
|
33
|
+
even number (preserving alternation in data rows below). Both
|
|
34
|
+
keys are optional; missing keys fall back to defaults.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
fill: str
|
|
38
|
+
"""Hex color of the band, without leading ``#``. Default ``BFBFBF``."""
|
|
39
|
+
|
|
40
|
+
height_twips: int
|
|
41
|
+
"""Height of *each* of the two rows. Total band height is
|
|
42
|
+
``2 * height_twips``. Default ``20`` (1pt per row, 2pt total)."""
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class _ResolvedSeparator(TypedDict):
|
|
46
|
+
"""Internal, fully-resolved variant of :class:`BlockSeparatorConfig`.
|
|
47
|
+
|
|
48
|
+
After defaults are merged in, every field is guaranteed present —
|
|
49
|
+
this lets call sites index without ``.get()`` and silences
|
|
50
|
+
pyright's NotRequired warnings.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
fill: str
|
|
54
|
+
height_twips: int
|
|
55
|
+
|
|
56
|
+
|
|
27
57
|
@dataclass(frozen=True)
|
|
28
58
|
class RenderConfig:
|
|
29
59
|
"""Per-call rendering options for :func:`render_table`.
|
|
@@ -35,12 +65,18 @@ class RenderConfig:
|
|
|
35
65
|
|
|
36
66
|
style: str | None = None
|
|
37
67
|
autofit: bool = False
|
|
68
|
+
block_separator: BlockSeparatorConfig | None = None
|
|
38
69
|
|
|
39
70
|
@classmethod
|
|
40
71
|
def from_global(cls) -> RenderConfig:
|
|
72
|
+
sep_raw: Any = RENDER_CONFIG.get("block_separator")
|
|
73
|
+
block_separator: BlockSeparatorConfig | None = (
|
|
74
|
+
None if sep_raw is None else BlockSeparatorConfig(**sep_raw)
|
|
75
|
+
)
|
|
41
76
|
return cls(
|
|
42
77
|
style=RENDER_CONFIG.get("style"),
|
|
43
78
|
autofit=bool(RENDER_CONFIG["autofit"]),
|
|
79
|
+
block_separator=block_separator,
|
|
44
80
|
)
|
|
45
81
|
|
|
46
82
|
|
|
@@ -49,46 +85,6 @@ TEXTO_TABLAS: int = 9
|
|
|
49
85
|
CENTER = WD_ALIGN_PARAGRAPH.CENTER
|
|
50
86
|
|
|
51
87
|
|
|
52
|
-
def _set_cell_border(cell: TableCell, **kwargs: Any) -> None:
|
|
53
|
-
"""
|
|
54
|
-
Set cell`s border
|
|
55
|
-
Usage:
|
|
56
|
-
|
|
57
|
-
set_cell_border(
|
|
58
|
-
cell,
|
|
59
|
-
top={"sz": 12, "val": "single", "color": "#FF0000", "space": "0"},
|
|
60
|
-
bottom={"sz": 12, "color": "#00FF00", "val": "single"},
|
|
61
|
-
start={"sz": 24, "val": "dashed", "shadow": "true"},
|
|
62
|
-
end={"sz": 12, "val": "dashed"},
|
|
63
|
-
)
|
|
64
|
-
"""
|
|
65
|
-
tc = cell._tc
|
|
66
|
-
tcPr = tc.get_or_add_tcPr()
|
|
67
|
-
|
|
68
|
-
# check for tag existence, if none found, create one
|
|
69
|
-
tcBorders: Any = tcPr.first_child_found_in("w:tcBorders") # type: ignore[reportUnknownMemberType]
|
|
70
|
-
if tcBorders is None:
|
|
71
|
-
tcBorders = OxmlElement("w:tcBorders") # type: ignore[reportUnknownVariableType]
|
|
72
|
-
tcPr.append(tcBorders) # type: ignore[reportUnknownMemberType]
|
|
73
|
-
|
|
74
|
-
# list over all available tags
|
|
75
|
-
for edge in ("start", "top", "end", "bottom", "insideH", "insideV"):
|
|
76
|
-
edge_data: Any = kwargs.get(edge)
|
|
77
|
-
if edge_data:
|
|
78
|
-
tag = "w:{}".format(edge)
|
|
79
|
-
|
|
80
|
-
# check for tag existence, if none found, then create one
|
|
81
|
-
element: Any = tcBorders.find(qn(tag)) # type: ignore[reportUnknownMemberType]
|
|
82
|
-
if element is None:
|
|
83
|
-
element = OxmlElement(tag) # type: ignore[reportUnknownVariableType]
|
|
84
|
-
tcBorders.append(element) # type: ignore[reportUnknownMemberType]
|
|
85
|
-
|
|
86
|
-
# looks like order of attributes is important
|
|
87
|
-
for key in ["sz", "val", "color", "space", "shadow"]:
|
|
88
|
-
if key in edge_data:
|
|
89
|
-
element.set(qn("w:{}".format(key)), str(edge_data[key])) # type: ignore[reportUnknownMemberType]
|
|
90
|
-
|
|
91
|
-
|
|
92
88
|
def _style_horizontal_blocks_header(cell: TableCell) -> None:
|
|
93
89
|
cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
94
90
|
cell.paragraphs[0].runs[0].font.size = Pt(12)
|
|
@@ -181,36 +177,125 @@ def _fill_index_names(
|
|
|
181
177
|
_style_index_names(cell)
|
|
182
178
|
|
|
183
179
|
|
|
180
|
+
_DEFAULT_SEPARATOR: _ResolvedSeparator = {
|
|
181
|
+
"fill": "BFBFBF",
|
|
182
|
+
"height_twips": 20,
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
|
|
184
186
|
# we only separate blocks in vertically stacked tables
|
|
185
187
|
def _separate_blocks(
|
|
186
188
|
index: pd.Index[Any] | pd.MultiIndex,
|
|
187
189
|
table_docx: TableDocx,
|
|
190
|
+
*,
|
|
191
|
+
horizontal: bool,
|
|
192
|
+
config: BlockSeparatorConfig | None = None,
|
|
188
193
|
) -> None:
|
|
194
|
+
"""Insert two adjacent separator rows after every block boundary.
|
|
195
|
+
|
|
196
|
+
Each separator is one merged cell (``<w:gridSpan>`` covering all
|
|
197
|
+
columns) with exact-height ``<w:trHeight>`` and a solid ``<w:shd>``
|
|
198
|
+
fill. Two adjacent rows with identical fill render as a single
|
|
199
|
+
seamless band; their pair shifts Word's automatic banding count by
|
|
200
|
+
an even number, preserving the alternation in the data rows below.
|
|
201
|
+
|
|
202
|
+
The cnfStyle approach this replaces was OOXML-valid but Word
|
|
203
|
+
treated ``<w:cnfStyle>`` as descriptive bookkeeping rather than as
|
|
204
|
+
an override directive — the conditional formatting was never
|
|
205
|
+
applied. See README "Block separators" for the postmortem.
|
|
206
|
+
"""
|
|
189
207
|
if not isinstance(index, pd.MultiIndex):
|
|
190
208
|
raise ValueError(
|
|
191
209
|
"block_sep=True requires the row index to be a MultiIndex; "
|
|
192
210
|
"got a flat Index. Set block_sep=False or wrap rows in a "
|
|
193
211
|
"MultiIndex with the block name as level 0."
|
|
194
212
|
)
|
|
213
|
+
cfg: _ResolvedSeparator = {**_DEFAULT_SEPARATOR, **(config or {})}
|
|
214
|
+
num_cols: int = len(table_docx.columns)
|
|
215
|
+
grid_total: int = _grid_total_twips(table_docx)
|
|
216
|
+
header_rows: int = 2 if horizontal else 1
|
|
195
217
|
blocks: list[str] = list(index.get_level_values(level=0).unique())
|
|
196
218
|
previous_rows: int = 0
|
|
219
|
+
inserted: int = 0
|
|
197
220
|
for block in blocks[:-1]:
|
|
198
221
|
block_size: int = len(index[index.get_level_values(level=0) == block])
|
|
199
|
-
|
|
200
|
-
|
|
222
|
+
anchor_idx: int = (
|
|
223
|
+
header_rows + previous_rows + block_size - 1 + inserted
|
|
224
|
+
)
|
|
225
|
+
anchor: TableRow = table_docx.rows[anchor_idx]
|
|
226
|
+
_insert_double_separator(anchor, num_cols, grid_total, cfg)
|
|
201
227
|
previous_rows += block_size
|
|
228
|
+
inserted += 2
|
|
202
229
|
|
|
203
230
|
|
|
204
|
-
def
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
231
|
+
def _grid_total_twips(table_docx: TableDocx) -> int:
|
|
232
|
+
"""Sum the widths of every ``<w:gridCol>`` under ``<w:tblGrid>``."""
|
|
233
|
+
tblGrid: Any = table_docx._element.find(qn("w:tblGrid")) # type: ignore[reportUnknownMemberType]
|
|
234
|
+
cols: Any = tblGrid.findall(qn("w:gridCol")) # type: ignore[reportUnknownMemberType]
|
|
235
|
+
return sum(int(gc.get(qn("w:w"))) for gc in cols) # type: ignore[reportUnknownArgumentType, reportUnknownVariableType]
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def _insert_double_separator(
|
|
239
|
+
anchor_row: TableRow,
|
|
240
|
+
num_cols: int,
|
|
241
|
+
grid_total_twips: int,
|
|
242
|
+
cfg: _ResolvedSeparator,
|
|
243
|
+
) -> None:
|
|
244
|
+
sep1: Any = _build_separator_row(num_cols, grid_total_twips, cfg)
|
|
245
|
+
sep2: Any = _build_separator_row(num_cols, grid_total_twips, cfg)
|
|
246
|
+
# Insert sep2 first, then sep1 in front of sep2 — both end up after
|
|
247
|
+
# anchor_row in document order (anchor → sep1 → sep2 → next data row).
|
|
248
|
+
anchor_row._tr.addnext(sep2) # type: ignore[reportUnknownMemberType]
|
|
249
|
+
anchor_row._tr.addnext(sep1) # type: ignore[reportUnknownMemberType]
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def _build_separator_row(
|
|
253
|
+
num_cols: int, grid_total_twips: int, cfg: _ResolvedSeparator
|
|
254
|
+
) -> Any:
|
|
255
|
+
fill: str = cfg["fill"]
|
|
256
|
+
height_twips: int = cfg["height_twips"]
|
|
257
|
+
|
|
258
|
+
tr: Any = OxmlElement("w:tr") # type: ignore[reportUnknownVariableType]
|
|
259
|
+
|
|
260
|
+
trPr: Any = OxmlElement("w:trPr") # type: ignore[reportUnknownVariableType]
|
|
261
|
+
trHeight: Any = OxmlElement("w:trHeight") # type: ignore[reportUnknownVariableType]
|
|
262
|
+
trHeight.set(qn("w:val"), str(height_twips)) # type: ignore[reportUnknownMemberType]
|
|
263
|
+
trHeight.set(qn("w:hRule"), "exact") # type: ignore[reportUnknownMemberType]
|
|
264
|
+
trPr.append(trHeight) # type: ignore[reportUnknownMemberType]
|
|
265
|
+
tr.append(trPr) # type: ignore[reportUnknownMemberType]
|
|
266
|
+
|
|
267
|
+
tc: Any = OxmlElement("w:tc") # type: ignore[reportUnknownVariableType]
|
|
268
|
+
tcPr: Any = OxmlElement("w:tcPr") # type: ignore[reportUnknownVariableType]
|
|
269
|
+
tcW: Any = OxmlElement("w:tcW") # type: ignore[reportUnknownVariableType]
|
|
270
|
+
tcW.set(qn("w:w"), str(grid_total_twips)) # type: ignore[reportUnknownMemberType]
|
|
271
|
+
tcW.set(qn("w:type"), "dxa") # type: ignore[reportUnknownMemberType]
|
|
272
|
+
tcPr.append(tcW) # type: ignore[reportUnknownMemberType]
|
|
273
|
+
gridSpan: Any = OxmlElement("w:gridSpan") # type: ignore[reportUnknownVariableType]
|
|
274
|
+
gridSpan.set(qn("w:val"), str(num_cols)) # type: ignore[reportUnknownMemberType]
|
|
275
|
+
tcPr.append(gridSpan) # type: ignore[reportUnknownMemberType]
|
|
276
|
+
shd: Any = OxmlElement("w:shd") # type: ignore[reportUnknownVariableType]
|
|
277
|
+
shd.set(qn("w:val"), "clear") # type: ignore[reportUnknownMemberType]
|
|
278
|
+
shd.set(qn("w:color"), "auto") # type: ignore[reportUnknownMemberType]
|
|
279
|
+
shd.set(qn("w:fill"), fill) # type: ignore[reportUnknownMemberType]
|
|
280
|
+
tcPr.append(shd) # type: ignore[reportUnknownMemberType]
|
|
281
|
+
tc.append(tcPr) # type: ignore[reportUnknownMemberType]
|
|
282
|
+
|
|
283
|
+
# OOXML requires <w:tc> to contain at least one block-level element.
|
|
284
|
+
# The inner paragraph carries exact line spacing so Word does not
|
|
285
|
+
# inflate the row past the configured trHeight on screen.
|
|
286
|
+
p: Any = OxmlElement("w:p") # type: ignore[reportUnknownVariableType]
|
|
287
|
+
pPr: Any = OxmlElement("w:pPr") # type: ignore[reportUnknownVariableType]
|
|
288
|
+
spacing: Any = OxmlElement("w:spacing") # type: ignore[reportUnknownVariableType]
|
|
289
|
+
spacing.set(qn("w:before"), "0") # type: ignore[reportUnknownMemberType]
|
|
290
|
+
spacing.set(qn("w:after"), "0") # type: ignore[reportUnknownMemberType]
|
|
291
|
+
spacing.set(qn("w:line"), str(height_twips)) # type: ignore[reportUnknownMemberType]
|
|
292
|
+
spacing.set(qn("w:lineRule"), "exact") # type: ignore[reportUnknownMemberType]
|
|
293
|
+
pPr.append(spacing) # type: ignore[reportUnknownMemberType]
|
|
294
|
+
p.append(pPr) # type: ignore[reportUnknownMemberType]
|
|
295
|
+
tc.append(p) # type: ignore[reportUnknownMemberType]
|
|
296
|
+
|
|
297
|
+
tr.append(tc) # type: ignore[reportUnknownMemberType]
|
|
298
|
+
return tr # type: ignore[reportUnknownVariableType]
|
|
214
299
|
|
|
215
300
|
|
|
216
301
|
def _is_bright(hex_color: str) -> bool:
|
|
@@ -313,9 +398,17 @@ def render_table(
|
|
|
313
398
|
horizontal=horizontal,
|
|
314
399
|
**kwargs,
|
|
315
400
|
)
|
|
316
|
-
if block_sep:
|
|
317
|
-
_separate_blocks(table.index, table_docx)
|
|
318
401
|
_fill_content(table, color_table, shade_table, table_docx, horizontal)
|
|
402
|
+
# Block separators insert *new rows* into the table, so they must
|
|
403
|
+
# run after _fill_content — otherwise the (row, col) indexing in
|
|
404
|
+
# _fill_content would land on the inserted separator rows.
|
|
405
|
+
if block_sep:
|
|
406
|
+
_separate_blocks(
|
|
407
|
+
table.index,
|
|
408
|
+
table_docx,
|
|
409
|
+
horizontal=horizontal,
|
|
410
|
+
config=cfg.block_separator,
|
|
411
|
+
)
|
|
319
412
|
table_docx.alignment = WD_TABLE_ALIGNMENT.CENTER
|
|
320
413
|
return table_docx
|
|
321
414
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/artists/barh_plot.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/artists/line_plot.py
RENAMED
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/artists/type_curve.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/assets/fonts/README.md
RENAMED
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/assets/tesoro.mplstyle
RENAMED
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/data_sources/__init__.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/data_sources/debug.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/database/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/dependencies/__init__.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/dependencies/node.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/dependencies/resolution.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/pipeline/__init__.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/pipeline/diagnose.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/providers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/content/__init__.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/content/content.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/content/images.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/content/section.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/content/subtitle.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/content/text.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.39 → tesorotools_python-0.0.41}/src/tesorotools/render/content/title.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|