Skip to content

Commit 4374852

Browse files
committed
fix: Actually prevent HTML re-rendering
1 parent 2e029cf commit 4374852

4 files changed

Lines changed: 27 additions & 15 deletions

File tree

src/markdown_exec/pycon.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import textwrap
66
from typing import Any
7+
from uuid import uuid4
78

89
from markdown.core import Markdown
910

@@ -41,8 +42,13 @@ def format_pycon( # noqa: WPS231
4142
python_code = "\n".join(python_lines)
4243

4344
extra = options.get("extra", {})
44-
output = run_python(python_code, html, **extra)
45+
output = run_python(python_code, **extra)
46+
stash = {}
47+
if html:
48+
placeholder = str(uuid4())
49+
stash[placeholder] = output
50+
output = placeholder
4551
if source:
4652
source_code = textwrap.indent(python_code, ">>> ")
4753
output = add_source(source=source_code, location=source, output=output, language="pycon", tabs=tabs, **extra)
48-
return markdown.convert(output)
54+
return markdown.convert(output, stash=stash)

src/markdown_exec/python.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from functools import partial
77
from io import StringIO
88
from typing import Any
9+
from uuid import uuid4
910

1011
from markdown.core import Markdown
1112

@@ -24,12 +25,11 @@ def buffer_print(buffer: StringIO, *text: str, end: str = "\n", **kwargs: Any) -
2425
buffer.write(" ".join(text) + end)
2526

2627

27-
def run_python(code: str, html: bool, **extra: str) -> str:
28+
def run_python(code: str, **extra: str) -> str:
2829
"""Run Python code using `exec` and return its output.
2930
3031
Parameters:
3132
code: The code to execute.
32-
html: Whether the output is HTML.
3333
**extra: Extra options passed to the traceback code block in case of errors.
3434
3535
Returns:
@@ -46,12 +46,8 @@ def run_python(code: str, html: bool, **extra: str) -> str:
4646
if frame.filename == "<string>":
4747
frame.filename = "<executed code block>"
4848
frame._line = code.split("\n")[frame.lineno - 1] # type: ignore[attr-defined,operator] # noqa: WPS437
49-
output = code_block("python", "".join(trace.format()), **extra)
50-
else:
51-
output = buffer.getvalue()
52-
if html:
53-
output = f'<div markdown="0">{str(output)}</div>'
54-
return output
49+
return code_block("python", "".join(trace.format()), **extra)
50+
return buffer.getvalue()
5551

5652

5753
def format_python( # noqa: WPS231
@@ -77,7 +73,12 @@ def format_python( # noqa: WPS231
7773
"""
7874
markdown.mimic(md)
7975
extra = options.get("extra", {})
80-
output = run_python(code, html, **extra)
76+
output = run_python(code, **extra)
77+
stash = {}
78+
if html:
79+
placeholder = str(uuid4())
80+
stash[placeholder] = output
81+
output = placeholder
8182
if source:
8283
output = add_source(source=code, location=source, output=output, language="python", tabs=tabs, **extra)
83-
return markdown.convert(output)
84+
return markdown.convert(output, stash=stash)

src/markdown_exec/rendering.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,12 @@ def mimic(self, md: Markdown) -> None:
132132
priority=4, # right after 'toc' (needed because that extension adds ids to headers)
133133
)
134134

135-
def convert(self, text: str) -> Markup:
135+
def convert(self, text: str, stash: dict[str, str] | None = None) -> Markup:
136136
"""Convert Markdown text to safe HTML.
137137
138138
Parameters:
139139
text: Markdown text.
140+
stash: An HTML stash.
140141
141142
Returns:
142143
Safe HTML.
@@ -145,9 +146,13 @@ def convert(self, text: str) -> Markup:
145146
self.counter += 1
146147

147148
try: # noqa: WPS501
148-
return Markup(self.md.convert(text))
149+
converted = self.md.convert(text)
149150
finally:
150151
self.md.treeprocessors[_IdPrependingTreeprocessor.name].id_prefix = ""
152+
if stash:
153+
for placeholder, stashed in stash.items():
154+
converted = converted.replace(placeholder, stashed)
155+
return Markup(converted)
151156

152157

153158
# provide a singleton

tests/test_python.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,4 @@ def test_output_html(md: Markdown) -> None:
3838
"""
3939
)
4040
)
41-
assert html == '<div markdown="0">**Bold!**\n</div>'
41+
assert html == "<p>**Bold!**\n</p>"

0 commit comments

Comments
 (0)