typst-pyexec 0.0.0__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.
Files changed (37) hide show
  1. typst_pyexec-0.0.0/.github/workflows/ci.yml +56 -0
  2. typst_pyexec-0.0.0/.github/workflows/release.yml +50 -0
  3. typst_pyexec-0.0.0/.gitignore +9 -0
  4. typst_pyexec-0.0.0/LICENSE +21 -0
  5. typst_pyexec-0.0.0/PKG-INFO +235 -0
  6. typst_pyexec-0.0.0/README.md +200 -0
  7. typst_pyexec-0.0.0/examples/demo.typ +102 -0
  8. typst_pyexec-0.0.0/examples/persistent_kernel.typ +42 -0
  9. typst_pyexec-0.0.0/examples/reactive.typ +37 -0
  10. typst_pyexec-0.0.0/examples/subplot_options.typ +31 -0
  11. typst_pyexec-0.0.0/pyproject.toml +74 -0
  12. typst_pyexec-0.0.0/tests/__init__.py +1 -0
  13. typst_pyexec-0.0.0/tests/test_builder.py +93 -0
  14. typst_pyexec-0.0.0/tests/test_cache.py +123 -0
  15. typst_pyexec-0.0.0/tests/test_dag.py +124 -0
  16. typst_pyexec-0.0.0/tests/test_execution.py +183 -0
  17. typst_pyexec-0.0.0/tests/test_kernel.py +25 -0
  18. typst_pyexec-0.0.0/tests/test_parser.py +96 -0
  19. typst_pyexec-0.0.0/tests/test_renderer.py +155 -0
  20. typst_pyexec-0.0.0/typst_pyexec/__init__.py +6 -0
  21. typst_pyexec-0.0.0/typst_pyexec/builder.py +218 -0
  22. typst_pyexec-0.0.0/typst_pyexec/cli.py +114 -0
  23. typst_pyexec-0.0.0/typst_pyexec/core/__init__.py +1 -0
  24. typst_pyexec-0.0.0/typst_pyexec/core/cache.py +110 -0
  25. typst_pyexec-0.0.0/typst_pyexec/core/dag.py +267 -0
  26. typst_pyexec-0.0.0/typst_pyexec/core/executor.py +572 -0
  27. typst_pyexec-0.0.0/typst_pyexec/core/kernel.py +241 -0
  28. typst_pyexec-0.0.0/typst_pyexec/core/parser.py +110 -0
  29. typst_pyexec-0.0.0/typst_pyexec/core/renderer.py +490 -0
  30. typst_pyexec-0.0.0/typst_pyexec/core/scheduler.py +80 -0
  31. typst_pyexec-0.0.0/typst_pyexec/runtime/__init__.py +1 -0
  32. typst_pyexec-0.0.0/typst_pyexec/runtime/capture.py +49 -0
  33. typst_pyexec-0.0.0/typst_pyexec/runtime/displayhook.py +39 -0
  34. typst_pyexec-0.0.0/typst_pyexec/utils/__init__.py +1 -0
  35. typst_pyexec-0.0.0/typst_pyexec/utils/hashing.py +39 -0
  36. typst_pyexec-0.0.0/typst_pyexec/utils/logging.py +39 -0
  37. typst_pyexec-0.0.0/uv.lock +2291 -0
