Spaces:
Running
Running
multi page apps
Browse files
app.py
CHANGED
|
@@ -380,6 +380,54 @@ Always respond with code that can be executed or rendered directly.
|
|
| 380 |
|
| 381 |
Always output only the HTML code inside a ```html ... ``` code block, and do not include any explanations or extra text. Do NOT add the language name at the top of the code output."""
|
| 382 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 383 |
GENERIC_SYSTEM_PROMPT_WITH_SEARCH = """You are an expert {language} developer. You have access to real-time web search. When needed, use web search to find the latest information, best practices, or specific technologies for {language}.
|
| 384 |
|
| 385 |
Write clean, idiomatic, and runnable {language} code for the user's request. If possible, include comments and best practices. Output ONLY the code inside a ``` code block, and do not include any explanations or extra text. If the user provides a file or other context, use it as a reference. If the code is for a script or app, make it as self-contained as possible. Do NOT add the language name at the top of the code output."""
|
|
@@ -1170,6 +1218,110 @@ def send_transformers_to_sandbox(files: dict) -> str:
|
|
| 1170 |
merged_html = build_transformers_inline_html(files)
|
| 1171 |
return send_to_sandbox(merged_html)
|
| 1172 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1173 |
def parse_svelte_output(text):
|
| 1174 |
"""Parse Svelte output to extract individual files"""
|
| 1175 |
files = {
|
|
@@ -3129,7 +3281,8 @@ def generation_code(query: Optional[str], vlm_image: Optional[gr.Image], gen_ima
|
|
| 3129 |
else:
|
| 3130 |
# Use language-specific prompt
|
| 3131 |
if language == "html":
|
| 3132 |
-
|
|
|
|
| 3133 |
elif language == "transformers.js":
|
| 3134 |
system_prompt = TRANSFORMERS_JS_SYSTEM_PROMPT_WITH_SEARCH if enable_search else TRANSFORMERS_JS_SYSTEM_PROMPT
|
| 3135 |
elif language == "svelte":
|
|
@@ -3199,7 +3352,8 @@ This will help me create a better design for you."""
|
|
| 3199 |
# Live streaming preview
|
| 3200 |
preview_val = None
|
| 3201 |
if language == "html":
|
| 3202 |
-
|
|
|
|
| 3203 |
elif language == "python" and is_streamlit_code(clean_code):
|
| 3204 |
preview_val = send_streamlit_to_stlite(clean_code)
|
| 3205 |
yield {
|
|
@@ -3428,7 +3582,8 @@ This will help me create a better design for you."""
|
|
| 3428 |
|
| 3429 |
preview_val = None
|
| 3430 |
if language == "html":
|
| 3431 |
-
|
|
|
|
| 3432 |
elif language == "python" and is_streamlit_code(final_content):
|
| 3433 |
preview_val = send_streamlit_to_stlite(final_content)
|
| 3434 |
yield {
|
|
@@ -3494,7 +3649,8 @@ This will help me create a better design for you."""
|
|
| 3494 |
clean_code = clean_code.replace("\\t", "\t")
|
| 3495 |
preview_val = None
|
| 3496 |
if language == "html":
|
| 3497 |
-
|
|
|
|
| 3498 |
elif language == "python" and is_streamlit_code(clean_code):
|
| 3499 |
preview_val = send_streamlit_to_stlite(clean_code)
|
| 3500 |
yield {
|
|
@@ -3513,7 +3669,8 @@ This will help me create a better design for you."""
|
|
| 3513 |
_history.append([query, clean_code])
|
| 3514 |
preview_val = None
|
| 3515 |
if language == "html":
|
| 3516 |
-
|
|
|
|
| 3517 |
elif language == "python" and is_streamlit_code(clean_code):
|
| 3518 |
preview_val = send_streamlit_to_stlite(clean_code)
|
| 3519 |
yield {
|
|
@@ -3689,7 +3846,8 @@ This will help me create a better design for you."""
|
|
| 3689 |
# Model returned a complete HTML file
|
| 3690 |
preview_val = None
|
| 3691 |
if language == "html":
|
| 3692 |
-
|
|
|
|
| 3693 |
elif language == "python" and is_streamlit_code(clean_code):
|
| 3694 |
preview_val = send_streamlit_to_stlite(clean_code)
|
| 3695 |
elif language == "gradio" or (language == "python" and is_gradio_code(clean_code)):
|
|
@@ -3706,7 +3864,8 @@ This will help me create a better design for you."""
|
|
| 3706 |
clean_content = remove_code_block(modified_content)
|
| 3707 |
preview_val = None
|
| 3708 |
if language == "html":
|
| 3709 |
-
|
|
|
|
| 3710 |
elif language == "python" and is_streamlit_code(clean_content):
|
| 3711 |
preview_val = send_streamlit_to_stlite(clean_content)
|
| 3712 |
elif language == "gradio" or (language == "python" and is_gradio_code(clean_content)):
|
|
@@ -3719,7 +3878,8 @@ This will help me create a better design for you."""
|
|
| 3719 |
else:
|
| 3720 |
preview_val = None
|
| 3721 |
if language == "html":
|
| 3722 |
-
|
|
|
|
| 3723 |
elif language == "python" and is_streamlit_code(clean_code):
|
| 3724 |
preview_val = send_streamlit_to_stlite(clean_code)
|
| 3725 |
elif language == "gradio" or (language == "python" and is_gradio_code(clean_code)):
|
|
@@ -3835,7 +3995,7 @@ This will help me create a better design for you."""
|
|
| 3835 |
yield {
|
| 3836 |
code_output: clean_content,
|
| 3837 |
history: _history,
|
| 3838 |
-
sandbox: (send_to_sandbox(clean_content) if language == "html" else (send_streamlit_to_stlite(clean_content) if (language == "python" and is_streamlit_code(clean_content)) else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML or Streamlit-in-Python.</div>")),
|
| 3839 |
history_output: history_to_chatbot_messages(_history),
|
| 3840 |
}
|
| 3841 |
else:
|
|
@@ -3864,7 +4024,8 @@ This will help me create a better design for you."""
|
|
| 3864 |
_history.append([query, final_content])
|
| 3865 |
preview_val = None
|
| 3866 |
if language == "html":
|
| 3867 |
-
|
|
|
|
| 3868 |
elif language == "python" and is_streamlit_code(final_content):
|
| 3869 |
preview_val = send_streamlit_to_stlite(final_content)
|
| 3870 |
elif language == "gradio" or (language == "python" and is_gradio_code(final_content)):
|
|
@@ -5323,6 +5484,11 @@ with gr.Blocks(
|
|
| 5323 |
|
| 5324 |
def preview_logic(code, language, html_part=None, js_part=None, css_part=None):
|
| 5325 |
if language == "html":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5326 |
return send_to_sandbox(code)
|
| 5327 |
if language == "streamlit":
|
| 5328 |
return send_streamlit_to_stlite(code) if is_streamlit_code(code) else "<div style='padding:1em;color:#888;text-align:center;'>Add `import streamlit as st` to enable Streamlit preview.</div>"
|
|
|
|
| 380 |
|
| 381 |
Always output only the HTML code inside a ```html ... ``` code block, and do not include any explanations or extra text. Do NOT add the language name at the top of the code output."""
|
| 382 |
|
| 383 |
+
# Multi-page static HTML project prompt (generic, production-style structure)
|
| 384 |
+
MULTIPAGE_HTML_SYSTEM_PROMPT = """You are an expert front-end developer.
|
| 385 |
+
|
| 386 |
+
Create a production-ready MULTI-PAGE website using ONLY HTML, CSS, and vanilla JavaScript. Do NOT use SPA frameworks.
|
| 387 |
+
|
| 388 |
+
Output MUST be a multi-file project with at least:
|
| 389 |
+
- index.html (home)
|
| 390 |
+
- about.html (secondary page)
|
| 391 |
+
- contact.html (secondary page)
|
| 392 |
+
- assets/css/styles.css (global styles)
|
| 393 |
+
- assets/js/main.js (site-wide JS)
|
| 394 |
+
|
| 395 |
+
Navigation requirements:
|
| 396 |
+
- A consistent header with a nav bar on every page
|
| 397 |
+
- Highlight current nav item
|
| 398 |
+
- Responsive layout and accessibility best practices
|
| 399 |
+
|
| 400 |
+
Output format requirements (CRITICAL):
|
| 401 |
+
- Return ONLY a series of file sections, each starting with a filename line:
|
| 402 |
+
=== index.html ===
|
| 403 |
+
...file content...
|
| 404 |
+
|
| 405 |
+
=== about.html ===
|
| 406 |
+
...file content...
|
| 407 |
+
|
| 408 |
+
(repeat for all files)
|
| 409 |
+
- Do NOT wrap files in Markdown code fences
|
| 410 |
+
- Use relative paths between files (e.g., assets/css/styles.css)
|
| 411 |
+
|
| 412 |
+
General requirements:
|
| 413 |
+
- Use modern, semantic HTML
|
| 414 |
+
- Mobile-first responsive design
|
| 415 |
+
- Include basic SEO meta tags in <head>
|
| 416 |
+
- Include a footer on all pages
|
| 417 |
+
- Avoid external CSS/JS frameworks (optional: CDN fonts/icons allowed)
|
| 418 |
+
"""
|
| 419 |
+
|
| 420 |
+
# Multi-page with search augmentation
|
| 421 |
+
MULTIPAGE_HTML_SYSTEM_PROMPT_WITH_SEARCH = """You are an expert front-end developer. You have access to real-time web search.
|
| 422 |
+
|
| 423 |
+
Create a production-ready MULTI-PAGE website using ONLY HTML, CSS, and vanilla JavaScript. Do NOT use SPA frameworks.
|
| 424 |
+
|
| 425 |
+
Follow the same file output format and project structure as specified:
|
| 426 |
+
=== filename === blocks for each file (no Markdown fences)
|
| 427 |
+
|
| 428 |
+
Use search results to apply current best practices in accessibility, semantics, responsive meta tags, and performance (preconnect, responsive images).
|
| 429 |
+
"""
|
| 430 |
+
|
| 431 |
GENERIC_SYSTEM_PROMPT_WITH_SEARCH = """You are an expert {language} developer. You have access to real-time web search. When needed, use web search to find the latest information, best practices, or specific technologies for {language}.
|
| 432 |
|
| 433 |
Write clean, idiomatic, and runnable {language} code for the user's request. If possible, include comments and best practices. Output ONLY the code inside a ``` code block, and do not include any explanations or extra text. If the user provides a file or other context, use it as a reference. If the code is for a script or app, make it as self-contained as possible. Do NOT add the language name at the top of the code output."""
|
|
|
|
| 1218 |
merged_html = build_transformers_inline_html(files)
|
| 1219 |
return send_to_sandbox(merged_html)
|
| 1220 |
|
| 1221 |
+
def parse_multipage_html_output(text: str) -> Dict[str, str]:
|
| 1222 |
+
"""Parse multi-page HTML output formatted as repeated "=== filename ===" sections.
|
| 1223 |
+
|
| 1224 |
+
Returns a mapping of filename → file content. Supports nested paths like assets/css/styles.css.
|
| 1225 |
+
"""
|
| 1226 |
+
if not text:
|
| 1227 |
+
return {}
|
| 1228 |
+
# First, strip any markdown fences
|
| 1229 |
+
cleaned = remove_code_block(text)
|
| 1230 |
+
files: Dict[str, str] = {}
|
| 1231 |
+
import re as _re
|
| 1232 |
+
pattern = _re.compile(r"^===\s*([^=\n]+?)\s*===\s*\n([\s\S]*?)(?=\n===\s*[^=\n]+?\s*===|\Z)", _re.MULTILINE)
|
| 1233 |
+
for m in pattern.finditer(cleaned):
|
| 1234 |
+
name = m.group(1).strip()
|
| 1235 |
+
content = m.group(2).strip()
|
| 1236 |
+
# Remove accidental trailing fences if present
|
| 1237 |
+
content = _re.sub(r"^```\w*\s*\n|\n```\s*$", "", content)
|
| 1238 |
+
files[name] = content
|
| 1239 |
+
return files
|
| 1240 |
+
|
| 1241 |
+
def inline_multipage_into_single_preview(files: Dict[str, str]) -> str:
|
| 1242 |
+
"""Inline local CSS/JS referenced by index.html for preview inside a data: iframe.
|
| 1243 |
+
|
| 1244 |
+
- Uses index.html as the base document
|
| 1245 |
+
- Inlines <link href="..."> if the target exists in files
|
| 1246 |
+
- Inlines <script src="..."> if the target exists in files
|
| 1247 |
+
- Leaves other links (e.g., about.html) untouched; preview covers the home page
|
| 1248 |
+
"""
|
| 1249 |
+
import re as _re
|
| 1250 |
+
html = files.get('index.html', '')
|
| 1251 |
+
if not html:
|
| 1252 |
+
return ""
|
| 1253 |
+
doc = html
|
| 1254 |
+
# Inline CSS links that point to known files
|
| 1255 |
+
def _inline_css(match):
|
| 1256 |
+
href = match.group(1)
|
| 1257 |
+
if href in files:
|
| 1258 |
+
return f"<style>\n{files[href]}\n</style>"
|
| 1259 |
+
return match.group(0)
|
| 1260 |
+
doc = _re.sub(r"<link[^>]+href=\"([^\"]+)\"[^>]*/?>", _inline_css, doc, flags=_re.IGNORECASE)
|
| 1261 |
+
|
| 1262 |
+
# Inline JS scripts that point to known files
|
| 1263 |
+
def _inline_js(match):
|
| 1264 |
+
src = match.group(1)
|
| 1265 |
+
if src in files:
|
| 1266 |
+
return f"<script>\n{files[src]}\n</script>"
|
| 1267 |
+
return match.group(0)
|
| 1268 |
+
doc = _re.sub(r"<script[^>]+src=\"([^\"]+)\"[^>]*>\s*</script>", _inline_js, doc, flags=_re.IGNORECASE)
|
| 1269 |
+
|
| 1270 |
+
# Inject a lightweight in-iframe client-side navigator to load other HTML files
|
| 1271 |
+
try:
|
| 1272 |
+
import json as _json
|
| 1273 |
+
import base64 as _b64
|
| 1274 |
+
import re as _re
|
| 1275 |
+
html_pages = {k: v for k, v in files.items() if k.lower().endswith('.html')}
|
| 1276 |
+
# Ensure index.html entry restores the current body's HTML
|
| 1277 |
+
_m_body = _re.search(r"<body[^>]*>([\s\S]*?)</body>", doc, flags=_re.IGNORECASE)
|
| 1278 |
+
_index_body = _m_body.group(1) if _m_body else doc
|
| 1279 |
+
html_pages['index.html'] = _index_body
|
| 1280 |
+
encoded = _b64.b64encode(_json.dumps(html_pages).encode('utf-8')).decode('ascii')
|
| 1281 |
+
nav_script = (
|
| 1282 |
+
"<script>\n" # Simple client-side loader for internal links
|
| 1283 |
+
"(function(){\n"
|
| 1284 |
+
f" const MP_FILES = JSON.parse(atob('{encoded}'));\n"
|
| 1285 |
+
" function extractBody(html){\n"
|
| 1286 |
+
" try {\n"
|
| 1287 |
+
" const doc = new DOMParser().parseFromString(html, 'text/html');\n"
|
| 1288 |
+
" const title = doc.querySelector('title'); if (title) document.title = title.textContent || document.title;\n"
|
| 1289 |
+
" return doc.body ? doc.body.innerHTML : html;\n"
|
| 1290 |
+
" } catch(e){ return html; }\n"
|
| 1291 |
+
" }\n"
|
| 1292 |
+
" function loadPage(path){\n"
|
| 1293 |
+
" if (!MP_FILES[path]) return false;\n"
|
| 1294 |
+
" const bodyHTML = extractBody(MP_FILES[path]);\n"
|
| 1295 |
+
" document.body.innerHTML = bodyHTML;\n"
|
| 1296 |
+
" attach();\n"
|
| 1297 |
+
" try { history.replaceState({}, '', '#'+path); } catch(e){}\n"
|
| 1298 |
+
" return true;\n"
|
| 1299 |
+
" }\n"
|
| 1300 |
+
" function clickHandler(e){\n"
|
| 1301 |
+
" const a = e.target && e.target.closest ? e.target.closest('a') : null;\n"
|
| 1302 |
+
" if (!a) return;\n"
|
| 1303 |
+
" const href = a.getAttribute('href') || '';\n"
|
| 1304 |
+
" if (!href || href.startsWith('#') || /^https?:/i.test(href) || href.startsWith('mailto:') || href.startsWith('tel:')) return;\n"
|
| 1305 |
+
" const clean = href.split('#')[0].split('?')[0];\n"
|
| 1306 |
+
" if (MP_FILES[clean]) { e.preventDefault(); loadPage(clean); }\n"
|
| 1307 |
+
" }\n"
|
| 1308 |
+
" function attach(){ document.removeEventListener('click', clickHandler, true); document.addEventListener('click', clickHandler, true); }\n"
|
| 1309 |
+
" document.addEventListener('DOMContentLoaded', function(){ attach(); const initial = (location.hash||'').slice(1); if (initial && MP_FILES[initial]) loadPage(initial); }, { once:true });\n"
|
| 1310 |
+
"})();\n"
|
| 1311 |
+
"</script>"
|
| 1312 |
+
)
|
| 1313 |
+
m = _re.search(r"</body>", doc, flags=_re.IGNORECASE)
|
| 1314 |
+
if m:
|
| 1315 |
+
i = m.start()
|
| 1316 |
+
doc = doc[:i] + nav_script + doc[i:]
|
| 1317 |
+
else:
|
| 1318 |
+
doc = doc + nav_script
|
| 1319 |
+
except Exception:
|
| 1320 |
+
# Non-fatal in preview
|
| 1321 |
+
pass
|
| 1322 |
+
|
| 1323 |
+
return doc
|
| 1324 |
+
|
| 1325 |
def parse_svelte_output(text):
|
| 1326 |
"""Parse Svelte output to extract individual files"""
|
| 1327 |
files = {
|
|
|
|
| 3281 |
else:
|
| 3282 |
# Use language-specific prompt
|
| 3283 |
if language == "html":
|
| 3284 |
+
# Use multi-page format prompt to encourage production multi-file output
|
| 3285 |
+
system_prompt = MULTIPAGE_HTML_SYSTEM_PROMPT_WITH_SEARCH if enable_search else MULTIPAGE_HTML_SYSTEM_PROMPT
|
| 3286 |
elif language == "transformers.js":
|
| 3287 |
system_prompt = TRANSFORMERS_JS_SYSTEM_PROMPT_WITH_SEARCH if enable_search else TRANSFORMERS_JS_SYSTEM_PROMPT
|
| 3288 |
elif language == "svelte":
|
|
|
|
| 3352 |
# Live streaming preview
|
| 3353 |
preview_val = None
|
| 3354 |
if language == "html":
|
| 3355 |
+
_mp = parse_multipage_html_output(clean_code)
|
| 3356 |
+
preview_val = send_to_sandbox(inline_multipage_into_single_preview(_mp)) if _mp.get('index.html') else send_to_sandbox(clean_code)
|
| 3357 |
elif language == "python" and is_streamlit_code(clean_code):
|
| 3358 |
preview_val = send_streamlit_to_stlite(clean_code)
|
| 3359 |
yield {
|
|
|
|
| 3582 |
|
| 3583 |
preview_val = None
|
| 3584 |
if language == "html":
|
| 3585 |
+
_mpf2 = parse_multipage_html_output(final_content)
|
| 3586 |
+
preview_val = send_to_sandbox(inline_multipage_into_single_preview(_mpf2)) if _mpf2.get('index.html') else send_to_sandbox(final_content)
|
| 3587 |
elif language == "python" and is_streamlit_code(final_content):
|
| 3588 |
preview_val = send_streamlit_to_stlite(final_content)
|
| 3589 |
yield {
|
|
|
|
| 3649 |
clean_code = clean_code.replace("\\t", "\t")
|
| 3650 |
preview_val = None
|
| 3651 |
if language == "html":
|
| 3652 |
+
_mpc = parse_multipage_html_output(clean_code)
|
| 3653 |
+
preview_val = send_to_sandbox(inline_multipage_into_single_preview(_mpc)) if _mpc.get('index.html') else send_to_sandbox(clean_code)
|
| 3654 |
elif language == "python" and is_streamlit_code(clean_code):
|
| 3655 |
preview_val = send_streamlit_to_stlite(clean_code)
|
| 3656 |
yield {
|
|
|
|
| 3669 |
_history.append([query, clean_code])
|
| 3670 |
preview_val = None
|
| 3671 |
if language == "html":
|
| 3672 |
+
_mpc2 = parse_multipage_html_output(clean_code)
|
| 3673 |
+
preview_val = send_to_sandbox(inline_multipage_into_single_preview(_mpc2)) if _mpc2.get('index.html') else send_to_sandbox(clean_code)
|
| 3674 |
elif language == "python" and is_streamlit_code(clean_code):
|
| 3675 |
preview_val = send_streamlit_to_stlite(clean_code)
|
| 3676 |
yield {
|
|
|
|
| 3846 |
# Model returned a complete HTML file
|
| 3847 |
preview_val = None
|
| 3848 |
if language == "html":
|
| 3849 |
+
_mpc3 = parse_multipage_html_output(clean_code)
|
| 3850 |
+
preview_val = send_to_sandbox(inline_multipage_into_single_preview(_mpc3)) if _mpc3.get('index.html') else send_to_sandbox(clean_code)
|
| 3851 |
elif language == "python" and is_streamlit_code(clean_code):
|
| 3852 |
preview_val = send_streamlit_to_stlite(clean_code)
|
| 3853 |
elif language == "gradio" or (language == "python" and is_gradio_code(clean_code)):
|
|
|
|
| 3864 |
clean_content = remove_code_block(modified_content)
|
| 3865 |
preview_val = None
|
| 3866 |
if language == "html":
|
| 3867 |
+
_mpc4 = parse_multipage_html_output(clean_content)
|
| 3868 |
+
preview_val = send_to_sandbox(inline_multipage_into_single_preview(_mpc4)) if _mpc4.get('index.html') else send_to_sandbox(clean_content)
|
| 3869 |
elif language == "python" and is_streamlit_code(clean_content):
|
| 3870 |
preview_val = send_streamlit_to_stlite(clean_content)
|
| 3871 |
elif language == "gradio" or (language == "python" and is_gradio_code(clean_content)):
|
|
|
|
| 3878 |
else:
|
| 3879 |
preview_val = None
|
| 3880 |
if language == "html":
|
| 3881 |
+
_mpc5 = parse_multipage_html_output(clean_code)
|
| 3882 |
+
preview_val = send_to_sandbox(inline_multipage_into_single_preview(_mpc5)) if _mpc5.get('index.html') else send_to_sandbox(clean_code)
|
| 3883 |
elif language == "python" and is_streamlit_code(clean_code):
|
| 3884 |
preview_val = send_streamlit_to_stlite(clean_code)
|
| 3885 |
elif language == "gradio" or (language == "python" and is_gradio_code(clean_code)):
|
|
|
|
| 3995 |
yield {
|
| 3996 |
code_output: clean_content,
|
| 3997 |
history: _history,
|
| 3998 |
+
sandbox: ((send_to_sandbox(inline_multipage_into_single_preview(parse_multipage_html_output(clean_content))) if parse_multipage_html_output(clean_content).get('index.html') else send_to_sandbox(clean_content)) if language == "html" else (send_streamlit_to_stlite(clean_content) if (language == "python" and is_streamlit_code(clean_content)) else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML or Streamlit-in-Python.</div>")),
|
| 3999 |
history_output: history_to_chatbot_messages(_history),
|
| 4000 |
}
|
| 4001 |
else:
|
|
|
|
| 4024 |
_history.append([query, final_content])
|
| 4025 |
preview_val = None
|
| 4026 |
if language == "html":
|
| 4027 |
+
_mpf = parse_multipage_html_output(final_content)
|
| 4028 |
+
preview_val = send_to_sandbox(inline_multipage_into_single_preview(_mpf)) if _mpf.get('index.html') else send_to_sandbox(final_content)
|
| 4029 |
elif language == "python" and is_streamlit_code(final_content):
|
| 4030 |
preview_val = send_streamlit_to_stlite(final_content)
|
| 4031 |
elif language == "gradio" or (language == "python" and is_gradio_code(final_content)):
|
|
|
|
| 5484 |
|
| 5485 |
def preview_logic(code, language, html_part=None, js_part=None, css_part=None):
|
| 5486 |
if language == "html":
|
| 5487 |
+
# If the content is a multi-page block, inline for preview; else render directly
|
| 5488 |
+
files = parse_multipage_html_output(code)
|
| 5489 |
+
if files and files.get('index.html'):
|
| 5490 |
+
merged = inline_multipage_into_single_preview(files)
|
| 5491 |
+
return send_to_sandbox(merged)
|
| 5492 |
return send_to_sandbox(code)
|
| 5493 |
if language == "streamlit":
|
| 5494 |
return send_streamlit_to_stlite(code) if is_streamlit_code(code) else "<div style='padding:1em;color:#888;text-align:center;'>Add `import streamlit as st` to enable Streamlit preview.</div>"
|