prezo 2026.1.1__py3-none-any.whl → 2026.1.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.
- prezo/__init__.py +8 -0
- prezo/app.py +25 -31
- prezo/config.py +1 -1
- prezo/export/__init__.py +36 -0
- prezo/export/common.py +77 -0
- prezo/export/html.py +340 -0
- prezo/export/images.py +261 -0
- prezo/export/pdf.py +497 -0
- prezo/export/svg.py +170 -0
- prezo/layout.py +680 -0
- prezo/parser.py +11 -4
- prezo/widgets/__init__.py +9 -1
- prezo/widgets/slide_content.py +81 -0
- {prezo-2026.1.1.dist-info → prezo-2026.1.3.dist-info}/METADATA +25 -4
- {prezo-2026.1.1.dist-info → prezo-2026.1.3.dist-info}/RECORD +17 -10
- prezo/export.py +0 -835
- {prezo-2026.1.1.dist-info → prezo-2026.1.3.dist-info}/WHEEL +0 -0
- {prezo-2026.1.1.dist-info → prezo-2026.1.3.dist-info}/entry_points.txt +0 -0
prezo/widgets/__init__.py
CHANGED
|
@@ -4,6 +4,14 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from .image_display import ImageDisplay
|
|
6
6
|
from .slide_button import SlideButton
|
|
7
|
+
from .slide_content import SlideContent
|
|
7
8
|
from .status_bar import ClockDisplay, ProgressBar, StatusBar
|
|
8
9
|
|
|
9
|
-
__all__ = [
|
|
10
|
+
__all__ = [
|
|
11
|
+
"ClockDisplay",
|
|
12
|
+
"ImageDisplay",
|
|
13
|
+
"ProgressBar",
|
|
14
|
+
"SlideButton",
|
|
15
|
+
"SlideContent",
|
|
16
|
+
"StatusBar",
|
|
17
|
+
]
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Slide content widget with layout support."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from rich.markdown import Markdown as RichMarkdown
|
|
6
|
+
from textual.widgets import Static
|
|
7
|
+
|
|
8
|
+
from prezo.layout import has_layout_blocks, parse_layout, render_layout
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SlideContent(Static):
|
|
12
|
+
"""Widget that renders slide content with optional layout support.
|
|
13
|
+
|
|
14
|
+
Handles both plain markdown and Pandoc-style fenced div layouts:
|
|
15
|
+
- Plain markdown is rendered using Rich's Markdown
|
|
16
|
+
- Layout blocks (columns, center) are rendered using the layout module
|
|
17
|
+
|
|
18
|
+
Inherits from Static to properly handle Rich renderable display.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
DEFAULT_CSS = """
|
|
22
|
+
SlideContent {
|
|
23
|
+
width: 100%;
|
|
24
|
+
height: auto;
|
|
25
|
+
}
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
content: str = "",
|
|
31
|
+
*,
|
|
32
|
+
name: str | None = None,
|
|
33
|
+
id: str | None = None,
|
|
34
|
+
classes: str | None = None,
|
|
35
|
+
) -> None:
|
|
36
|
+
"""Initialize the slide content widget.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
content: Markdown content to display.
|
|
40
|
+
name: Widget name.
|
|
41
|
+
id: Widget ID.
|
|
42
|
+
classes: CSS classes.
|
|
43
|
+
|
|
44
|
+
"""
|
|
45
|
+
# Initialize Static with the rendered content
|
|
46
|
+
super().__init__("", name=name, id=id, classes=classes)
|
|
47
|
+
self._raw_content = content
|
|
48
|
+
if content:
|
|
49
|
+
self._update_renderable()
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def raw_content(self) -> str:
|
|
53
|
+
"""Get the current raw markdown content."""
|
|
54
|
+
return self._raw_content
|
|
55
|
+
|
|
56
|
+
def set_content(self, content: str) -> None:
|
|
57
|
+
"""Set the markdown content and refresh the widget.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
content: New markdown content to display.
|
|
61
|
+
|
|
62
|
+
"""
|
|
63
|
+
self._raw_content = content
|
|
64
|
+
self._update_renderable()
|
|
65
|
+
|
|
66
|
+
def _update_renderable(self) -> None:
|
|
67
|
+
"""Update the internal renderable based on content."""
|
|
68
|
+
if not self._raw_content:
|
|
69
|
+
super().update("")
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
# Check for layout directives
|
|
73
|
+
if has_layout_blocks(self._raw_content):
|
|
74
|
+
blocks = parse_layout(self._raw_content)
|
|
75
|
+
renderable = render_layout(blocks)
|
|
76
|
+
else:
|
|
77
|
+
# Plain markdown
|
|
78
|
+
renderable = RichMarkdown(self._raw_content)
|
|
79
|
+
|
|
80
|
+
# Use Static's update to set the renderable
|
|
81
|
+
super().update(renderable)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: prezo
|
|
3
|
-
Version: 2026.1.
|
|
3
|
+
Version: 2026.1.3
|
|
4
4
|
Summary: A TUI-based presentation tool for the terminal, built with Textual.
|
|
5
5
|
Author: Stefane Fermigier
|
|
6
6
|
Author-email: Stefane Fermigier <sf@fermigier.com>
|
|
@@ -16,9 +16,10 @@ A TUI-based presentation tool for the terminal, built with [Textual](https://tex
|
|
|
16
16
|
|
|
17
17
|
Display presentations written in Markdown using conventions similar to those of [MARP](https://marp.app/) or [Deckset](https://www.deckset.com/).
|
|
18
18
|
|
|
19
|
-
## Features
|
|
19
|
+
## Features
|
|
20
20
|
|
|
21
21
|
- **Markdown presentations** - MARP/Deckset format with `---` slide separators
|
|
22
|
+
- **Column layouts** - Pandoc-style fenced divs for multi-column slides (`::: columns`)
|
|
22
23
|
- **Live reload** - Auto-refresh when file changes (1s polling)
|
|
23
24
|
- **Keyboard navigation** - Vim-style keys, arrow keys, and more
|
|
24
25
|
- **Slide overview** - Grid view for quick navigation (`o`)
|
|
@@ -130,12 +131,32 @@ Presenter notes go here (after ???)
|
|
|
130
131
|
|
|
131
132
|
# Third Slide
|
|
132
133
|
|
|
134
|
+
::: columns
|
|
135
|
+
::: column
|
|
136
|
+
**Left Column**
|
|
137
|
+
- Point A
|
|
138
|
+
- Point B
|
|
139
|
+
:::
|
|
140
|
+
|
|
141
|
+
::: column
|
|
142
|
+
**Right Column**
|
|
143
|
+
- Point C
|
|
144
|
+
- Point D
|
|
145
|
+
:::
|
|
146
|
+
:::
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
# Fourth Slide
|
|
151
|
+
|
|
133
152
|
<!-- notes: Alternative notes syntax -->
|
|
134
153
|
|
|
135
|
-
|
|
154
|
+
::: center
|
|
155
|
+
**Centered content**
|
|
156
|
+
:::
|
|
136
157
|
```
|
|
137
158
|
|
|
138
|
-
See the [Writing Presentations in Markdown](docs/tutorial.md) tutorial for a complete guide on creating presentations, including images, presenter notes, and configuration directives.
|
|
159
|
+
See the [Writing Presentations in Markdown](docs/tutorial.md) tutorial for a complete guide on creating presentations, including column layouts, images, presenter notes, and configuration directives.
|
|
139
160
|
|
|
140
161
|
## Themes
|
|
141
162
|
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
prezo/__init__.py,sha256=
|
|
2
|
-
prezo/app.py,sha256=
|
|
3
|
-
prezo/config.py,sha256=
|
|
4
|
-
prezo/export.py,sha256=
|
|
1
|
+
prezo/__init__.py,sha256=RDpFh0F3DGdMB08n7G3HM-c14JAoqvElq4DyXLSPDQg,6740
|
|
2
|
+
prezo/app.py,sha256=3RPSx56hjyyG55ueNWHvuUNe-KkQ3ZzidNgBRc3I2WQ,31713
|
|
3
|
+
prezo/config.py,sha256=DLHUQkThxhmYXQE1AgpWkPvtNlDwOxQRSNjRrfJJEew,6646
|
|
4
|
+
prezo/export/__init__.py,sha256=jdf4Xu71aUKPBXUt8k8TEUzgMee4bfEh71iJGZXtVKE,1010
|
|
5
|
+
prezo/export/common.py,sha256=W9Gn2_wjd3EPuenAECrs6pqsJEWFBJHtGs8y6-4VEKQ,2451
|
|
6
|
+
prezo/export/html.py,sha256=GLRjTvZUEmvee6F2NlU3sn94H47PqLTLpaC3Ab_kxo8,8787
|
|
7
|
+
prezo/export/images.py,sha256=TNTGIYNRTxwVjbHqZXYjIj0gouV_Dy1_DtenMlxsquE,7410
|
|
8
|
+
prezo/export/pdf.py,sha256=9rzybk8o1vEu_JwvKB2abzrYoKfpEA8IP5pEFJHF5WM,13942
|
|
9
|
+
prezo/export/svg.py,sha256=gxhRXpLiKcVr4NSF8nwaid74p8f9dvj4RwXwvMP0EbU,5698
|
|
5
10
|
prezo/images/__init__.py,sha256=xrWSR3z0SXYpLtjIvR2VOMxiJGkxEsls5-EOs9GecFA,324
|
|
6
11
|
prezo/images/ascii.py,sha256=aNz02jN4rkDw0WzmkGDrAGw1R1dY5QGREvIIPI6jwow,7613
|
|
7
12
|
prezo/images/base.py,sha256=STuS57AVSJ2lzwyn0QrIceGaSd2IWEiLGN-elT3u3AM,2749
|
|
@@ -11,7 +16,8 @@ prezo/images/kitty.py,sha256=mWR-tIE_WDP5BjOkQydPpxWBBGNaZL8PkMICesWQid8,10883
|
|
|
11
16
|
prezo/images/overlay.py,sha256=lWIAvINxZrKembtB0gzWWaUoedNt7beFU4OhErfwWaw,9600
|
|
12
17
|
prezo/images/processor.py,sha256=zMcfwltecup_AX2FhUIlPdO7c87a9jw7P9tLTIkr54U,4069
|
|
13
18
|
prezo/images/sixel.py,sha256=2IeKDiMsWU1Tn3HYI3PC972ygxKGqpfz6tnhQcM_sVM,5604
|
|
14
|
-
prezo/
|
|
19
|
+
prezo/layout.py,sha256=xy-UaZvU2ZDe0H7XjMCDb30tog4LRdZKB5OUh_r0aqo,19929
|
|
20
|
+
prezo/parser.py,sha256=f1eJtr9xVnxa35jgQ3GvKwNa6TvaXrIKQWgBB_geVAI,15058
|
|
15
21
|
prezo/screens/__init__.py,sha256=xHG9jNJz4vi1tpneSEVlD0D9I0M2U4gAGk6-R9xbUf4,508
|
|
16
22
|
prezo/screens/base.py,sha256=2n6Uj8evfIbcpn4AVYNG5iM_k7rIJ3Vwmor_xrQPU9E,2057
|
|
17
23
|
prezo/screens/blackout.py,sha256=wPSdD9lgu8ykAIQjU1OesnmjQoQEn9BdC4TEpABYxW4,1640
|
|
@@ -22,11 +28,12 @@ prezo/screens/search.py,sha256=3YG9WLGEIKW3YHpM0K1lgwhuqBveXd8ZoQZ178_zGd4,7809
|
|
|
22
28
|
prezo/screens/toc.py,sha256=8WYb5nbgP9agY-hUTATxLU4X1uka_bc2MN86hFW4aRg,8241
|
|
23
29
|
prezo/terminal.py,sha256=Z3DuuighY-qfF6GWH_AkR5RnAc5Gj3LsPS266VNj7Pk,3638
|
|
24
30
|
prezo/themes.py,sha256=3keUgheOsNGjS0uCjRv7az9sVSnrz5tc-jZ58YNB7tg,3070
|
|
25
|
-
prezo/widgets/__init__.py,sha256=
|
|
31
|
+
prezo/widgets/__init__.py,sha256=6qAbVVWG2fb4DLv0EzMQ-Qbi74SviXIo-7D7DyDwnrI,378
|
|
26
32
|
prezo/widgets/image_display.py,sha256=8IKncaoC2iWebmJQp_QomF7UVgRxD4WThOshN1Nht2M,3361
|
|
27
33
|
prezo/widgets/slide_button.py,sha256=g5mvtCZSorTIZp_PXgHYeYeeCSNFy0pW3K7iDlZu7yA,2012
|
|
34
|
+
prezo/widgets/slide_content.py,sha256=AO3doIuPBSo5vec_d1xE5F8YMJWxzOq5IFO7gSYSWNw,2300
|
|
28
35
|
prezo/widgets/status_bar.py,sha256=Wcun71kg2Q4s5aduPwTvS4kDHZj5p-zDmD7Cx3_ZFP4,8136
|
|
29
|
-
prezo-2026.1.
|
|
30
|
-
prezo-2026.1.
|
|
31
|
-
prezo-2026.1.
|
|
32
|
-
prezo-2026.1.
|
|
36
|
+
prezo-2026.1.3.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
|
|
37
|
+
prezo-2026.1.3.dist-info/entry_points.txt,sha256=74ShZJ_EKjzi63JyPynVnc0uCHGNjIWjAVs8vU_qTyA,38
|
|
38
|
+
prezo-2026.1.3.dist-info/METADATA,sha256=mv3i3_l0Rq03cmGDQzwBeZ9FiUIJ6enFmJNSvm83v2I,5320
|
|
39
|
+
prezo-2026.1.3.dist-info/RECORD,,
|