pl2html 0.3.0__tar.gz → 0.4.1__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.
- {pl2html-0.3.0 → pl2html-0.4.1}/PKG-INFO +5 -8
- {pl2html-0.3.0 → pl2html-0.4.1}/README.md +4 -7
- {pl2html-0.3.0 → pl2html-0.4.1}/pl2html/__init__.py +11 -5
- {pl2html-0.3.0 → pl2html-0.4.1}/pl2html/formats.py +9 -9
- {pl2html-0.3.0 → pl2html-0.4.1}/pyproject.toml +1 -1
- {pl2html-0.3.0 → pl2html-0.4.1}/pl2html/styles.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pl2html
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Requires-Dist: polars>=1.42.1
|
|
6
6
|
Requires-Python: >=3.14
|
|
@@ -51,10 +51,8 @@ df = pl.DataFrame(
|
|
|
51
51
|
)
|
|
52
52
|
|
|
53
53
|
# Compiles safely to a Polars LazyFrame containing the HTML output
|
|
54
|
-
|
|
54
|
+
html_table_string = to_html(df)
|
|
55
55
|
|
|
56
|
-
# Collect and extract the compiled string
|
|
57
|
-
html_table_string = html_lazy.collect().item()
|
|
58
56
|
print(html_table_string)
|
|
59
57
|
```
|
|
60
58
|
|
|
@@ -101,7 +99,7 @@ df_f = df.with_columns(
|
|
|
101
99
|
fmt.sub_zero("status_code", zero_text="OK")
|
|
102
100
|
)
|
|
103
101
|
|
|
104
|
-
html = to_html(df_f)
|
|
102
|
+
html = to_html(df_f)
|
|
105
103
|
```
|
|
106
104
|
|
|
107
105
|
### 3. Advanced Styling via Native Attributes (`attrs`)
|
|
@@ -141,7 +139,7 @@ styles.update(
|
|
|
141
139
|
)
|
|
142
140
|
)
|
|
143
141
|
|
|
144
|
-
html_table = to_html(df, attrs=styles)
|
|
142
|
+
html_table = to_html(df, attrs=styles)
|
|
145
143
|
```
|
|
146
144
|
|
|
147
145
|
Output (github may override table colors, but they are there):
|
|
@@ -213,5 +211,4 @@ Most of the API design and formatting parameters in this library are heavily ins
|
|
|
213
211
|
However, this library was born out of distinct architectural and environment constraints:
|
|
214
212
|
|
|
215
213
|
* **Zero Overhead Styling:** While `great-tables` is incredibly feature-rich, it often produces dense HTML styles and boilerplate structures that were unnecessary for the target use cases. This library optimizes for minimal, highly clean HTML output.
|
|
216
|
-
* **Modern Python Compatibility (Py 3.14+):** `great-tables` pulls in heavy external dependencies, including binary wheels like `multimark`. At the time of development, these dependencies did not support Python 3.14. To unblock workflows and maintain an ultra-lightweight, future-proof stack with zero complex binary dependencies, this native, Rust-backed Polars formatter was built from the ground up.
|
|
217
|
-
|
|
214
|
+
* **Modern Python Compatibility (Py 3.14+):** `great-tables` pulls in heavy external dependencies, including binary wheels like `multimark`. At the time of development, these dependencies did not support Python 3.14 (see [multimark #3](https://github.com/posit-dev/multimark/issues/3)). To unblock workflows and maintain an ultra-lightweight, future-proof stack with zero complex binary dependencies, this native, Rust-backed Polars formatter was built from the ground up.
|
|
@@ -42,10 +42,8 @@ df = pl.DataFrame(
|
|
|
42
42
|
)
|
|
43
43
|
|
|
44
44
|
# Compiles safely to a Polars LazyFrame containing the HTML output
|
|
45
|
-
|
|
45
|
+
html_table_string = to_html(df)
|
|
46
46
|
|
|
47
|
-
# Collect and extract the compiled string
|
|
48
|
-
html_table_string = html_lazy.collect().item()
|
|
49
47
|
print(html_table_string)
|
|
50
48
|
```
|
|
51
49
|
|
|
@@ -92,7 +90,7 @@ df_f = df.with_columns(
|
|
|
92
90
|
fmt.sub_zero("status_code", zero_text="OK")
|
|
93
91
|
)
|
|
94
92
|
|
|
95
|
-
html = to_html(df_f)
|
|
93
|
+
html = to_html(df_f)
|
|
96
94
|
```
|
|
97
95
|
|
|
98
96
|
### 3. Advanced Styling via Native Attributes (`attrs`)
|
|
@@ -132,7 +130,7 @@ styles.update(
|
|
|
132
130
|
)
|
|
133
131
|
)
|
|
134
132
|
|
|
135
|
-
html_table = to_html(df, attrs=styles)
|
|
133
|
+
html_table = to_html(df, attrs=styles)
|
|
136
134
|
```
|
|
137
135
|
|
|
138
136
|
Output (github may override table colors, but they are there):
|
|
@@ -204,5 +202,4 @@ Most of the API design and formatting parameters in this library are heavily ins
|
|
|
204
202
|
However, this library was born out of distinct architectural and environment constraints:
|
|
205
203
|
|
|
206
204
|
* **Zero Overhead Styling:** While `great-tables` is incredibly feature-rich, it often produces dense HTML styles and boilerplate structures that were unnecessary for the target use cases. This library optimizes for minimal, highly clean HTML output.
|
|
207
|
-
* **Modern Python Compatibility (Py 3.14+):** `great-tables` pulls in heavy external dependencies, including binary wheels like `multimark`. At the time of development, these dependencies did not support Python 3.14. To unblock workflows and maintain an ultra-lightweight, future-proof stack with zero complex binary dependencies, this native, Rust-backed Polars formatter was built from the ground up.
|
|
208
|
-
|
|
205
|
+
* **Modern Python Compatibility (Py 3.14+):** `great-tables` pulls in heavy external dependencies, including binary wheels like `multimark`. At the time of development, these dependencies did not support Python 3.14 (see [multimark #3](https://github.com/posit-dev/multimark/issues/3)). To unblock workflows and maintain an ultra-lightweight, future-proof stack with zero complex binary dependencies, this native, Rust-backed Polars formatter was built from the ground up.
|
|
@@ -10,7 +10,7 @@ from polars import (
|
|
|
10
10
|
when as _when,
|
|
11
11
|
)
|
|
12
12
|
|
|
13
|
-
__version__ = '0.
|
|
13
|
+
__version__ = '0.4.1'
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def _escape_polars_string(col_name: str) -> _Expr:
|
|
@@ -126,7 +126,7 @@ def to_html(
|
|
|
126
126
|
*,
|
|
127
127
|
attrs: dict[str, dict[str, _Expr]] | None = None,
|
|
128
128
|
exclude_columns: list[str] | None = None,
|
|
129
|
-
) ->
|
|
129
|
+
) -> str:
|
|
130
130
|
"""
|
|
131
131
|
Compiles a Polars DataFrame safely into an HTML string layout.
|
|
132
132
|
Accepts structural custom attributes mappings to handle layout modifications natively.
|
|
@@ -151,8 +151,14 @@ def to_html(
|
|
|
151
151
|
# 4. Generate wrappers and frame the query graph
|
|
152
152
|
html_header, html_footer = _build_html_skeleton(visible_columns)
|
|
153
153
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
154
|
+
# 5. Execute the query graph and pull out the raw python string directly
|
|
155
|
+
return (
|
|
156
|
+
lf.select(row_expr.alias('html_row'))
|
|
157
|
+
.select(
|
|
158
|
+
(
|
|
159
|
+
html_header + _col('html_row').str.join('\n') + html_footer
|
|
160
|
+
).alias('html_table')
|
|
157
161
|
)
|
|
162
|
+
.collect()
|
|
163
|
+
.item()
|
|
158
164
|
)
|
|
@@ -48,6 +48,7 @@ def fmt_number(
|
|
|
48
48
|
Highly optimized, native Polars numeric formatter matching great_tables features.
|
|
49
49
|
Runs entirely in the parallel Rust engine without dropping into Python row loops.
|
|
50
50
|
"""
|
|
51
|
+
col_name = columns if isinstance(columns, str) else str(columns)
|
|
51
52
|
val = _col(columns)
|
|
52
53
|
if scale_by != 1.0:
|
|
53
54
|
val = val * scale_by
|
|
@@ -61,6 +62,13 @@ def fmt_number(
|
|
|
61
62
|
)
|
|
62
63
|
thousands_exponent = (log10_expr / 3.0).floor().cast(_Int32) * 3
|
|
63
64
|
|
|
65
|
+
# Force exponent to 0 for fractional numbers (< 1.0) so we don't scale up without micro-suffixes
|
|
66
|
+
thousands_exponent = (
|
|
67
|
+
_when(thousands_exponent < 0)
|
|
68
|
+
.then(_lit(0))
|
|
69
|
+
.otherwise(thousands_exponent)
|
|
70
|
+
)
|
|
71
|
+
|
|
64
72
|
if compact_system == 'engineering':
|
|
65
73
|
suffix_chain = (
|
|
66
74
|
_when(thousands_exponent == 3)
|
|
@@ -96,28 +104,23 @@ def fmt_number(
|
|
|
96
104
|
if n_sigfig < 1:
|
|
97
105
|
raise ValueError('n_sigfig must be a positive integer >= 1')
|
|
98
106
|
|
|
99
|
-
# Round natively using Polars' built-in significant figures feature
|
|
100
107
|
rounded = val_scaled.round_sig_figs(n_sigfig)
|
|
101
108
|
abs_rounded = rounded.abs()
|
|
102
109
|
|
|
103
|
-
# Determine the number of dynamic decimal places needed for padding per row
|
|
104
110
|
log10_expr = (
|
|
105
111
|
_when(abs_rounded > 0)
|
|
106
112
|
.then(abs_rounded.log10())
|
|
107
113
|
.otherwise(_lit(0.0))
|
|
108
114
|
)
|
|
109
|
-
# decimals required = n_sigfig - 1 - floor(log10(x))
|
|
110
115
|
dynamic_decimals = (_lit(n_sigfig - 1) - log10_expr.floor()).cast(
|
|
111
116
|
_Int32
|
|
112
117
|
)
|
|
113
|
-
# Ensure we don't try to pad negative decimal places for large numbers
|
|
114
118
|
dynamic_decimals = (
|
|
115
119
|
_when(dynamic_decimals < 0)
|
|
116
120
|
.then(_lit(0))
|
|
117
121
|
.otherwise(dynamic_decimals)
|
|
118
122
|
)
|
|
119
123
|
else:
|
|
120
|
-
# Fallback to standard fixed decimal logic
|
|
121
124
|
epsilon = (
|
|
122
125
|
_when(val_scaled >= 0).then(_lit(1e-9)).otherwise(_lit(-1e-9))
|
|
123
126
|
)
|
|
@@ -134,7 +137,6 @@ def fmt_number(
|
|
|
134
137
|
.otherwise(_lit(''))
|
|
135
138
|
)
|
|
136
139
|
|
|
137
|
-
# Use native Python string multiplication inside _lit()
|
|
138
140
|
pad_len = n_sigfig if n_sigfig is not None else decimals
|
|
139
141
|
frac_part = (
|
|
140
142
|
_when(dynamic_decimals > 0)
|
|
@@ -175,7 +177,6 @@ def fmt_number(
|
|
|
175
177
|
+ _lit(')')
|
|
176
178
|
)
|
|
177
179
|
.otherwise(
|
|
178
|
-
# If force_sign is True, explicitly prepend '+' to positive values
|
|
179
180
|
_lit('+' if force_sign else '')
|
|
180
181
|
+ _lit(prefix)
|
|
181
182
|
+ base_num_str
|
|
@@ -186,13 +187,12 @@ def fmt_number(
|
|
|
186
187
|
formatted_expr = (
|
|
187
188
|
_when(val < 0)
|
|
188
189
|
.then(_lit('-') + _lit(prefix) + base_num_str + _lit(suffix))
|
|
189
|
-
# Handle zero explicitly if you don't want a sign on exactly 0.0
|
|
190
190
|
.when((val == 0) | (not force_sign))
|
|
191
191
|
.then(_lit(prefix) + base_num_str + _lit(suffix))
|
|
192
192
|
.otherwise(_lit('+') + _lit(prefix) + base_num_str + _lit(suffix))
|
|
193
193
|
)
|
|
194
194
|
|
|
195
|
-
return formatted_expr
|
|
195
|
+
return formatted_expr.alias(col_name)
|
|
196
196
|
|
|
197
197
|
|
|
198
198
|
@_multicolumn
|
|
File without changes
|