Spaces:
Running on Zero
Running on Zero
Add HTML+MathJax preview panel with source view
Browse files
app.py
CHANGED
|
@@ -235,6 +235,62 @@ def to_math_html(text: str) -> str:
|
|
| 235 |
|
| 236 |
return f'<div class="math-preview">{html}</div>'
|
| 237 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 238 |
def embed_images(markdown, crops):
|
| 239 |
if not crops:
|
| 240 |
return markdown
|
|
@@ -402,6 +458,9 @@ with gr.Blocks(title="DeepSeek-OCR-2") as demo:
|
|
| 402 |
text_out = gr.Textbox(lines=20, buttons=["copy"], show_label=False)
|
| 403 |
with gr.Tab("Markdown Preview", id="tab_markdown"):
|
| 404 |
md_out = gr.HTML("")
|
|
|
|
|
|
|
|
|
|
| 405 |
with gr.Tab("Boxes", id="tab_boxes"):
|
| 406 |
img_out = gr.Image(type="pil", height=500, show_label=False)
|
| 407 |
with gr.Tab("Cropped Images", id="tab_crops"):
|
|
@@ -461,7 +520,7 @@ with gr.Blocks(title="DeepSeek-OCR-2") as demo:
|
|
| 461 |
elif image is not None:
|
| 462 |
cleaned, markdown, raw, img_out, crops = process_image(image, task, custom_prompt)
|
| 463 |
else:
|
| 464 |
-
return "Error: Upload a file or image", "", "", None, [], gr.DownloadButton(visible=False)
|
| 465 |
|
| 466 |
# Text tab: convert \[...\] → $$...$$ and \(...\) → $...$ for readability
|
| 467 |
text_display = re.sub(r'\\\[(.+?)\\\]',
|
|
@@ -474,11 +533,13 @@ with gr.Blocks(title="DeepSeek-OCR-2") as demo:
|
|
| 474 |
dl_tmp.write(cleaned)
|
| 475 |
dl_tmp.close()
|
| 476 |
|
| 477 |
-
|
|
|
|
|
|
|
| 478 |
gr.DownloadButton(value=dl_tmp.name, visible=True))
|
| 479 |
|
| 480 |
submit_event = btn.click(run, [input_img, file_in, task, prompt, page_selector],
|
| 481 |
-
[text_out, md_out, raw_out, img_out, gallery, download_btn])
|
| 482 |
submit_event.then(select_boxes, [task], [tabs])
|
| 483 |
|
| 484 |
if __name__ == "__main__":
|
|
|
|
| 235 |
|
| 236 |
return f'<div class="math-preview">{html}</div>'
|
| 237 |
|
| 238 |
+
def to_mathjax_html(text: str) -> str:
|
| 239 |
+
"""Render markdown to HTML and typeset math client-side with MathJax."""
|
| 240 |
+
if not text:
|
| 241 |
+
return ""
|
| 242 |
+
html = md_lib.markdown(text, extensions=['tables', 'fenced_code', 'sane_lists', 'nl2br'])
|
| 243 |
+
return f"""<!doctype html>
|
| 244 |
+
<html>
|
| 245 |
+
<head>
|
| 246 |
+
<meta charset="utf-8" />
|
| 247 |
+
<style>
|
| 248 |
+
body {{
|
| 249 |
+
margin: 0;
|
| 250 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
| 251 |
+
font-size: 15px;
|
| 252 |
+
line-height: 1.8;
|
| 253 |
+
color: #1a1a1a;
|
| 254 |
+
}}
|
| 255 |
+
.mathjax-preview {{
|
| 256 |
+
padding: 1.5em;
|
| 257 |
+
max-width: 100%;
|
| 258 |
+
overflow-x: auto;
|
| 259 |
+
}}
|
| 260 |
+
.mathjax-preview h1 {{ font-size: 1.8em; font-weight: 700; margin: 1em 0 0.4em; border-bottom: 2px solid #e0e0e0; padding-bottom: 0.3em; }}
|
| 261 |
+
.mathjax-preview h2 {{ font-size: 1.4em; font-weight: 600; margin: 1em 0 0.4em; border-bottom: 1px solid #e0e0e0; padding-bottom: 0.2em; }}
|
| 262 |
+
.mathjax-preview h3 {{ font-size: 1.15em; font-weight: 600; margin: 0.9em 0 0.3em; }}
|
| 263 |
+
.mathjax-preview p {{ margin: 0.6em 0; }}
|
| 264 |
+
.mathjax-preview ul, .mathjax-preview ol {{ padding-left: 1.8em; margin: 0.5em 0; }}
|
| 265 |
+
.mathjax-preview li {{ margin: 0.25em 0; }}
|
| 266 |
+
.mathjax-preview table {{ border-collapse: collapse; width: 100%; margin: 1em 0; font-size: 0.95em; }}
|
| 267 |
+
.mathjax-preview th, .mathjax-preview td {{ border: 1px solid #ccc; padding: 0.45em 0.75em; text-align: left; }}
|
| 268 |
+
.mathjax-preview th {{ background: #f2f2f2; font-weight: 600; }}
|
| 269 |
+
.mathjax-preview tr:nth-child(even) {{ background: #fafafa; }}
|
| 270 |
+
.mathjax-preview code {{ background: #f4f4f4; padding: 0.15em 0.4em; border-radius: 3px; font-family: 'Courier New', monospace; font-size: 0.88em; }}
|
| 271 |
+
.mathjax-preview pre {{ background: #f4f4f4; padding: 1em; border-radius: 5px; overflow-x: auto; margin: 0.8em 0; }}
|
| 272 |
+
.mathjax-preview pre code {{ background: none; padding: 0; }}
|
| 273 |
+
.mathjax-preview blockquote {{ border-left: 4px solid #ccc; margin: 0.8em 0; padding: 0.4em 1em; color: #555; background: #fafafa; }}
|
| 274 |
+
.mathjax-preview img {{ max-width: 100%; height: auto; display: block; margin: 0.8em 0; }}
|
| 275 |
+
</style>
|
| 276 |
+
<script>
|
| 277 |
+
window.MathJax = {{
|
| 278 |
+
tex: {{
|
| 279 |
+
inlineMath: [['\\\\(', '\\\\)'], ['$', '$']],
|
| 280 |
+
displayMath: [['\\\\[', '\\\\]'], ['$$', '$$']]
|
| 281 |
+
}},
|
| 282 |
+
options: {{
|
| 283 |
+
skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
|
| 284 |
+
}}
|
| 285 |
+
}};
|
| 286 |
+
</script>
|
| 287 |
+
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
|
| 288 |
+
</head>
|
| 289 |
+
<body>
|
| 290 |
+
<div class="mathjax-preview">{html}</div>
|
| 291 |
+
</body>
|
| 292 |
+
</html>"""
|
| 293 |
+
|
| 294 |
def embed_images(markdown, crops):
|
| 295 |
if not crops:
|
| 296 |
return markdown
|
|
|
|
| 458 |
text_out = gr.Textbox(lines=20, buttons=["copy"], show_label=False)
|
| 459 |
with gr.Tab("Markdown Preview", id="tab_markdown"):
|
| 460 |
md_out = gr.HTML("")
|
| 461 |
+
with gr.Tab("HTML + MathJax", id="tab_html"):
|
| 462 |
+
html_out = gr.HTML("")
|
| 463 |
+
html_source_out = gr.Code(label="Generated HTML Source", language="html", lines=16)
|
| 464 |
with gr.Tab("Boxes", id="tab_boxes"):
|
| 465 |
img_out = gr.Image(type="pil", height=500, show_label=False)
|
| 466 |
with gr.Tab("Cropped Images", id="tab_crops"):
|
|
|
|
| 520 |
elif image is not None:
|
| 521 |
cleaned, markdown, raw, img_out, crops = process_image(image, task, custom_prompt)
|
| 522 |
else:
|
| 523 |
+
return "Error: Upload a file or image", "", "", "", "", None, [], gr.DownloadButton(visible=False)
|
| 524 |
|
| 525 |
# Text tab: convert \[...\] → $$...$$ and \(...\) → $...$ for readability
|
| 526 |
text_display = re.sub(r'\\\[(.+?)\\\]',
|
|
|
|
| 533 |
dl_tmp.write(cleaned)
|
| 534 |
dl_tmp.close()
|
| 535 |
|
| 536 |
+
mathjax_html = to_mathjax_html(markdown)
|
| 537 |
+
|
| 538 |
+
return (text_display, to_math_html(markdown), mathjax_html, mathjax_html, raw, img_out, crops,
|
| 539 |
gr.DownloadButton(value=dl_tmp.name, visible=True))
|
| 540 |
|
| 541 |
submit_event = btn.click(run, [input_img, file_in, task, prompt, page_selector],
|
| 542 |
+
[text_out, md_out, html_out, html_source_out, raw_out, img_out, gallery, download_btn])
|
| 543 |
submit_event.then(select_boxes, [task], [tabs])
|
| 544 |
|
| 545 |
if __name__ == "__main__":
|