@@ -0,0 +1,56 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - "**"
7
+ pull_request:
8
+
9
+ jobs:
10
+ test-and-quality:
11
+ name: ${{ matrix.os }} / py${{ matrix.python-version }}
12
+ runs-on: ${{ matrix.os }}
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ os: [ubuntu-latest, windows-latest]
17
+ python-version: ["3.10", "3.11", "3.12"]
18
+
19
+ steps:
20
+ - name: Checkout
21
+ uses: actions/checkout@v4
22
+
23
+ - name: Setup Python
24
+ uses: actions/setup-python@v5
25
+ with:
26
+ python-version: ${{ matrix.python-version }}
27
+
28
+ - name: Setup uv
29
+ uses: astral-sh/setup-uv@v5
30
+
31
+ - name: Install dependencies
32
+ run: uv sync --extra dev
33
+
34
+ - name: Ruff lint
35
+ run: uv run ruff check .
36
+
37
+ - name: Black auto-format
38
+ run: uv run black typst_pyexec tests
39
+
40
+ - name: Black format check
41
+ run: uv run black --check typst_pyexec tests
42
+
43
+ - name: Mypy
44
+ run: uv run mypy typst_pyexec
45
+
46
+ - name: Pytest
47
+ env:
48
+ typst_pyexec_SKIP_KERNEL_TESTS: "1"
49
+ run: uv run pytest --cov=typst_pyexec --cov-report=term-missing --cov-report=xml
50
+
51
+ - name: Upload coverage XML
52
+ if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
53
+ uses: actions/upload-artifact@v4
54
+ with:
55
+ name: coverage-xml
56
+ path: coverage.xml
@@ -0,0 +1,50 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*.*.*"
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: read
13
+ steps:
14
+ - name: Checkout
15
+ uses: actions/checkout@v4
16
+
17
+ - name: Setup Python
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.11"
21
+
22
+ - name: Setup uv
23
+ uses: astral-sh/setup-uv@v5
24
+
25
+ - name: update version
26
+ run: uv version "${GITHUB_REF_NAME#v}"
27
+
28
+ - name: Build package
29
+ run: uv build
30
+
31
+ - name: Upload distribution artifacts
32
+ uses: actions/upload-artifact@v4
33
+ with:
34
+ name: dist
35
+ path: dist/*
36
+
37
+ publish:
38
+ runs-on: ubuntu-latest
39
+ needs: build
40
+ permissions:
41
+ id-token: write
42
+ steps:
43
+ - name: Download distribution artifacts
44
+ uses: actions/download-artifact@v4
45
+ with:
46
+ name: dist
47
+ path: dist
48
+
49
+ - name: Publish to PyPI
50
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,9 @@
1
+ *__pycache__
2
+ *.typst_pyexec*
3
+ *.venv
4
+ *.pytest_cache
5
+ *.mypy*
6
+ *.ruff*
7
+ *dist
8
+ *coverage*
9
+ *report
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Michel Jean Joseph Donnet
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,235 @@
1
+ Metadata-Version: 2.4
2
+ Name: typst_pyexec
3
+ Version: 0.0.0
4
+ Summary: Reactive Python execution engine for Typst documents
5
+ Author: typst_pyexec contributors
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Keywords: jupyter,notebook,python,reactive,typst
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Scientific/Engineering
17
+ Classifier: Topic :: Text Processing :: Markup
18
+ Requires-Python: >=3.10
19
+ Requires-Dist: black>=24.0
20
+ Requires-Dist: ipykernel>=6.0
21
+ Requires-Dist: joblib>=1.3
22
+ Requires-Dist: jupyter-client>=8.0
23
+ Requires-Dist: matplotlib>=3.7
24
+ Requires-Dist: nbformat>=5.9
25
+ Requires-Dist: pandas>=2.0
26
+ Requires-Dist: watchdog>=3.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: mypy; extra == 'dev'
29
+ Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
30
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
31
+ Requires-Dist: pytest-timeout>=2.1; extra == 'dev'
32
+ Requires-Dist: pytest>=7.0; extra == 'dev'
33
+ Requires-Dist: ruff; extra == 'dev'
34
+ Description-Content-Type: text/markdown
35
+
36
+ # typst_pyexec
37
+
38
+ typst_pyexec is a reactive Python execution engine for Typst documents.
39
+
40
+ It executes Python fences inside `.typ` files, captures outputs (stdout, figures, tables), and injects rendered Typst markup into an intermediate file (`*.typst_pyexec.typ`) that can be compiled directly.
41
+
42
+ ## Core Capabilities
43
+
44
+ - Reactive dependency graph based on Python AST analysis
45
+ - Incremental execution with source-hash cache
46
+ - Persistent Jupyter kernel between builds
47
+ - Automatic cold-kernel hydration for dependency prerequisites
48
+ - Matplotlib figure export to SVG with PNG fallback
49
+ - Subfigure reconstruction via `figure(grid(...))`
50
+ - DataFrame HTML rendering to Typst `#table(...)`
51
+ - Watch mode with automatic rebuilds
52
+
53
+ ## Installation
54
+
55
+ ```bash
56
+ pip install typst_pyexec
57
+ ```
58
+
59
+ For development:
60
+
61
+ ```bash
62
+ uv sync --extra dev
63
+ ```
64
+
65
+ ## CLI Usage
66
+
67
+ Build once:
68
+
69
+ ```bash
70
+ typst_pyexec build document.typ
71
+ ```
72
+
73
+ Watch and rebuild on save:
74
+
75
+ ```bash
76
+ typst_pyexec watch document.typ
77
+ ```
78
+
79
+ Clean local state directory:
80
+
81
+ ```bash
82
+ typst_pyexec clean
83
+ ```
84
+
85
+ Common options:
86
+
87
+ - `--output-dir <dir>`: write intermediate/state outputs to a custom folder
88
+ - `--no-cache`: disable cache lookups and force execution
89
+ - `--jobs <n>`: reserved for future multi-kernel scheduling (`-1` default)
90
+ - `--compiler <cmd>`: Typst compiler binary name/path (default `typst`)
91
+
92
+ ## Block Options (`%|`)
93
+
94
+ Place options at the top of a Python fence:
95
+
96
+ ````typst
97
+ ```python
98
+ %| echo: false
99
+ %| raw: true
100
+ %| figure: true
101
+ print("hello")
102
+ ```
103
+ ````
104
+
105
+ Supported options:
106
+
107
+ - `execute` (default `true`): skip execution when `false`
108
+ - `refresh` (default `false`): force this cell to run every build
109
+ - `echo` (default `true`): show or hide source code
110
+ - `raw` (default `true`): show or hide textual runtime output (`stdout`, traceback, `text/plain` display bundles)
111
+ - `figure` (default `true`): show or hide rendered figures
112
+ - `caption`: explicit figure caption override
113
+ - `label`: Typst label for cross-references
114
+ - `keep-subplots` (default `false`): preserve multi-axis plot as one image
115
+ - `img-*`: passthrough kwargs for Typst `image(...)`
116
+ - `fig-*`: passthrough kwargs for Typst `figure(...)`
117
+ - `grid-*`: passthrough kwargs for Typst `grid(...)`
118
+
119
+ Behavior notes:
120
+
121
+ - `cell_id` is internal and generated automatically.
122
+ - Option-only edits do not invalidate cache because cache keys are based on Python source.
123
+ - To re-run on option updates, set `refresh: true`.
124
+
125
+ ## Figure and Caption Behavior
126
+
127
+ - For single-axis plots, title text is promoted into Typst caption when `caption` is not set.
128
+ - For subplot grids, each axis title becomes child caption; suptitle becomes outer caption.
129
+ - Title text is removed from exported images after promotion to captions.
130
+ - If SVG export fails and PNG is emitted, renderer auto-resolves PNG paths in final Typst output.
131
+
132
+ ## How It Works
133
+
134
+ 1. Parse Python fences from Typst source
135
+ 2. Build def/use DAG from AST
136
+ 3. Compute changed cells from source-hash cache
137
+ 4. Execute required cells in topological groups
138
+ 5. Capture stdout, display bundles, and figure artifacts
139
+ 6. Render Typst fragments per cell
140
+ 7. Inject into `document.typst_pyexec.typ`
141
+ 8. Compile with Typst compiler
142
+
143
+ ## Local State
144
+
145
+ typst_pyexec writes runtime state into `.typst_pyexec/`:
146
+
147
+ - `kernel_connection.json`: reconnect data for persistent kernel
148
+ - `cache/`: JSON entries keyed by SHA-256 of cell source
149
+ - `figures/`: SVG/PNG artifacts
150
+ - `notebook.ipynb`: synchronized notebook representation
151
+
152
+ ## Development Quality Gates
153
+
154
+ Run checks locally:
155
+
156
+ ```bash
157
+ uv run ruff check .
158
+ uv run black --check typst_pyexec tests
159
+ uv run mypy typst_pyexec
160
+ uv run pytest
161
+ ```
162
+
163
+ ## CI/CD (GitHub Actions)
164
+
165
+ - `CI`: matrix on Ubuntu and Windows, Python 3.10-3.12, with lint + format + type-check + tests + coverage artifact
166
+ - `Release`: tag-driven (`v*.*.*`) build and publish workflow for PyPI using trusted publishing
167
+
168
+ Workflows are in:
169
+
170
+ - `.github/workflows/ci.yml`
171
+ - `.github/workflows/release.yml`
172
+
173
+ ## Publish to PyPI
174
+
175
+ typst_pyexec is already configured for trusted publishing through GitHub Actions.
176
+
177
+ Release steps:
178
+
179
+ 1. Bump version in `pyproject.toml` and `typst_pyexec/__init__.py`.
180
+ 2. Commit and push to main.
181
+ 3. Create and push a version tag:
182
+
183
+ ```bash
184
+ git tag v0.1.1
185
+ git push origin v0.1.1
186
+ ```
187
+
188
+ 4. GitHub Actions runs `.github/workflows/release.yml` and publishes to PyPI.
189
+
190
+ Pre-tag checklist:
191
+
192
+ 1. `python -m pytest -q` is green.
193
+ 2. `python -m build` succeeds.
194
+ 3. `python -m twine check dist/*` passes.
195
+ 4. Version matches in `pyproject.toml` and `typst_pyexec/__init__.py`.
196
+ 5. Git tag matches that version (`vX.Y.Z`).
197
+
198
+ Local preflight checks before tagging:
199
+
200
+ ```bash
201
+ python -m build
202
+ python -m twine check dist/*
203
+ ```
204
+
205
+ If you prefer token-based manual publishing:
206
+
207
+ ```bash
208
+ python -m twine upload dist/*
209
+ ```
210
+
211
+ ## Use in Other Repositories
212
+
213
+ After publishing, install as a normal dependency.
214
+
215
+ With pip:
216
+
217
+ ```bash
218
+ pip install typst_pyexec
219
+ ```
220
+
221
+ With uv (project dependency):
222
+
223
+ ```bash
224
+ uv add typst_pyexec
225
+ ```
226
+
227
+ With uvx (run CLI without adding dependency):
228
+
229
+ ```bash
230
+ uvx typst_pyexec build document.typ
231
+ ```
232
+
233
+ ## License
234
+
235
+ MIT
@@ -0,0 +1,200 @@
1
+ # typst_pyexec
2
+
3
+ typst_pyexec is a reactive Python execution engine for Typst documents.
4
+
5
+ It executes Python fences inside `.typ` files, captures outputs (stdout, figures, tables), and injects rendered Typst markup into an intermediate file (`*.typst_pyexec.typ`) that can be compiled directly.
6
+
7
+ ## Core Capabilities
8
+
9
+ - Reactive dependency graph based on Python AST analysis
10
+ - Incremental execution with source-hash cache
11
+ - Persistent Jupyter kernel between builds
12
+ - Automatic cold-kernel hydration for dependency prerequisites
13
+ - Matplotlib figure export to SVG with PNG fallback
14
+ - Subfigure reconstruction via `figure(grid(...))`
15
+ - DataFrame HTML rendering to Typst `#table(...)`
16
+ - Watch mode with automatic rebuilds
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ pip install typst_pyexec
22
+ ```
23
+
24
+ For development:
25
+
26
+ ```bash
27
+ uv sync --extra dev
28
+ ```
29
+
30
+ ## CLI Usage
31
+
32
+ Build once:
33
+
34
+ ```bash
35
+ typst_pyexec build document.typ
36
+ ```
37
+
38
+ Watch and rebuild on save:
39
+
40
+ ```bash
41
+ typst_pyexec watch document.typ
42
+ ```
43
+
44
+ Clean local state directory:
45
+
46
+ ```bash
47
+ typst_pyexec clean
48
+ ```
49
+
50
+ Common options:
51
+
52
+ - `--output-dir <dir>`: write intermediate/state outputs to a custom folder
53
+ - `--no-cache`: disable cache lookups and force execution
54
+ - `--jobs <n>`: reserved for future multi-kernel scheduling (`-1` default)
55
+ - `--compiler <cmd>`: Typst compiler binary name/path (default `typst`)
56
+
57
+ ## Block Options (`%|`)
58
+
59
+ Place options at the top of a Python fence:
60
+
61
+ ````typst
62
+ ```python
63
+ %| echo: false
64
+ %| raw: true
65
+ %| figure: true
66
+ print("hello")
67
+ ```
68
+ ````
69
+
70
+ Supported options:
71
+
72
+ - `execute` (default `true`): skip execution when `false`
73
+ - `refresh` (default `false`): force this cell to run every build
74
+ - `echo` (default `true`): show or hide source code
75
+ - `raw` (default `true`): show or hide textual runtime output (`stdout`, traceback, `text/plain` display bundles)
76
+ - `figure` (default `true`): show or hide rendered figures
77
+ - `caption`: explicit figure caption override
78
+ - `label`: Typst label for cross-references
79
+ - `keep-subplots` (default `false`): preserve multi-axis plot as one image
80
+ - `img-*`: passthrough kwargs for Typst `image(...)`
81
+ - `fig-*`: passthrough kwargs for Typst `figure(...)`
82
+ - `grid-*`: passthrough kwargs for Typst `grid(...)`
83
+
84
+ Behavior notes:
85
+
86
+ - `cell_id` is internal and generated automatically.
87
+ - Option-only edits do not invalidate cache because cache keys are based on Python source.
88
+ - To re-run on option updates, set `refresh: true`.
89
+
90
+ ## Figure and Caption Behavior
91
+
92
+ - For single-axis plots, title text is promoted into Typst caption when `caption` is not set.
93
+ - For subplot grids, each axis title becomes child caption; suptitle becomes outer caption.
94
+ - Title text is removed from exported images after promotion to captions.
95
+ - If SVG export fails and PNG is emitted, renderer auto-resolves PNG paths in final Typst output.
96
+
97
+ ## How It Works
98
+
99
+ 1. Parse Python fences from Typst source
100
+ 2. Build def/use DAG from AST
101
+ 3. Compute changed cells from source-hash cache
102
+ 4. Execute required cells in topological groups
103
+ 5. Capture stdout, display bundles, and figure artifacts
104
+ 6. Render Typst fragments per cell
105
+ 7. Inject into `document.typst_pyexec.typ`
106
+ 8. Compile with Typst compiler
107
+
108
+ ## Local State
109
+
110
+ typst_pyexec writes runtime state into `.typst_pyexec/`:
111
+
112
+ - `kernel_connection.json`: reconnect data for persistent kernel
113
+ - `cache/`: JSON entries keyed by SHA-256 of cell source
114
+ - `figures/`: SVG/PNG artifacts
115
+ - `notebook.ipynb`: synchronized notebook representation
116
+
117
+ ## Development Quality Gates
118
+
119
+ Run checks locally:
120
+
121
+ ```bash
122
+ uv run ruff check .
123
+ uv run black --check typst_pyexec tests
124
+ uv run mypy typst_pyexec
125
+ uv run pytest
126
+ ```
127
+
128
+ ## CI/CD (GitHub Actions)
129
+
130
+ - `CI`: matrix on Ubuntu and Windows, Python 3.10-3.12, with lint + format + type-check + tests + coverage artifact
131
+ - `Release`: tag-driven (`v*.*.*`) build and publish workflow for PyPI using trusted publishing
132
+
133
+ Workflows are in:
134
+
135
+ - `.github/workflows/ci.yml`
136
+ - `.github/workflows/release.yml`
137
+
138
+ ## Publish to PyPI
139
+
140
+ typst_pyexec is already configured for trusted publishing through GitHub Actions.
141
+
142
+ Release steps:
143
+
144
+ 1. Bump version in `pyproject.toml` and `typst_pyexec/__init__.py`.
145
+ 2. Commit and push to main.
146
+ 3. Create and push a version tag:
147
+
148
+ ```bash
149
+ git tag v0.1.1
150
+ git push origin v0.1.1
151
+ ```
152
+
153
+ 4. GitHub Actions runs `.github/workflows/release.yml` and publishes to PyPI.
154
+
155
+ Pre-tag checklist:
156
+
157
+ 1. `python -m pytest -q` is green.
158
+ 2. `python -m build` succeeds.
159
+ 3. `python -m twine check dist/*` passes.
160
+ 4. Version matches in `pyproject.toml` and `typst_pyexec/__init__.py`.
161
+ 5. Git tag matches that version (`vX.Y.Z`).
162
+
163
+ Local preflight checks before tagging:
164
+
165
+ ```bash
166
+ python -m build
167
+ python -m twine check dist/*
168
+ ```
169
+
170
+ If you prefer token-based manual publishing:
171
+
172
+ ```bash
173
+ python -m twine upload dist/*
174
+ ```
175
+
176
+ ## Use in Other Repositories
177
+
178
+ After publishing, install as a normal dependency.
179
+
180
+ With pip:
181
+
182
+ ```bash
183
+ pip install typst_pyexec
184
+ ```
185
+
186
+ With uv (project dependency):
187
+
188
+ ```bash
189
+ uv add typst_pyexec
190
+ ```
191
+
192
+ With uvx (run CLI without adding dependency):
193
+
194
+ ```bash
195
+ uvx typst_pyexec build document.typ
196
+ ```
197
+
198
+ ## License
199
+
200
+ MIT
@@ -0,0 +1,102 @@
1
+ = typst_pyexec Example — Python Output, Plots and Tables
2
+
3
+ #set document(title: "typst_pyexec Demo", author: "typst_pyexec")
4
+ #set page(numbering: "1")
5
+
6
+ == Scalar and array output
7
+
8
+ ```python
9
+ import numpy as np
10
+ import pandas as pd
11
+ import matplotlib
12
+ matplotlib.use("Agg")
13
+ import matplotlib.pyplot as plt
14
+ print("Libraries loaded.")
15
+ ```
16
+
17
+ ```python
18
+ arr = np.arange(10)
19
+ print(arr)
20
+ ```
21
+
22
+ == Reactive dependency demo
23
+
24
+ If you change `cell_scalar` below, only `cell_derived` will re-execute.
25
+ `cell_array` (no dependency on `x`) stays cached.
26
+
27
+ ```python
28
+ x = 7
29
+ print(f"x = {x}")
30
+ ```
31
+
32
+ ```python
33
+ y = x ** 2
34
+ print(f"y = x**2 = {y}")
35
+ ```
36
+
37
+ == Simple plot
38
+
39
+ ```python
40
+ %| label: fig-trig
41
+ fig, ax = plt.subplots()
42
+ t = np.linspace(0, 2 * np.pi, 200)
43
+ ax.plot(t, np.sin(t), label="sin(t)")
44
+ ax.plot(t, np.cos(t), label="cos(t)")
45
+ ax.legend()
46
+ ax.set_title("Trigonometric functions")
47
+ plt.show()
48
+ ```
49
+
50
+ == Multi-panel figure (subfigures)
51
+
52
+ ```python
53
+ %| img-width: 100%
54
+ %| label: fig-multipanel
55
+ fig, axes = plt.subplots(1, 2, figsize=(8, 3))
56
+ axes[0].plot([1, 2, 3], [1, 4, 8])
57
+ axes[0].set_title("Quadratic")
58
+ axes[1].bar(["A", "B", "C"], [3, 1, 4])
59
+ axes[1].set_title("Bar chart")
60
+ plt.tight_layout()
61
+ plt.show()
62
+ ```
63
+
64
+ == Pandas DataFrame table
65
+
66
+ ```python
67
+ df = pd.DataFrame({
68
+ "Name": ["Alice", "Bo", "Carol"],
69
+ "Score": [95, 87, 92],
70
+ "Grade": ["A", "B+", "A-"],
71
+ })
72
+ df
73
+ ```
74
+
75
+ == Adding a new cell — no recomputation of previous cells
76
+
77
+ The cell below is independent of all prior cells. If you add it
78
+ to an existing document, typst_pyexec will execute only *this* cell because
79
+ all previous cells are served from the SHA-256 cache.
80
+
81
+ ```python
82
+ msg = "I was added later and ran independently!"
83
+ print(msg)
84
+ print("Coucou")
85
+ ```
86
+
87
+ ```python
88
+ test = np.arange(5)
89
+ print("Coucou")
90
+ print(test)
91
+ ```
92
+
93
+ ```python
94
+ %| label: test
95
+ plt.figure()
96
+ plt.title("Gnyajaja")
97
+ plt.plot(np.arange(6), np.arange(6))
98
+ plt.show()
99
+ ```
100
+
101
+ Here is some coucou in @test and in @fig-multipanel-a
102
+ The code is amazing because the rebuild is very fast
@@ -0,0 +1,42 @@
1
+ = Persistent Kernel Demo
2
+
3
+ Imports defined in an earlier cell are available in all later cells
4
+ because the Jupyter kernel's namespace is preserved across builds.
5
+
6
+ ```python
7
+ import numpy as np
8
+ import matplotlib
9
+ matplotlib.use("Agg")
10
+ import matplotlib.pyplot as plt
11
+ print("numpy version:", np.__version__)
12
+ ```
13
+
14
+ ```python
15
+ # np is already in the kernel namespace from the `imports` cell.
16
+ result = np.sqrt(np.array([1, 4, 9, 16, 25]))
17
+ print("Square roots:", result)
18
+ ```
19
+
20
+ ```python
21
+ %| caption: Matplotlib reuses imported namespace
22
+ x = np.linspace(0, 10, 300)
23
+ plt.plot(x, np.exp(-0.3 * x) * np.sin(x))
24
+ plt.title("Damped oscillation")
25
+ plt.xlabel("t")
26
+ plt.ylabel("f(t)")
27
+ plt.show()
28
+ ```
29
+
30
+ == Adding a new cell later
31
+
32
+ If you add the cell below *after* an initial build, typst_pyexec will:
33
+
34
+ 1. Detect that the new cell is not in the cache.
35
+ 2. Execute only the new cell (imports cell is cached — kernel already has `np`).
36
+ 3. Re-use the live kernel namespace so `np` is available immediately.
37
+
38
+ ```python
39
+ # This cell was added in a second build but imports still work.
40
+ arr = np.random.default_rng(0).integers(0, 100, size=5)
41
+ print("Random integers:", arr)
42
+ ```