Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -115,7 +115,6 @@ def build_full_html(markdown_text, styles, for_image=False):
|
|
| 115 |
|
| 116 |
/* Headers */
|
| 117 |
{wrapper_id} h1, {wrapper_id} h2, {wrapper_id} h3 {{ border-bottom: 1px solid #eee; padding-bottom: 5px; margin-top: 1.5em; }}
|
| 118 |
-
|
| 119 |
/* --- CODE BOX STYLING (FIXED) --- */
|
| 120 |
|
| 121 |
/* Apply box styling to ALL pre tags (plain or highlighted) */
|
|
@@ -129,7 +128,6 @@ def build_full_html(markdown_text, styles, for_image=False):
|
|
| 129 |
margin: 1em 0;
|
| 130 |
line-height: 1.45;
|
| 131 |
}}
|
| 132 |
-
|
| 133 |
/* Ensure code inside pre doesn't double-pad */
|
| 134 |
{wrapper_id} pre code {{
|
| 135 |
background-color: transparent;
|
|
@@ -138,7 +136,6 @@ def build_full_html(markdown_text, styles, for_image=False):
|
|
| 138 |
font-family: 'Fira Code', 'Consolas', 'Monaco', monospace;
|
| 139 |
font-size: 0.9em;
|
| 140 |
}}
|
| 141 |
-
|
| 142 |
/* Specific override for Pygments container if it exists */
|
| 143 |
{wrapper_id} .codehilite {{
|
| 144 |
background-color: {bg_color};
|
|
@@ -150,7 +147,6 @@ def build_full_html(markdown_text, styles, for_image=False):
|
|
| 150 |
margin: 0;
|
| 151 |
border: none; /* Let container handle border if needed */
|
| 152 |
}}
|
| 153 |
-
|
| 154 |
/* Syntax Highlighting Colors */
|
| 155 |
{pygments_css}
|
| 156 |
|
|
@@ -285,13 +281,11 @@ def index():
|
|
| 285 |
<h1>Markdown Tool</h1>
|
| 286 |
<button onclick="document.body.classList.toggle('dark-mode')" class="btn-secondary">🌓 Dark Mode</button>
|
| 287 |
</div>
|
| 288 |
-
|
| 289 |
<fieldset>
|
| 290 |
<legend>1. Input</legend>
|
| 291 |
<textarea id="md-input" rows="8"></textarea>
|
| 292 |
<div class="action-bar"><button onclick="analyze()" class="btn-primary" id="load-btn">Analyze Content</button></div>
|
| 293 |
</fieldset>
|
| 294 |
-
|
| 295 |
<div id="comp-section" style="display:none;">
|
| 296 |
<div id="detected-format" class="format-banner"></div>
|
| 297 |
<fieldset>
|
|
@@ -299,7 +293,6 @@ def index():
|
|
| 299 |
<div class="comp-grid" id="comp-list"></div>
|
| 300 |
</fieldset>
|
| 301 |
</div>
|
| 302 |
-
|
| 303 |
<fieldset>
|
| 304 |
<legend>3. Styles</legend>
|
| 305 |
<div class="style-grid">
|
|
@@ -319,9 +312,7 @@ def index():
|
|
| 319 |
</div>
|
| 320 |
<textarea id="c_css" rows="2" style="margin-top:15px;" placeholder="Custom CSS..."></textarea>
|
| 321 |
</fieldset>
|
| 322 |
-
|
| 323 |
<button onclick="process('preview')" class="btn-primary" id="gen-btn" style="width:100%; height:50px; font-size:18px;">GENERATE PREVIEW</button>
|
| 324 |
-
|
| 325 |
<div id="preview-area" style="display:none;">
|
| 326 |
<div class="preview-section">
|
| 327 |
<div class="preview-box">
|
|
@@ -338,79 +329,62 @@ def index():
|
|
| 338 |
</div>
|
| 339 |
</div>
|
| 340 |
</div>
|
| 341 |
-
|
| 342 |
<script>
|
| 343 |
async function analyze() {
|
| 344 |
const btn = document.getElementById('load-btn');
|
| 345 |
-
const
|
| 346 |
-
if(!
|
| 347 |
|
| 348 |
btn.innerText = "Analyzing...";
|
| 349 |
const fd = new FormData();
|
| 350 |
-
fd.append('markdown_text',
|
| 351 |
|
| 352 |
try {
|
| 353 |
const res = await fetch('/parse', {method:'POST', body:fd});
|
| 354 |
-
if (!res.ok) throw new Error("Server error during analysis");
|
| 355 |
const data = await res.json();
|
| 356 |
-
|
| 357 |
-
|
| 358 |
const list = document.getElementById('comp-list');
|
| 359 |
-
|
| 360 |
-
banner.innerText = "Detected: " + (data.format || "Unknown");
|
| 361 |
list.innerHTML = '';
|
| 362 |
-
|
| 363 |
data.components.forEach(c => {
|
| 364 |
-
|
| 365 |
-
const safeContent = btoa(encodeURIComponent(c.content));
|
| 366 |
list.innerHTML += `
|
| 367 |
<div class="comp-card">
|
| 368 |
<label style="cursor:pointer; display:block;">
|
| 369 |
-
<input type="checkbox" checked class="c-check"
|
| 370 |
-
data-name="${c.filename}"
|
| 371 |
-
data-content="${safeContent}">
|
| 372 |
<b>${c.filename}</b>
|
| 373 |
</label>
|
| 374 |
<textarea readonly>${c.content.substring(0,80)}...</textarea>
|
| 375 |
</div>`;
|
| 376 |
});
|
| 377 |
document.getElementById('comp-section').style.display = 'block';
|
| 378 |
-
} catch(e) {
|
| 379 |
-
|
| 380 |
-
alert("Analysis failed: " + e.message);
|
| 381 |
-
} finally {
|
| 382 |
-
btn.innerText = "Analyze Content";
|
| 383 |
-
}
|
| 384 |
}
|
| 385 |
-
|
| 386 |
async function process(action, type = null) {
|
| 387 |
const btn = document.getElementById('gen-btn');
|
| 388 |
let md = "";
|
| 389 |
const checks = document.querySelectorAll('.c-check');
|
|
|
|
| 390 |
|
| 391 |
-
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
|
| 397 |
-
|
| 398 |
-
if(!name.includes("Intro") && !name.includes("Structure")) {
|
| 399 |
-
md += "### File: " + name + "\n";
|
| 400 |
-
}
|
| 401 |
-
|
| 402 |
-
// WRAP IN CODE BOX: Detect if it's a file or code block
|
| 403 |
-
if(name.includes(".") || name === "Agent Command" || name === "File Structure") {
|
| 404 |
-
md += "```\n" + content + "\n```\n\n";
|
| 405 |
-
} else {
|
| 406 |
-
md += content + "\n\n";
|
| 407 |
-
}
|
| 408 |
}
|
| 409 |
-
|
| 410 |
-
|
| 411 |
-
|
| 412 |
-
|
| 413 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 414 |
const payload = {
|
| 415 |
markdown_text: md,
|
| 416 |
download: action === 'download',
|
|
@@ -426,7 +400,6 @@ def index():
|
|
| 426 |
page_padding: 40, code_padding: 15
|
| 427 |
}
|
| 428 |
};
|
| 429 |
-
|
| 430 |
if(action === 'preview') btn.innerText = "Processing...";
|
| 431 |
|
| 432 |
try {
|
|
@@ -446,7 +419,6 @@ def index():
|
|
| 446 |
} else {
|
| 447 |
const data = await res.json();
|
| 448 |
if(data.error) throw new Error(data.error);
|
| 449 |
-
|
| 450 |
document.getElementById('preview-area').style.display = 'block';
|
| 451 |
document.getElementById('html-prev').innerHTML = data.preview_html;
|
| 452 |
const pngContainer = document.getElementById('png-prev');
|
|
|
|
| 115 |
|
| 116 |
/* Headers */
|
| 117 |
{wrapper_id} h1, {wrapper_id} h2, {wrapper_id} h3 {{ border-bottom: 1px solid #eee; padding-bottom: 5px; margin-top: 1.5em; }}
|
|
|
|
| 118 |
/* --- CODE BOX STYLING (FIXED) --- */
|
| 119 |
|
| 120 |
/* Apply box styling to ALL pre tags (plain or highlighted) */
|
|
|
|
| 128 |
margin: 1em 0;
|
| 129 |
line-height: 1.45;
|
| 130 |
}}
|
|
|
|
| 131 |
/* Ensure code inside pre doesn't double-pad */
|
| 132 |
{wrapper_id} pre code {{
|
| 133 |
background-color: transparent;
|
|
|
|
| 136 |
font-family: 'Fira Code', 'Consolas', 'Monaco', monospace;
|
| 137 |
font-size: 0.9em;
|
| 138 |
}}
|
|
|
|
| 139 |
/* Specific override for Pygments container if it exists */
|
| 140 |
{wrapper_id} .codehilite {{
|
| 141 |
background-color: {bg_color};
|
|
|
|
| 147 |
margin: 0;
|
| 148 |
border: none; /* Let container handle border if needed */
|
| 149 |
}}
|
|
|
|
| 150 |
/* Syntax Highlighting Colors */
|
| 151 |
{pygments_css}
|
| 152 |
|
|
|
|
| 281 |
<h1>Markdown Tool</h1>
|
| 282 |
<button onclick="document.body.classList.toggle('dark-mode')" class="btn-secondary">🌓 Dark Mode</button>
|
| 283 |
</div>
|
|
|
|
| 284 |
<fieldset>
|
| 285 |
<legend>1. Input</legend>
|
| 286 |
<textarea id="md-input" rows="8"></textarea>
|
| 287 |
<div class="action-bar"><button onclick="analyze()" class="btn-primary" id="load-btn">Analyze Content</button></div>
|
| 288 |
</fieldset>
|
|
|
|
| 289 |
<div id="comp-section" style="display:none;">
|
| 290 |
<div id="detected-format" class="format-banner"></div>
|
| 291 |
<fieldset>
|
|
|
|
| 293 |
<div class="comp-grid" id="comp-list"></div>
|
| 294 |
</fieldset>
|
| 295 |
</div>
|
|
|
|
| 296 |
<fieldset>
|
| 297 |
<legend>3. Styles</legend>
|
| 298 |
<div class="style-grid">
|
|
|
|
| 312 |
</div>
|
| 313 |
<textarea id="c_css" rows="2" style="margin-top:15px;" placeholder="Custom CSS..."></textarea>
|
| 314 |
</fieldset>
|
|
|
|
| 315 |
<button onclick="process('preview')" class="btn-primary" id="gen-btn" style="width:100%; height:50px; font-size:18px;">GENERATE PREVIEW</button>
|
|
|
|
| 316 |
<div id="preview-area" style="display:none;">
|
| 317 |
<div class="preview-section">
|
| 318 |
<div class="preview-box">
|
|
|
|
| 329 |
</div>
|
| 330 |
</div>
|
| 331 |
</div>
|
|
|
|
| 332 |
<script>
|
| 333 |
async function analyze() {
|
| 334 |
const btn = document.getElementById('load-btn');
|
| 335 |
+
const text = document.getElementById('md-input').value;
|
| 336 |
+
if(!text) return alert("Please enter text.");
|
| 337 |
|
| 338 |
btn.innerText = "Analyzing...";
|
| 339 |
const fd = new FormData();
|
| 340 |
+
fd.append('markdown_text', text);
|
| 341 |
|
| 342 |
try {
|
| 343 |
const res = await fetch('/parse', {method:'POST', body:fd});
|
|
|
|
| 344 |
const data = await res.json();
|
| 345 |
+
if(data.error) { alert(data.error); return; }
|
| 346 |
+
document.getElementById('detected-format').innerText = "Detected: " + data.format;
|
| 347 |
const list = document.getElementById('comp-list');
|
|
|
|
|
|
|
| 348 |
list.innerHTML = '';
|
|
|
|
| 349 |
data.components.forEach(c => {
|
| 350 |
+
const safe = btoa(unescape(encodeURIComponent(c.content)));
|
|
|
|
| 351 |
list.innerHTML += `
|
| 352 |
<div class="comp-card">
|
| 353 |
<label style="cursor:pointer; display:block;">
|
| 354 |
+
<input type="checkbox" checked class="c-check" data-name="${c.filename}" data-content="${safe}">
|
|
|
|
|
|
|
| 355 |
<b>${c.filename}</b>
|
| 356 |
</label>
|
| 357 |
<textarea readonly>${c.content.substring(0,80)}...</textarea>
|
| 358 |
</div>`;
|
| 359 |
});
|
| 360 |
document.getElementById('comp-section').style.display = 'block';
|
| 361 |
+
} catch(e) { alert(e); }
|
| 362 |
+
finally { btn.innerText = "Analyze Content"; }
|
|
|
|
|
|
|
|
|
|
|
|
|
| 363 |
}
|
|
|
|
| 364 |
async function process(action, type = null) {
|
| 365 |
const btn = document.getElementById('gen-btn');
|
| 366 |
let md = "";
|
| 367 |
const checks = document.querySelectorAll('.c-check');
|
| 368 |
+
let hasSelection = false;
|
| 369 |
|
| 370 |
+
checks.forEach(c => {
|
| 371 |
+
if(c.checked) {
|
| 372 |
+
hasSelection = true;
|
| 373 |
+
const content = decodeURIComponent(escape(atob(c.dataset.content)));
|
| 374 |
+
|
| 375 |
+
if(!c.dataset.name.includes("Intro") && !c.dataset.name.includes("Structure")) {
|
| 376 |
+
md += "### File: " + c.dataset.name + "\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 377 |
}
|
| 378 |
+
|
| 379 |
+
if(c.dataset.name.includes(".") || c.dataset.name === "Agent Command") {
|
| 380 |
+
md += "```\n" + content + "\n```\n\n";
|
| 381 |
+
} else {
|
| 382 |
+
md += content + "\n\n";
|
| 383 |
+
}
|
| 384 |
+
}
|
| 385 |
+
});
|
| 386 |
+
|
| 387 |
+
if(!hasSelection) md = document.getElementById('md-input').value;
|
| 388 |
const payload = {
|
| 389 |
markdown_text: md,
|
| 390 |
download: action === 'download',
|
|
|
|
| 400 |
page_padding: 40, code_padding: 15
|
| 401 |
}
|
| 402 |
};
|
|
|
|
| 403 |
if(action === 'preview') btn.innerText = "Processing...";
|
| 404 |
|
| 405 |
try {
|
|
|
|
| 419 |
} else {
|
| 420 |
const data = await res.json();
|
| 421 |
if(data.error) throw new Error(data.error);
|
|
|
|
| 422 |
document.getElementById('preview-area').style.display = 'block';
|
| 423 |
document.getElementById('html-prev').innerHTML = data.preview_html;
|
| 424 |
const pngContainer = document.getElementById('png-prev');
|