diff -Nru markdown-exec-1.3.0/CHANGELOG.md markdown-exec-1.4.0/CHANGELOG.md
--- markdown-exec-1.3.0/CHANGELOG.md 2023-02-18 13:54:04.000000000 +0100
+++ markdown-exec-1.4.0/CHANGELOG.md 2023-03-15 21:43:25.000000000 +0100
@@ -5,6 +5,14 @@
and this project adheres to [Semantic
Versioning](http://semver.org/spec/v2.0.0.html).
<!-- insertion marker -->
+## [1.4.0](https://github.com/pawamoy/markdown-exec/releases/tag/1.4.0) -
2023-03-15
+
+<small>[Compare with
1.3.0](https://github.com/pawamoy/markdown-exec/compare/1.3.0...1.4.0)</small>
+
+### Features
+
+- Sessions: persist and reuse state for Python and Pycon code blocks
([a8fef5e](https://github.com/pawamoy/markdown-exec/commit/a8fef5e90b1d7165e16ff5afe4b84e8441503098)
by Timothée Mazzucotelli). [Issue
#16](https://github.com/pawamoy/markdown-exec/issues/16)
+
## [1.3.0](https://github.com/pawamoy/markdown-exec/releases/tag/1.3.0) -
2023-02-18
<small>[Compare with 1.2.0](https://github.com/pawamoy/markdown-exec/compare/1.2.0...1.3.0)</small>
diff -Nru markdown-exec-1.3.0/debian/changelog
markdown-exec-1.4.0/debian/changelog
--- markdown-exec-1.3.0/debian/changelog 2023-02-27 12:21:30.000000000
+0100
+++ markdown-exec-1.4.0/debian/changelog 2023-03-19 07:26:01.000000000
+0100
@@ -1,3 +1,9 @@
+markdown-exec (1.4.0-1) unstable; urgency=medium
+
+ * [2aede3c] New upstream version 1.4.0
+
+ -- Carsten Schoenert <c.schoen...@t-online.de> Sun, 19 Mar 2023 07:26:01
+0100
+
markdown-exec (1.3.0-1) unstable; urgency=medium
* [8a80096] New upstream version 1.3.0
diff -Nru markdown-exec-1.3.0/docs/usage/index.md
markdown-exec-1.4.0/docs/usage/index.md
--- markdown-exec-1.3.0/docs/usage/index.md 2023-02-18 13:54:04.000000000
+0100
+++ markdown-exec-1.4.0/docs/usage/index.md 2023-03-15 21:43:25.000000000
+0100
@@ -258,6 +258,27 @@
> WARNING - markdown_exec: Execution of python code block 'print world'
exited with errors
> ```
+## Sessions
+
+Markdown Exec makes it possible to persist state between executed code blocks.
+To persist state and reuse it in other code blocks, give a session name to
your blocks:
+
+````md exec="1" source="material-block" title="Sessions"
+```python exec="1" session="greet"
+def greet(name):
+ print(f"Hello {name}!")
+```
+
+Hello Mushu!
+
+```python exec="1" session="greet"
+greet("Ping")
+```
+````
+
+WARNING: **Limitation**
+Sessions only work with Python and Pycon syntax for now.
+
## Literate Markdown
With this extension, it is also possible to write "literate programming" Markdown.
diff -Nru markdown-exec-1.3.0/README.md markdown-exec-1.4.0/README.md
--- markdown-exec-1.3.0/README.md 2023-02-18 13:54:04.000000000 +0100
+++ markdown-exec-1.4.0/README.md 2023-03-15 21:43:25.000000000 +0100
@@ -91,5 +91,14 @@
The `exec` option will be true for every possible value except `0`, `no`, `off` and `false` (case insensitive).
+Below you can see an example of running a bash script that is expected to
+return a non-zero exit code:
+
+````md
+```bash exec="1" source="tabbed-left" returncode="2"
+grep extra_css README.md && exit 2
+```
+````
+
See [usage](https://pawamoy.github.io/markdown-exec/usage/) for more details,
and the [gallery](https://pawamoy.github.io/markdown-exec/gallery/) for more
examples!
diff -Nru markdown-exec-1.3.0/src/markdown_exec/formatters/base.py
markdown-exec-1.4.0/src/markdown_exec/formatters/base.py
--- markdown-exec-1.3.0/src/markdown_exec/formatters/base.py 2023-02-18
13:54:04.000000000 +0100
+++ markdown-exec-1.4.0/src/markdown_exec/formatters/base.py 2023-03-15
21:43:25.000000000 +0100
@@ -50,6 +50,7 @@
id: str = "", # noqa: A002,VNE003
returncode: int = 0,
transform_source: Callable[[str], tuple[str, str]] | None = None,
+ session: str | None = None,
**options: Any,
) -> Markup:
"""Execute code and return HTML.
@@ -68,6 +69,7 @@
transform_source: An optional callable that returns transformed
versions of the source.
The input source is the one that is ran, the output source is the
one that is
rendered (when the source option is enabled).
+ session: A session name, to persist state between executed code blocks.
**options: Additional options passed from the formatter.
Returns:
@@ -83,7 +85,7 @@
source_output = code
try:
- output = run(source_input, returncode=returncode, **extra)
+ output = run(source_input, returncode=returncode, session=session,
**extra)
except ExecutionError as error:
identifier = id or extra.get("title", "")
identifier = identifier and f"'{identifier}' "
diff -Nru markdown-exec-1.3.0/src/markdown_exec/formatters/python.py
markdown-exec-1.4.0/src/markdown_exec/formatters/python.py
--- markdown-exec-1.3.0/src/markdown_exec/formatters/python.py 2023-02-18
13:54:04.000000000 +0100
+++ markdown-exec-1.4.0/src/markdown_exec/formatters/python.py 2023-03-15
21:43:25.000000000 +0100
@@ -10,14 +10,23 @@
from markdown_exec.formatters.base import ExecutionError, base_format
from markdown_exec.rendering import code_block
+_sessions: dict[str, dict] = {}
+
def _buffer_print(buffer: StringIO, *texts: str, end: str = "\n", **kwargs: Any) -> None:
buffer.write(" ".join(str(text) for text in texts) + end)
-def _run_python(code: str, **extra: str) -> str:
+def _run_python(code: str, session: str | None = None, **extra: str) -> str:
+ if session:
+ if session in _sessions:
+ exec_globals = _sessions[session]
+ else:
+ exec_globals = _sessions[session] = {} # noqa: WPS429
+ else:
+ exec_globals = {}
buffer = StringIO()
- exec_globals = {"print": partial(_buffer_print, buffer)}
+ exec_globals["print"] = partial(_buffer_print, buffer)
try:
exec(code, exec_globals) # noqa: S102
diff -Nru markdown-exec-1.3.0/src/markdown_exec/__init__.py
markdown-exec-1.4.0/src/markdown_exec/__init__.py
--- markdown-exec-1.3.0/src/markdown_exec/__init__.py 2023-02-18
13:54:04.000000000 +0100
+++ markdown-exec-1.4.0/src/markdown_exec/__init__.py 2023-03-15
21:43:25.000000000 +0100
@@ -65,6 +65,7 @@
source_value = inputs.pop("source", "")
result_value = inputs.pop("result", "")
returncode_value = int(inputs.pop("returncode", "0"))
+ session_value = inputs.pop("session", "")
tabs_value = inputs.pop("tabs", "|".join(default_tabs))
tabs = tuple(_tabs_re.split(tabs_value, maxsplit=1))
options["id"] = id_value
@@ -72,6 +73,7 @@
options["source"] = source_value
options["result"] = result_value
options["returncode"] = returncode_value
+ options["session"] = session_value
options["tabs"] = tabs
options["extra"] = inputs
return True
diff -Nru markdown-exec-1.3.0/tests/test_python.py
markdown-exec-1.4.0/tests/test_python.py
--- markdown-exec-1.3.0/tests/test_python.py 2023-02-18 13:54:04.000000000
+0100
+++ markdown-exec-1.4.0/tests/test_python.py 2023-03-15 21:43:25.000000000
+0100
@@ -84,3 +84,48 @@
)
)
assert "Traceback" not in html
+
+
+def test_sessions(md: Markdown) -> None:
+ """Assert sessions can be reused.
+
+ Parameters:
+ md: A Markdown instance (fixture).
+ """
+ html = md.convert(
+ dedent(
+ """
+ ```python exec="1" session="a"
+ a = 1
+ ```
+
+ ```pycon exec="1" session="b"
+ >>> b = 2
+ ```
+
+ ```pycon exec="1" session="a"
+ >>> print(f"a = {a}")
+ >>> try:
+ ... print(b)
+ ... except NameError:
+ ... print("ok")
+ ... else:
+ ... print("ko")
+ ```
+
+ ```python exec="1" session="b"
+ print(f"b = {b}")
+ try:
+ print(a)
+ except NameError:
+ print("ok")
+ else:
+ print("ko")
+ ```
+ """
+ )
+ )
+ assert "a = 1" in html
+ assert "b = 2" in html
+ assert "ok" in html
+ assert "ko" not in html