staticdash 2026.2__py3-none-any.whl → 2026.3__py3-none-any.whl

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.
staticdash/dashboard.py CHANGED
@@ -10,8 +10,38 @@ from dominate.util import raw as raw_util
10
10
  import html
11
11
  import io
12
12
  import base64
13
+ import matplotlib
13
14
  from matplotlib import rc_context
14
15
 
16
+ def split_paragraphs_preserving_math(text):
17
+ """
18
+ Split text into paragraphs on double newlines, preserving math expressions.
19
+ Assumes math is in $...$ (inline) or $$...$$ (display) format.
20
+ """
21
+ math_blocks = []
22
+
23
+ # Replace math with placeholders
24
+ def replace_math(match):
25
+ math_blocks.append(match.group(0))
26
+ return f"__MATH_BLOCK_{len(math_blocks)-1}__"
27
+
28
+ # Handle display math first ($$...$$), then inline ($...$)
29
+ text = re.sub(r'\$\$([^$]+)\$\$', replace_math, text, flags=re.DOTALL)
30
+ text = re.sub(r'\$([^$]+)\$', replace_math, text, flags=re.DOTALL)
31
+
32
+ # Split on double newlines
33
+ paragraphs = text.split('\n\n')
34
+
35
+ # Restore math in each paragraph
36
+ restored_paragraphs = []
37
+ for para in paragraphs:
38
+ for i, block in enumerate(math_blocks):
39
+ para = para.replace(f"__MATH_BLOCK_{i}__", block)
40
+ restored_paragraphs.append(para.strip())
41
+
42
+ # Filter out empty paragraphs
43
+ return [para for para in restored_paragraphs if para]
44
+
15
45
  class AbstractPage:
16
46
  def __init__(self):
17
47
  self.elements = []
@@ -111,7 +141,11 @@ class Page(AbstractPage):
111
141
  outer_style = "display: flex; justify-content: center; margin: 0 auto;"
112
142
  elem = None
113
143
  if kind == "text":
114
- elem = p(content)
144
+ paragraphs = split_paragraphs_preserving_math(content)
145
+ if paragraphs:
146
+ elem = div(*[p(para) for para in paragraphs])
147
+ else:
148
+ elem = p(content)
115
149
  elif kind == "header":
116
150
  text, level = content
117
151
  header_tag = {1: h1, 2: h2, 3: h3, 4: h4}[level]
@@ -140,8 +174,6 @@ class Page(AbstractPage):
140
174
  elem = div(f"Plotly figure could not be rendered: {e}")
141
175
  else:
142
176
  try:
143
- buf = io.BytesIO()
144
- # Ensure we use ASCII hyphen-minus for negative ticks when saving
145
177
  with rc_context({"axes.unicode_minus": False}):
146
178
  fig.savefig(buf, format="png", bbox_inches="tight")
147
179
  buf.seek(0)
@@ -213,7 +245,11 @@ class MiniPage(AbstractPage):
213
245
  outer_style = "display: flex; justify-content: center; margin: 0 auto;"
214
246
  elem = None
215
247
  if kind == "text":
216
- elem = p(content)
248
+ paragraphs = split_paragraphs_preserving_math(content)
249
+ if paragraphs:
250
+ elem = div(*[p(para) for para in paragraphs])
251
+ else:
252
+ elem = p(content)
217
253
  elif kind == "header":
218
254
  text, level = content
219
255
  header_tag = {1: h1, 2: h2, 3: h3, 4: h4}[level]
@@ -240,7 +276,7 @@ class MiniPage(AbstractPage):
240
276
  else:
241
277
  try:
242
278
  buf = io.BytesIO()
243
- # Ensure we use ASCII hyphen-minus for negative ticks when saving
279
+ # Matplotlib may not be installed in minimal installs; import lazily
244
280
  with rc_context({"axes.unicode_minus": False}):
245
281
  fig.savefig(buf, format="png", bbox_inches="tight")
246
282
  buf.seek(0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: staticdash
3
- Version: 2026.2
3
+ Version: 2026.3
4
4
  Summary: A lightweight static HTML dashboard generator with Plotly and pandas support.
5
5
  Author-email: Brian Day <brian.day1@gmail.com>
6
6
  License: CC0-1.0
@@ -11,9 +11,11 @@ Description-Content-Type: text/markdown
11
11
  Requires-Dist: plotly
12
12
  Requires-Dist: pandas
13
13
  Requires-Dist: dominate
14
- Requires-Dist: reportlab
15
- Requires-Dist: kaleido
16
14
  Requires-Dist: matplotlib
15
+ Provides-Extra: images
16
+ Requires-Dist: kaleido; extra == "images"
17
+ Provides-Extra: all
18
+ Requires-Dist: kaleido; extra == "all"
17
19
 
18
20
  # staticdash
19
21
 
@@ -1,5 +1,5 @@
1
1
  staticdash/__init__.py,sha256=MQGR6LAqx2aFEA64MZz1ADxwpXLPn3VYNVIyjt9qx4Q,268
2
- staticdash/dashboard.py,sha256=xy3f8e0t6HQALSSuhj9z7I00h3oDnnAJIzTewCR4Quw,29452
2
+ staticdash/dashboard.py,sha256=37OQ_cpJEAsM-syAzGAz-CCR2zLPVnsN8hBKNPI9VsU,30766
3
3
  staticdash/assets/css/style.css,sha256=AOYdkw-nK_WvV6im_Y34gz4rJZWifk5o-mRmCKwMP60,7014
4
4
  staticdash/assets/js/script.js,sha256=7xBRlz_19wybbNVwAcfuKNXtDEojGB4EB0Yj4klsoTA,6998
5
5
  staticdash/assets/vendor/mathjax/tex-mml-chtml.js,sha256=MASABpB4tYktI2Oitl4t-78w_lyA-D7b_s9GEP0JOGI,1173007
@@ -13,7 +13,7 @@ staticdash/assets/vendor/prism/components/prism-json.min.js,sha256=lW2GuqWufsQQZ
13
13
  staticdash/assets/vendor/prism/components/prism-markup.min.js,sha256=h5_J0lbDUtmA4FOFf6cHMwhTuL-2fOKE6mYaJN7FdW4,2850
14
14
  staticdash/assets/vendor/prism/components/prism-python.min.js,sha256=7UOFaFvPLUk1yNu6tL3hZgPaEyngktK_NsPa3WfpqFw,2113
15
15
  staticdash/assets/vendor/prism/components/prism-sql.min.js,sha256=P8X4zmmVDsc63JcvBh30Kq6nj6pIZHCRNOoq3Ag_OjM,3261
16
- staticdash-2026.2.dist-info/METADATA,sha256=XdDg08yBsaYylKH6g8OFK0VrQN7vUyT--75Z9OFYdzA,2445
17
- staticdash-2026.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
18
- staticdash-2026.2.dist-info/top_level.txt,sha256=3MzZU6SptkUkjcHV1cvPji0H4aRzPphLHnpStgGEcxM,11
19
- staticdash-2026.2.dist-info/RECORD,,
16
+ staticdash-2026.3.dist-info/METADATA,sha256=XOU934A9XFnn2IqZuHLKp1bo7mA9ShE6UkifQ7G6dWw,2521
17
+ staticdash-2026.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
18
+ staticdash-2026.3.dist-info/top_level.txt,sha256=3MzZU6SptkUkjcHV1cvPji0H4aRzPphLHnpStgGEcxM,11
19
+ staticdash-2026.3.dist-info/RECORD,,