Skip to content

Commit 33bdd32

Browse files
Merge pull request #7 from feldroy/fix-render-in-newer-air
Fix child rendering for Air 0.45+
2 parents 3f4876a + 6270c59 commit 33bdd32

File tree

5 files changed

+344
-246
lines changed

5 files changed

+344
-246
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
matrix:
1919
# Test all supported Python versions under Ubuntu
2020
os: [ubuntu-latest]
21-
python-version: ['3.12', '3.13']
21+
python-version: ['3.13']
2222

2323
runs-on: ${{ matrix.os }}
2424

pyproject.toml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "air-markdown"
3-
version = "0.4.0"
3+
version = "0.5.0"
44
description = "Air Tags + Markdown"
55
readme = "README.md"
66
authors = [
@@ -26,17 +26,14 @@ classifiers = [
2626
"Framework :: FastAPI",
2727
"Intended Audience :: Developers",
2828
"Programming Language :: Python :: 3 :: Only",
29-
"Programming Language :: Python :: 3.10",
30-
"Programming Language :: Python :: 3.11",
31-
"Programming Language :: Python :: 3.12",
3229
"Programming Language :: Python :: 3.13",
3330
]
3431
license = {text = "MIT"}
3532
dependencies = [
36-
"air>=0.15.0",
33+
"air>=0.45.0",
3734
"mistletoe>=1.4.0",
3835
]
39-
requires-python = ">= 3.10"
36+
requires-python = ">= 3.13"
4037

4138
[project.optional-dependencies]
4239
dev = ["rust-just"]

src/air_markdown/tags.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import air
77
import mistletoe
8+
from air.tags import BaseTag
89
from mistletoe import block_token
910
from mistletoe.html_renderer import HtmlRenderer
1011

@@ -59,8 +60,12 @@ def wrapper(self):
5960
"""
6061
return content
6162

62-
def render(self) -> str:
63-
"""Render the string with the Markdown library."""
63+
def _render(self) -> str:
64+
"""Render the string with the Markdown library.
65+
66+
Note: We override _render() rather than render() because Air 0.25+
67+
renders child tags via __str__ -> html property -> _render().
68+
"""
6469
content = self._children[0] if self._children else ""
6570
return self.wrapper(mistletoe.markdown(content, self.html_renderer))
6671

@@ -100,7 +105,7 @@ def render_block_code(self, token: block_token.BlockCode) -> str:
100105
expr_obj = compile(ast.Expression(body=node.value), "<string>", "eval")
101106
# Ensure local_scope is passed to eval
102107
result = eval(expr_obj, globals(), local_scope)
103-
if isinstance(result, air.Tag):
108+
if isinstance(result, BaseTag):
104109
rendered_parts.append(result.render())
105110
else:
106111
# Execute other statements (imports, assignments, etc.)

tests/test_air_markdown.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Tests for `air_markdown` package."""
22

3+
import air
34
import mistletoe
45

56
from air_markdown import Markdown, TailwindTypographyMarkdown
@@ -53,9 +54,12 @@ def render_strong(self, token: mistletoe.span_token.Strong) -> str: # type: ign
5354

5455

5556
def test_custom_wrapper_dynamic_assignment():
56-
Markdown.wrapper = lambda self, x: f"<section>{x}</section>" # type: ignore
57-
58-
assert Markdown("# Big").render() == "<section><h1>Big</h1>\n</section>"
57+
original_wrapper = Markdown.wrapper
58+
try:
59+
Markdown.wrapper = lambda self, x: f"<section>{x}</section>" # type: ignore
60+
assert Markdown("# Big").render() == "<section><h1>Big</h1>\n</section>"
61+
finally:
62+
Markdown.wrapper = original_wrapper
5963

6064

6165
def test_TailwindTypographyMarkdown():
@@ -184,3 +188,25 @@ def test_air_markdown_airtag_multiple_tags_with_logic():
184188
'<article class="prose"><h1>Multiple Tags with Logic</h1>\n<h1>My Title</h1>\n<p>Some content.</p>\n</article>'
185189
)
186190
assert html == expected_html
191+
192+
193+
def test_markdown_as_child_of_div():
194+
"""Test that Markdown renders correctly when used as a child of another tag.
195+
196+
This tests the fix for Air 0.25+ where child tags are rendered via
197+
__str__ -> html property -> _render() rather than render().
198+
"""
199+
div = air.Div(Markdown("# Hello"))
200+
html = div.render()
201+
assert html == "<div><h1>Hello</h1>\n</div>"
202+
203+
204+
def test_markdown_nested_in_layout():
205+
"""Test Markdown inside a more complex tag structure."""
206+
layout = air.Main(
207+
air.Header(air.H1("Site Title")),
208+
air.Article(Markdown("## Article\n\nSome content.")),
209+
)
210+
html = layout.render()
211+
assert "<h2>Article</h2>" in html
212+
assert "<p>Some content.</p>" in html

0 commit comments

Comments
 (0)