From 9754b892d6be30242cad9088c4938011c579576e Mon Sep 17 00:00:00 2001 From: giles Date: Tue, 3 Mar 2026 00:31:31 +0000 Subject: [PATCH] Fix double-escaping when render forms (<>, HTML tags) appear in eval position Return _RawHTML wrapper so pre-rendered HTML in let bindings isn't escaped when used in render context. Co-Authored-By: Claude Opus 4.6 --- shared/sx/async_eval.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/shared/sx/async_eval.py b/shared/sx/async_eval.py index b5e46dc..a260d4f 100644 --- a/shared/sx/async_eval.py +++ b/shared/sx/async_eval.py @@ -102,9 +102,11 @@ async def async_eval(expr: Any, env: dict[str, Any], ctx: RequestContext) -> Any return await async_eval(expanded, env, ctx) # Render forms in eval position — delegate to renderer and return - # the HTML string. Allows (let ((x (<> ...))) ...) etc. + # as _RawHTML so it won't be double-escaped when used in render + # context later. Allows (let ((x (<> ...))) ...) etc. if name in ("<>", "raw!") or name in HTML_TAGS: - return await _arender(expr, env, ctx) + html = await _arender(expr, env, ctx) + return _RawHTML(html) # --- function / lambda call --- fn = await async_eval(head, env, ctx)